Створення користувальницьких типів інтеграції CLR – ЧАСТИНА 2

■ Використання СОМ Це можна заявити тільки з невеликою натяжкою, але у випадку, коли користувача тип впроваджує деякий старий програмний код, важливий для організації, за допомогою interop-збірки, необхідна ретельна перевірка типу, створеного як клас або структура Наприклад, коли нездатна до коректного перетворенню змінна розміщується interop-збіркою, в документації попереджається про можливі проблеми Серед таких типів – рядки, масиви, обєкти, класи і типи значень Це не обходить стороною і безліч інших вбудованих типів, тому, з міркувань безпеки, якщо в типі планується використання СОМ, то цей тип розумно створювати як клас

Решта важливі вимоги буде краще обговорити в контексті шаблону користувальницького типу програми Visual Studio 2005

Програмування користувача типів CLR в Visual Studio

Деякі з вимог висуваються конкретним шаблоном, в той час як інші необхідні для всіх типів Послідовно переглядаючи згенерований шаблоном програмний код для тестового типу, в цьому розділі ми досліджуємо вимоги і відмінності в програмуванні, необхідні для досягнення потрібної поведінки

Створюваний як приклад тип буде використовуватися для зберігання IP-адрес Це найпоширеніша схема адресації, використовуваної в даний час в Інтернеті IP-адреса традиційно представляється чотирма цілими числами, кожне з яких знаходиться в діапазоні від нуля до 255, розділеними крапками В даний час більшість мереж призначають кожному вузлу один або кілька IP-адрес для підтримки транспортного та мережевого рівнів моделі OSI В Інтернеті використовуються символьні імена DNS, присвоєні IP-адресами На практиці досить часто виникає потреба представляти 1Р-адреси в базі даних, однак у попередніх версіях SQL Server було досить проблематично забезпечувати доменну цілісність цих значень Зазвичай IP-адреси зберігалися як рядки, а перевірка виконувалася вже на рівні додатку, якому потрібні були ці дані За допомогою користувача типів в SQL Server можна організувати перевірку IP-адрес вже на рівні бази даних за допомогою звичайних виразів NET До того ж тепер стало можливим посилатися на простір імен SystemNet з членів користувальницького типу

Повне рішення Visual Studio 2005 для користувальницького типу, обговорюваного В в цій главі, можна завантажити з Web-сайту книги У цьому рішенні со-^ ^ ХСеті тримаються робочі приклади типу IP-адреси, реалізованого трьома способами:

•&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp як структури у своїй простій формі

•&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp як структури з призначеним для користувача форматом

•&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp&nbsp як класи

Давайте подивимося, як можна створити користувальницький тип для IP-адреси У простій структурі користувальницького типу можна побачити його елементи У першу чергу зверніть увагу на системні збірки, які повинні бути включені у всі користувальницькі типи: Imports System Imports SystemData Imports SystemDataSql Imports SystemDataSqlTypes Imports MicrosoftSqlServerServer Imports SystemTextRegularExpressions

1 Якщо стовпець з призначеним для користувача типом буде індексуватися,

‘Необхідно встановити властивість IsByteOrdered в значення true _

&ltMicrosoftSqlServerServerSqlUserDefinedType(FormatNative, IsByteOrdered:=True)&gt _

Public Structure IPTypel Implements INullable

Private Shared Readonly _parser As _New _

Regex(&quot\A((2[0-4]\d|25 [0-5] | [01] \d\d)\){3}(2[0-4]\d|25 [0-5] |

[01]\d\d)&quot)

Private Const _NULL As String = &quotNULL_IP&quot

Private m_Null As Boolean Private m_OctetA As Byte Private m_OctetB As Byte Private m_OctetC As Byte Private m_OctetD As Byte

Public Overrides Function ToString() As String If MeIsNull Then Return _NULL

‘Можна також використовувати Return Nothing Else

Return Me m_OctetA ToString () &amp &quot 11 &amp _

Mem_OctetBToString() &amp            &amp _

Mem_OctetCToString() &amp &quot.&quot &amp _

Mem_OctetDToString()

End If End Function

Public Readonly Property IsNull() As Boolean Implements _

INullableIsNull Get

Return m_Null End Get End Property

Public Shared Readonly Property NullO As IPTypel Get

Dim h As IPTypel 1= New IPTypel hm_Null = True Return h End Get End Property

Public Shared Function Parse(ByVal s As SqlString) As IPTypel If sIsNull Or sValue = _NULL Then

‘База даних визначає допустимість в стовпці порожніх значень

Return Null End If

‘Конструктор не обовязковий для структури 1 Припустимо, але не обовязково, щоб

‘Кожен член мав значення за замовчуванням, щоб кожен октет IP-адреси був инициализирован нулем Dim u As IPTypel = New IPTypel

‘Рядок NET повинна бути розібрана на складові Dim str As String = ConvertToString (s)

Dim m As Match = _parserMatch(str)

If mSuccess Then

Dim arr() As String = strSplit(CType, Char))

uOctetA = CType(arr(0), Byte)

uOctetB = CType(arr(1), Byte)

uOctetC = CType(arr(2), Byte)

uOctetD = CType(arr(3), Byte)

Return u Else

Throw New ArgumentException(&quotInvalid IP v4 Address&quot)

‘ Return Nothing End If End Function

‘results in 0000 = null Public Property OctetAO As Byte Get

OctetA = m_OctetA End Get

Set(ByVal value As Byte) m_OctetA = value End Set End Property

Public Property OctetBO As Byte Get

OctetB = m_OctetB End Get

Set(ByVal value As Byte) m_OctetB = value End Set End Property

Public Property OctetCO As Byte Get

OctetC = m_OctetC End Get

Set(ByVal value As Byte) m_OctetC = value End Set End Property

Public Property OctetDO As Byte Get

OctetD = mjDctetD End Get

Set(ByVal value As Byte) m__OctetD = value End Set

End Property

&ltSqlMethod(IsDeterministic:=True, IsPrecise:=True)&gt _

Public Function GetCSubNetO As String

GetCSubNet = m_OctetCToString +      + m_OctetDToString

End Function End Structure

Якщо потрібно закласти в тип інші функції, то в проект інтеграції CLR потрібно включити і інші простори імен за допомогою команди Imports та посилання на відповідну збірку Наприклад, до звичайних виразами, інструментам WMI (Windows Management Instrumentation) і безлічі мережевих служб можна отримати доступ з типів інтеграції CLR за допомогою пропонованих системою просторів імен NET Для використання регулярних виразів додайте наступний оператор:

Imports SystemTextRegularExpressions

Далі оголошується клас або структура Деякі важливі аспекти оголошення можуть варіюватися залежно від того, на чому заснований тип – на структурі або класі У першу чергу слід визначити обовязкові атрибути Потім вказується область визначення класу і його імя Якщо клас є похідним від іншого, то далі вказується батьківський клас Зауважимо, що клас може успадковувати тільки від одного класу, а структура не може успадковувати взагалі Якщо клас реалізує небудь інтерфейс, реалізації цього інтерфейсу перераховуються після батьківського обєкта Закривається клас або структура оператором End Class або End Structure

Тепер розглянемо оголошення елементів структури або класу більш докладно

Атрибут Serializable забезпечує підтримку метаданих для представлення стану даних користувальницького типу в потоці байтів при їх транспортуванні та використанні, а також для упаковки потоку з метою зберігання в типі даних Атрибут Serializable не обовязковий в призначеному для користувача типі, проте в більшості ситуацій може виявитися корисним Звичайно, сериализация допомагає визначити, як потік байтів буде розділятися на дані членів користувальницького типу У загальному випадку сериализация займається обєднанням всіх полів користувальницького типу в двійковий потік або потік XML Атрибут Sertializable не має параметрів – він просто повинен бути визначений, після чого в тілі структури або класу повинні бути визначені інтерфейси і методи сериализации

Додаткова Дискусію про використання користувальницьких атрибутів типів інтеграції інформація CLR см в главі 27

Атрибут SqlUserDef inedType є спеціалізованим і використовується тільки для користувача типів Як зазначалося в розділі 27, компілятор використовує цей атрибут при компіляції збірки в код MSIL Він також впливає на маніфест збірки і використовується SQL Server під час завантаження збірки в сервер Цей атрибут досить ємний він містить чотири параметри По-перше, слід чітко визначити формат зберігання типу за умовчанням в шаблоні передбачений формат Fonmat Native Цей формат здатний забезпечити найбільшу сумісність і продуктивність при мінімальному обсязі додаткового програмування Якщо стовпці, створювані з даним типом, будуть брати участь в індексації, також необхідно встановити параметр IsByteOrdered Серед інших значень атрибута дуже корисний Format UserDef ined і відносно безинтересной FormatUnknown

Якщо користувальницький тип визначається як клас, що використовує рідний формат, то для забезпечення сумісності з СОМ повинен бути встановлений атрибут Struct Layout Це виконується за допомогою додавання простору імен InteropServices і присвоєння властивості LayoutKind значення StructLayout Можливими значеннями атрибута також є Auto, Explicit і Sequential, і в більшості користувача типів інтеграції CLR зазвичай використовують значення Sequential У загальному випадку значення Auto вказує системі самій ухвалити рішення щодо компонування полів користувальницького типу значення Explicit дозволяє програмісту явним чином визначити компоновку, а значення Sequential інструктує програму розташовувати поля в порядку їх відправлення За замовчуванням компілятор Visual Studio використовує розкладку Sequential

Імпортується простір імен:

Imports SystemRuntimeInteropServices

Параметр LayoutKind Sequential включається з іншими користувацькими атрибутами:

&ltSystemRuntimeInteropServicesStructLayout(LayoutKindSequential)&gt _

Для визначення способу доступу до типу використовується область визначення структури У VBNET рівні доступу можуть бути встановлені за допомогою наступних модифікаторів: Public, Private, Friend, Protected і ProtectedFriend В інших мовах програмування сімейства NET існують аналогічні модифікатори Щоб користувальницький тип був доступний поза домену програми (як ви памятаєте з глави 27, домен програми є аналогом схеми бази даних), рівень доступу повинен бути встановлений в Public: _

&ltMicrosoftSqlServerServerSqlUserDef inedType(FormatNative, IsByteOrdered:=True)&gt _

Public Structure IPTypel

Implements INullable

На відміну від класу структура не може успадковувати від іншої структури Водночас, подібно класу, структура може відтіняти (або приховувати, або повністю заміщати) інший програмний елемент, що має точна таке ж імя, за допомогою модифікатора Shadows

Додаткова Додаткові ресурси, з яких можна почерпнути інформацію про роботу інформація, із середовищем NET Framework, см в главі 27

Клас може успадковувати від іншого класу Це означає, що на додаток до модифікаторів рівня доступу і Shadows доступні і два додаткових для базового класу типу, що визначає область спадкування класу

■ Модифікатор Must Inherit вимагає, щоб клас міг використовуватися тільки для наслідування, і забороняє створення примірників даного класу

■ Модифікатор Not Inheritable забороняє використання даного класу іншими для наслідування

Якщо створюється базовий тип, на якому буде заснована маса інших типів, і ви не хочете, щоб базовий тип був реалізований сам по собі в SQL Server, використовуйте модифікатор Must Inherit Якщо з міркувань безпеки або продуктивності ви не хочете, щоб на базі даного типу створювалися інші, використовуйте модифікатор Not Inheritable

Якщо тип оголошується як клас, то він може успадковувати тільки від одного базового класу Для вказівки базового класу в мові VBNET передбачено ключове слово Inherits (супроводжуване імям класу), який вставляється в оголошення безпосередньо після імені типу Необхідно також включити посилання на збірку, де можна знайти базовий клас (якщо він знаходиться в іншій збірці), а також простір імен в розділі Imports у верхній частині файлу Незважаючи на те що тип може управлятися з базового класу, SQL Server

не гарантує спадкування Якщо повинні використовуватися члени керуючої класу, вони повинні бути явно включені в поточний клас

Коли в роботі не бере участь SQL Server, члени базового класу неявно доступні в керованому класі Однак в інтеграції CLR в SQL Server в даний час спадкування не підтримується SQL Server вимагає, щоб загальнодоступні члени не заміняють, і неявне спадкування не розпізнає середовищем виконання CLR в SQL Server Спільно все це висуває вимогу не використовувати в інтеграції CLR спадкування в його класичній формі Це обмеження суттєво впливає на розгляд інтеграції CLR як обєктно-орієнтованого середовища виконання У цьому сенсі більш дружнім підходом до управління функціональністю з інших класів буде реалізація інтерфейсу, а не успадкування з базового класу

&ltSerializable()&gt _

&ltMicrosoftSqlServerServerSqlUserDefinedType(FormatNative, IsByteOrdered:=True)&gt _

&ltSysternRuntimeInteropServicesStructLayout(LayoutKindSequential)&gt _ Public Class IPType3 Implements INullable

Останнє, що потрібно вставити в оголошення класу, – це імена інтерфейсів, які будуть використовуватися типом Клас може використовувати кілька інтерфейсів У користувача тип завжди потрібно впроваджувати інтерфейс INullable з простору імен Sys-tem Data SQLTypes Цей інтерфейс містить властивість IsNull, що дозволяє середовищі NET Framework функціонувати в базі даних, що допускає порожні значення в якому-небудь з типів даних

Серед інших інтерфейсів, які реалізуються вбудованими типами даних SQL Server, можна згадати IComparable і IXMLSerializable з простору імен System Інтерфейс IComparable служить для підтримки порівнянь в середовищі NET і дозволяє розробнику визначати, як екземпляр користувальницького типу може бути обчислений у виразі IXMLSerializable є інтерфейсом з простору імен SystemXML, забезпечує підтримку сериализации і десеріалізациі між структурою сховища і потоками XML шляхом підміни методів ReadXML і WriteXML Ще один інтерфейс, цікавий з точки зору користувальницьких типів, використовується у віддалених і внутрішніх організаційних ситуаціях Це інтерфейс IBinarySerialize з простору імен Microsoft SQLServer Server Його методи Read і Write повинні бути реалізовані при використанні формату сериализации UserDef ined

&ltSerializable()&gt _

&ltMicrosoftSqlServerServerSqlUserDefinedType(FormatUserDefined, _

IsByteOrdered:=True, _

IsFixedLength:=True, _

MaxByteSize:=4, _

Name : =111 Pv411) &gt _

Public Structure IPType2

Implements INullable, IComparable, IBinarySerialize,_

IXMLSerializable

Нагадаю, що формат сериализации в атрибуті користувальницького типу SQLUserDef inedType зазвичай визначений як Native Формат сериализации UserDef ined може стати в нагоді у випадках, коли структура або клас користувальницького типу містить властивості, що не відповідають вбудованим в SQL Server числовим і тимчасовим типам До того ж, коли формат визначений як UserDef ined, ідентифікатор властивості IsByteOrdered є обовязковим, а властивість MaxByteSize користувальницького типу повинно знаходитися в діапазоні від 1 до 8 ТОВ Ці обмеження розміру висуває SQL Server Ліміт в 8 Кбайт прояснює причину, по якій бізнес-обєкти поки не можна вважати хорошими кандидатами на реалізацію за допомогою користувацьких типів

Методи Read і Write, необхідні для сериализации UserDefined, виглядають дещо туманно, оскільки в документації відсутня їх чіткий опис На жаль, це може привести багатьох розробників (в Зокрема, тих, хто намагається знайти свій шлях з Т-SQL в NET) до вирішення замкнутися в сериализации Native, уникаючи того, чого вони не розуміють Може, це і стало б хорошим рішенням для рідко використовуваних користувача типів, призначених для реалізації правил бізнес-логіки, проте сериализация Native може стати стримуючим фактором впровадження користувача типів, коли на перше місце виходять питання продуктивності Для прикладу уявімо, наскільки корисно було б сортувати географічні координати по таким атрибутам, як континент, країна або область Аналогічно, уявіть, наскільки зручніше сортувати ЕР-адреси по октетам, а не як єдину рядок Серіалізация Native абсолютно не призначена для потреб подібних угруповань Водночас сериализация UserDefined повністю розвязує програмісту руки в питаннях переміщення та зберігання даних

У документації програми Visual Studio міститься набагато краща дискусія з питань сериализации, ніж в документації з інтеграції CLR в SQL Server На жаль, навіть документація Visual Studio вимагає від читача концептуального підходу до сериализации в середовищі NET Framework Коли вона застосовується в складних бізнес-обєктах, реалізованих за допомогою спеціалізованих користувача типів SQL Server, яким необхідні тільки методи Read і Write, складність таких обєктів може охолодити програміста Серіалізация є нічим іншим, як кодуванням значень всіх полів членів примірника структури або класу в позиційний потік бітів в операціях транспортування і копіювання Дещо дивно дізнатися, що всі поля, загальнодоступні і приватні, повинні бути завантажені і направлені в потік, хоча для розробника було б достатньо явно серіалізовать тільки поля членів, щоб дозволити станом примірника бути точно відтвореним на іншому кінці операції транспортування або копіювання

У прикладах з IP-адресою, описуваних у цій главі, один з типів використовує сериализацию UserDefined Чотирьохбайтові приватні поля повинні завжди перебувати в одній і тій же послідовності, щоб гарантувати представлення одного і того ж IP-адреси Наслідки порушення порядку октетів IP або їх неповноти при транспортуванні очевидні для будь-якого читача, бодай трохи знайомої з мережевим стеком TCP / IP Серіалізация гарантує порядок і якість даних при передачі з бази даних клієнта У методі Read необхідно тільки завантажити поля в обєкт BinaryReader Після цього в методі Write потрібно витягти поля з обєкта Binary Writer точно в тому ж порядку, який використовувався в методі Read

Public Sub Read(ByVal r As System10BinaryReader) _

Implements IBinarySerializeRead m_OctetA = rReadByteO m_OctetB = rReadByteO m_OctetC = rReadByteO m_OctetD = rReadByteO End Sub

Public Sub Write(ByVal w As System10BinaryWriter) _

Implements IBinarySerializeWrite wWrite(m_OctetA) wWrite(m_OctetB) wWrite(m_OctetC) wWrite(m_OctetD)

End Sub

У наведеному вище фрагменті програмного коду октети IP були визначені в порядку від А до D Це не так технічно важливо – головне, щоб порядок полів в методах Read і Write в точності збігався Ця гнучкість продемонстрована в завантаження коді, так само як і реалізація інтерфейсу I Comparable

Тестування та налагодження користувальницького типу

Перед тим як користувальницький тип зможе бути адекватно використаний, успішно скомпільована збірка повинна бути розгорнута в SQL Server До того ж найбільш ймовірні сценарії функціонування повинні включати створення таблиці та виконання солідного пакета інструкцій DML, щоб перевірити правильність роботи нового користувальницького типу в контексті бази даних

Visual Studio в цьому відношенні пропонує для цього етапу розробки корисний компонент Test Scripts рівня проекту Існують три істотних переваги використання цього проекту над розгортанням користувальницького типу на тестовому сервері (навіть якщо Developer Edition SQL Server розгорнутий в тому ж середовищі, що й Visual Studio) і тестуванням за допомогою Management Studio або утиліти командного рядка SQLCMD Перше з них полягає в тому, що увага розробника може бути ексклюзивно сфокусовано на тестуванні функціональності Коли тестовий сценарій використовується в проекті, користувальницький тип може бути розгорнутий і переразвернут в ході розробки за допомогою пункту меню Debug ^ Visual Studio Deploy Коли ж використовується Management Studio або будь-яка інша утиліта, зовнішня по відношенню до Visual Studio, потрібно постійно вручну перевіряти наявність у ній посилання на версію користувальницького типу, скомпільовану останньої Другою перевагою є те, що покрокове проходження зі сценарію Т-SQL за кодом CLR повністю підтримується тільки в інтерфейсі Visual Studio Третя перевага полягає в тому, що версії тестових сценаріїв можна підтримувати за допомогою SourceSafe разом з іншими компонентами проекту

Для створення і видалення будь-яких таблиць і уявлень, на які містяться посилання в тестовому сценарії, корисно створити спеціальні інструкції DDL Це заощадить час, який довелося б витратити на пошук таблиць і уявлень для видалення в них обєктів із змінним в процесі розробки типом

Питання продуктивності

Оптимізація програмного коду CLR вимагає не стільки зусиль, як налаштування продуктивності коду Т-SQL У той час як на практиці доводилося чути безліч історій про перетворення 30-годинний збереженої процедури в 10-хвилинний запит, користувацькі типи інтеграції CLR навряд чи окуплять героїчні зусилля, вкладені в їх оптимізацію Якщо користувача типи створювалися більш-менш коректно, то максимум, чого можна очікувати, – це усунення з коду декількох циклів роботи процесора Якщо реалізація типу була некоректною, то в продуктивності можуть залишитися деякі вузькі місця, і акуратний розробник може їх уникнути Наприклад, якщо в призначеному для користувача типі реалізований метод, що вимагає рівня захисту EXTERNAL_ACCESS, і результат цього методу залишився в наборі даних, коли значення типу було додано в таблицю, користувач повинен усвідомлювати, що не існує способу управління тим, що може статися в процесі вилучення зовнішнього значення Дуже ймовірно, що низька продуктивність операцій введення-виведення повязана із затримками в мережі або несприйнятливими зовнішніми джерелами даних, до яких виконується звернення з програмного коду NET класу користувальницького типу

Розглянемо наступний приклад користувальницького типу IP-адреси, який використовує простір імен SystemNet для перетворення IP-адреси в імя сервера за допомогою класу DNS:

&ltSqlMethod(IsDeterministic:=False)&gt _

Public Function GetDNSNameO As String If Not (MeIsNull) Then GetDNSName = _NULL Else Try

GetDNSName =_

DnsGetHostEntry(IPAddressParse(MeToString))HostName Catch ex As SocketsSocketException

GetDNSName = &quotSocket Error: &quot &amp exSocketErrorCodeToString End Try End If

End Function

Як правило, слід остерігатися мощі інтеграції CLR Припустимо, що Увага описаний вище метод використовується при кожному додаванні IP-адреси в таблицю При цьому імя компютера буде зберігатися в таблиці як обчислюваний стовпець Деякі перешкоди здатні затягнути тривалість транзакції вставки і вивести її за встановлені межі А в SQL Server може трапитися маса несподіваних і непередбачуваних подій, безпосередньо не стосуються виконуваного коду CLR Вузькі місця мережі і конфлікти DNS можуть створити неприпустимий рівень конкуренції в таблиці Все, що залишається в даній ситуації операції вставки, – Це змиритися з затримками До того ж у випадках, коли додається IP-адреса не може бути перетворений в імя вузла, збільшення навантаження за рахунок обробки виключення SocketException для кожного вставляється значення може також стати причиною уповільнення роботи бази даних Іншими словами, потенційні можливості інтеграції CLR можуть запросто призвести до небажаних наслідків, які слід передбачити при створенні та використанні для користувача типів

Як і будь-який інший стовпець даних, стовпець, створений з призначеним для користувача типом, може істотно підняти продуктивність, якщо він буде проіндексовані Стовпець з призначеним для користувача типом може індексуватися тільки в тому випадку, якщо він може бути відсортований в двійковому порядку Гетерогенні користувача типи (тобто ті, які містять суміш вбудованих типів) можуть допомогти створити більш корисні індекси, якщо був ретельно продуманий порядок десеріалізациі полів членів Розглянемо користувальницький тип з інтегральними і символьними полями Якщо символьне поле більш цікаво з точки зору пошуку і є найбільш вірогідним претендентом на включення до вираження аргументу пошуку пропозиції WHERE, при серіалізациі розумно вставляти значення цього поля в сховище першим Обчислювані стовпці, керовані членами класу користувальницького типу, також можуть бути проіндексовані, якщо в атрибути цих членів включено властивість IsDeterministic

Ще одне питання, яке вже обговорювалося в контексті структурних відмінностей семантики значень і посилань, повязаний з тим, що користувацькі типи, створені як структури, мають тип значень і зберігаються в стеку програми, в той час як типи, створені як клас, мають тип посилань і знаходяться в просторі купи обєкта У загальному випадку вплив цієї відмінності на продуктивність невелика У прикладі коду для цієї глави, що міститься на Web-сайті книги, виконується тест продуктивності, який полягає в наступному Виконується одне і те ж кількість вставок в користувача типи, створені за допомогою структур (Семантика значень) і класів (семантика посилань) і вбудованою сериализации Клас користувальницького типу використовує сериализацию UserDef ined і стовпець з вбудованим типом varchar В результаті виконання цього тесту не було помічено значних відмінностей в продуктивності операцій вставки Проте при проектуванні користувальницького типу корисно оцінити витрати на впровадження і знати про існуючі відмінностях

Коли технологія користувача типів інтеграції CLR пробє собі дорогу в додатки, що працюють з SQL Server, природно, виникнуть нові питання, повязані з продуктивністю У цьому процесі компанія Microsoft, безсумнівно, буде поступово удосконалювати модель користувача типів з метою підвищення їх продуктивності

Джерело: Нільсен, Пол Microsoft SQL Server 2005 Біблія користувача : Пер з англ – М: ООО ІД Вільямс , 2008 – 1232 с : Ил – Парал тит англ

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*