|
| ||||||||||||
| ||||||||||||
|
2008 г.
Принципы организации иерархии атомарных литеральных типов объектной системы на основе РСУБД Microsoft SQL Server 2005Олейник П.П., к.т.н. Благодаря наличию большого количества коммерческих и свободно распространяемых реляционных систем баз данных (РСУБД), именно данные продукты являются доминирующим программным обеспечением, используемым для хранения информации широкого круга прикладных предметных областей. При этом для построения графического интерфейса пользователя (ГИП), серверов приложений, распределённых объектов и т.п. чаще всего используют объектно-ориентированные языки программирования (ООЯП). Из-за различий в концепциях и областях применения РСУБД и ООЯП возникает так называемое объектно-реляционное несоответствие (ОРН) [1]1. Для снижения последствий ОРН широко используются методы (паттерны) объектно-реляционного отображения (ОРО, Object-Relational Mapping), суть применения которых заключается в возможности реализации элементов объектной системы (описания классов, создания иерархии наследования, описание отношений между классами и т.п.) на основе реляционной БД. Методы ОРО особое внимание уделяют проблеме сохранения экземпляров классов, значений атрибутов и т.п. С точки зрения реализации все методы ОРО можно разделить на две категории: Под метаинформацией подразумевается наличие информации об объектной системе, такой как состав атрибутов и структура классов, описание иерархии наследования и принадлежности атрибутов к определенным классам. Учитывая тенденцию повсеместного добавления метаинформации в объектно-ориентированные языки программирования (Delphi, Java, С#), можно утверждать, что именно методы второй категории наиболее перспективны, так как их применение позволяет значительно расширять и изменять модель предметной области системы, не внося изменений в физическую структуру базы данных (БД). Несмотря на различие в подходах и физической структуре таблиц, конечным результатом применения методов ОРО является реализация возможности объявления классов и сохранения объектов (экземпляров классов с заданными значениями атрибутов), представляющих сущности прикладной предметной области. Проектирование объектной системы начинается с выделения классов, атрибутов классов и определения для них подходящих типов данных. Большая часть атрибутов в любой объектной системе описывается атомарным литеральным типом данных (целые числа, строки, символы, дробные числа и т.п.). С точки зрения реализации методов ОРО унификация иерархии подобных типов является ключевой проблемой, возникающей при организации объектной системы на основе РСУБД. Несмотря на наличие достаточно большого количества работ, посвящённых методам объектно-реляционного отображения, в каждой из них уделяется недостаточно внимания принципам организации атомарных литеральных типов в объектной системе. При этом существует несколько ортогональных подходов к решению описанной задачи. В работах, посвященных методам ОРО без поддержки метаинформации, атрибуты классов отображаются непосредственно на поля таблиц, в которых сохранены экземпляры классов [1-3]. При этом используются типы данных, присутствующие в СУБД. Так как данные методы предполагают выделение таблиц для сохранения объектов конкретной предметной области, то в них не предусмотрена унификация иерархии литеральных типов. В методах ОРО с поддержкой метаинформации, например, в «Сущность-Атрибут-Значение» (САЗ, Entity-Attribute-Value, EAV) выполняется выделение отдельных таблиц для представления конкретного типа данных [4]. При этом для каждого атрибута указывается имя таблицы, в которой будет физически сохраняться значение для конкретного объекта. Рассмотрим недостатки известных методов организации объектной системы в РБД и причины, не позволяющие успешно решать описанную задачу:
Целью данной статьи является разработка унифицированной иерархии атомарных литеральных типов, применимой в любой объектной системе, построенной на основе реляционной базы данных. В полученной реализации должны отсутствовать недостатки, присущие имеющимся реализациям, и все выделенные типы не должны зависеть ни от типов, присутствующих в РСУБД, ни от метода ОРО, применённого при построении объектной системы. В заключении статьи представлена иерархия атомарных типов, построенная на основе типов данных, которые поддерживаются в РСУБД Microsoft SQL Server 2005. Для проектирования оптимальной иерархии необходимо рассмотреть имеющиеся решения сходных задач, т.е. спецификацию как объектных расширений языка SQL (SQL:2003), так и объектно-ориентированных БД (ODMG 3.0). Рассмотрим спецификацию ODMG 3.0. На рис. 1 изображён фрагмент метамодели ODMG 3.0, на котором описаны метаклассы, выделенные для представления атомарных литеральных типов [7-8].
Рисунок требует пояснений. Для представления атомарных литеральных типов выделены класс d_Primitive_Type и перечисление d_TypeId. Причина выделения единственного класса в том, что в спецификации ODMG метамодель объектной системы логически отделена от атомарных типов (классов), имеющихся в системе (чисел, строк, коллекций, множеств и т.п.). С нашей точки зрения, такой подход имеет ряд недостатков. Присутствие одного класса предполагает наличие фиксированного набора атрибутов, т.е. каждый атомарный литеральный тип описывается определённым количеством параметров. Поэтому заранее необходимо выделить максимальное число атрибутов, часть из которых для определённых типов данных не будет иметь смысла. Для типа String, представляющего символьную строку, достаточно указать лишь длину (количество символов), а для типа Numeric, позволяющего сохранять дробные числа, потребуется указать уже два свойства: первое - для определения максимального количества символов в числе, а второе - для определения точности значения (количества символов после запятой). Для занесения информации об этих типах данных в классе d_Primitive_Type потребуется объявить оба свойства. При этом для типа String второе свойство избыточно и его значение не анализируется. В модели ODMG для определения встроенных атомарных литеральных типов выделено перечисление d_TypeId, которое содержит список зарезервированных констант. Этот список не может модифицироваться с целью отражения потребностей конкретного приложения. То есть недопустимо добавление новых литеральных типов. Тем не менее, имеется возможность создать псевдонимы типов, для представления которых выделен класс d_Alias_Type. Кроме того, в d_Primitive_Type отсутствует атрибут, предназначенный для сохранения информации о базовом классе примитивного типа. Т.е. атомарные литеральные типы в стандарте ODMG не организованы в иерархию. Перейдём к рассмотрению языка SQL. На рис. 2 представлен фрагмент онтологии типов данных, реализующих объектные расширения языка SQL:2003 [9].
На рис. 2 видно, что для представления атомарных литеральных типов, которые в стандарте называются предопределёнными, выделен единственный класс Predefined. Т.е. стандарту SQL:2003 присущи недостатки, описанные в отношении представления литеральных типов в метамодели ODMG 3.0. Для реализации оптимальной, с нашей точки зрения, иерархии атомарных литеральных классов необходимо определить критерии оптимальности (КО):
4. Чёткая структуризация атомарных литеральных классов, которая предполагает введение промежуточных корневых подклассов, определяющих такие категории (и подкатегории) типов данных как числа, целые числа и т.п. При этом каждый корневой класс категории (подкатегории) должен быть абстрактным, а унаследованные от него реализованные классы определяют конкретный тип данных (например, короткое целое, длинное целое и т.п.). На рис. 3 представлена иерархия атомарных литеральных типов, удовлетворяющая сформулированым критериям. Рисунок требует пояснений. Все литеральные типы унаследованы от базового абстрактного класса AtomicLiteral. Этот класс в свою очередь может быть производным от корневого класса всей иерархии объектной системы. Тем самым реализован КО1, т.к. в единой иерархии присутствуют как классы метамодели объектной системы, так и классы доменов. Для каждой категории (числа, Number) и подкатегории (целые числа (IntegerNumber), дробные числа (FractionNumber)) типов данных введён абстрактный класс, от которого унаследованы реализованные классы (КО4). Рис. 3. Иерархия литеральных типов объектной системы, отвечающая выделенным критериям При сохранении (извлечении) экземпляра класса можно с помощью операции is проверить тип его класса и в соответствии с полученным результатом обработать его требуемым образом. Кроме того, для каждой категории типов, например, для целых чисел, выделен абстрактный базовый класс (IntegerNumber), от которого унаследованы конкретные реализации атомарных литеральных типов, входящих в группу (BigInt, Int, SmallInt, TinyInt, Bit). Такая реализация соответствует требованию КО4. Для введения дополнительного типа, позволяющего сохранять значения целых чисел, достаточно создать класс производный от IntegerNumber. Тем самым, реализован КО1, в котором требуется представление возможности определения производных классов от литеральных типов. Как видно на рис. 3, каждый из присутствующих классов имеет только одного родителя, т.е. при проектировании иерархии использовано одиночное наследование, что позволило упростить реализацию и соответствует требованию КО2. В отличие от метамодели стандарта ODMG [7-8], активно применяющей множественное наследование (что связанно с использованием языка C++, в котором эта функциональность присутствует), в нашей реализации используется только одиночное наследование. Многие современные ООЯП (C#, Java) не поддерживают множественное наследование, поэтому представленная иерархия упрощает отображение присутствующих в ней классов на типы, имеющиеся в целевом языке. В случае необходимости для получения преимуществ, которые раньше достигались за счёт использования множественного наследования, можно применять интерфейсы. Следует отметить, что представленная иерархия является унифицированной и не зависит от типов данных, присутствующих в какой-либо конкретной РСУБД (КО3). В отличие от существующих работ, посвящённых методам ОРО и описанных с позиции их реализуемости в конкретной СУБД, представленная иерархия оперирует в конечном счёте группами типов, каждая из которых имеет в своём составе абстрактный корневой тип. Как видно на рис. 3, для классов активно используется отношение наследования, которое поддерживается не в каждой РСУБД. При этом во всех объектно-реляционных СУБД отсутствует наследование пользовательского типа от встроенного литерального. Имеется лишь возможность создания псевдонима типа, что по функциональным возможностям гораздо уже, чем отношение наследования. Описанная иерархия может быть применена в любой предметной области, т.к. она ортогональна к любой из них и оперирует такими общими сущностями, как целые числа, дробные числа, символьные строки, бинарные строки и т.п. Этот подход удовлетворяет КО3 и не требует изменения представленных классов при реализации бизнес-объектов конкретной предметной области. Однако допускается введение дополнительных литеральных типов, унаследованных от объявленных ранее. Все присутствующие классы не привязаны к каким-либо конкретным типам данных, имеющимся в языке программирования (КО3). Поэтому при реализации конкретного приложения потребуется задать отображение (mapping) литеральных типов данных объектной системы на встроенные типы ООЯП. Подобный подход используется в стандарте ODMG, в котором определены отображения на языки С++, Java, SmallTalk [7-8]. При этом ИС проектируется в понятиях типов, присутствующих в объектной модели, а отображение выполняется при реализации клиентского приложения, что позволяет уменьшить зависимость отдельных звеньев системы друг от друга. Подведя итог, можно утверждать, что описанная иерархия литеральных типов соответствует выдвинутым критериям оптимальности. Перейдём к вопросу о возможности практического применения разработанной иерархии в среде конкретной СУБД на примере Microsoft SQL Server 2005 [10]. Так как в соответствии с выделенными критериями оптимальности полученная иерархия атомарных литеральных типов (рис. 3) не зависит ни от конкретной предметной области, ни от целевой РСУБД (типов данных, которые в ней поддерживаются) и при этом позволяет определять производные классы, нам достаточно объявить дополнительные классы, которые однозначно соответствуют встроенному в СУБД типу данных. На рис. 4 изображена диаграмма классов иерархии литеральных типов для объектной системы, реализованной в среде СУБД Microsoft SQL Server 2005. Рис. 4. Иерархия литеральных типов для СУБД Microsoft SQL Server 2005 Левая часть рисунка, на которой изображены классы, представляющие целые типы данных (производные от IntegerNumber) осталась неизменной потому, что данные типы присутствуют в Microsoft SQL Server 2005. Однако некоторые классы значений времени (классы, производные от Period) отсутствуют на рис. 4. Были исключены классы: Date, Time, Interval, т.к. подобных типов данных нет в целевой СУБД [10]. Отметим, что в версии Microsoft SQL Server 2008 появятся как типы данных, представляющие значения даты и времени (Date, Time, DateTime2, DateTimeOffset), так и тип, позволяющий организовать данные в иерархию (HierarchyId). В новой версии СУБД появятся типы, позволяющие сохранять географические (тип Geography) и геометрические (тип Geometry) координаты [11]. В последствии необходимо добавить эти типы данных к разработанной иерархии. Ключевые изменения, представленные на рис. 4, коснулись корневых классов, соответствующих точным дробным числам (Numeric), приближенным дробным числам (Float), бинарным строкам как фиксированной длины (Binary), так и переменной длины (VarBinary), а также классов символьных строк, сохраняющих не только однобайтовые символы (Char, VarChar), но и позволяющих сохранять двубайтовые символы (NChar, NVarChar). Все описанные выше классы сделаны абстрактными (см. рис.3 и рис.4) и, с нашей точки зрения, стали представлять собой категорию типов данных. Причина в том, что в выбранной СУБД для сохранения значений обозначенных типов данных необходимо указать максимальную длину в символах, а для дробных чисел требуется также указать и точность (количество символов после запятой) значения. Заданные параметры играют ключевую роль при расчёте занимаемого физического пространства, необходимого для значения [10]. Поэтому для класа Numeric выделены четыре абстрактных подкласса. Класс Numeric9_X предназначен для хранения чисел, имеющих длину 9 символов и занимающих в памяти 5 байтов; Numeric19_X позволяет сохранить числа, имеющие длину 19 символов и занимающих в памяти 9 байтов; Numeric28_X требует для сохранения значений 13 байтов, а Numeric38_X для этого потребуется уже 17 байтов. Для сохранения значений, имеющих определённую точность, выделены реализованные классы, производные от описанных четырёх абстрактных. Тот же подход использован для классов, унаследованных от Float. Значения типа данных Float24 могут иметь длину до 7 знаков и занимают 4 байта, а значения типа Float53 – длину до 15 знаков и занимают 8 байтов. В языке Transact-SQL имеется тип данных SQL_Variant, который в нашем случае является аналогом типа данных Variant, представленного на рис. 3. Строки (как бинарные, так и символьные) требуют указания максимальной длины сохраняемого значение. На рис. 4 присутствуют реализованные классы, представляющие строки с заданной максимальной длиной. Следует учесть, что строки переменной длины (VarBinary, VarChar, NVarChar) в SQL Server могут иметь неограниченную длину; при спецификации соответствующего типа необходимо указать ключевое слово Max. Для подобных типов данных выделены соответствующие классы (VarBinaryMax, VarCharMax, NVarCharMax). СУБД SQL Server 2005 имеет в своём составе типы данных Cursor и Table, которые не рассматриваются в данной статье потому, что они не являются атомарными литеральными. Стоит отметить, что при проектировании приложения для конкретной предметной области при описании типов данных для атрибутов классов следует применять реализованные (не абстрактные) классы. Это связано с тем, что выделенная иерархия предполагает её использование при реализации объектной системы на основе РСУБД и в конечном счёте подразумевает сохранение значений атрибутов в полях таблиц БД. В случае использования абстрактных классов возникает неоднозначность при сохранении значений, что может привести к их урезанию и/или искажению. В статье рассмотрена проблема организации иерархии атомарных литеральных типов объектной системы, построенной на основе РСУБД. Изучены имеющиеся реализации (метамодель стандарта ODMG 3.0, онтология SQL:2003), отмечены присущие недостатки и сформулированы критерии оптимальности, которым должна соответствовать спроектированная иерархия. На рис. 3 изображена оптимальная реализация, которая является унифицированной и не привязана ни к конкретному методу ОРО, ни к конкретной СУБД, а на рис. 4 представлена иерархия атомарных классов, организованных в соответствии с типами данных, имеющимися в СУБД Microsoft SQL Server 2005. Дальнейшее развитие спроектированной иерархии должно выполняться в плане добавления классов, описывающих метамодель объектной системы, а также классов, являющихся базовыми для сущностей предметной области. Кроме того, для построения реальной объектной системы на основе РБД потребуется добавление классов, экземпляры которых представляют коллекции, множества, перечисления и т.п. Также необходимо разработать общий механизм выборки значений, присутствующих в каждой таблице, представляющей отдельный атомарный литеральный тип данных. БлагодарностьАвтор выражает признательность Кузнецову Сергею Дмитриевичу за то, что тот ознакомился с первоначальной версией данной статьи и активно способствовал её опубликованию. Литература
1 Т.к. в русскоязычной литературе не сформировался устоявшийся перевод термина «Object-Relational Impedance Mismatch», то автором предложен собственный вариант, который (в отличие от имеющихся) явно указывает на наличие несоответствия между реляционной моделью данных и принципами объектно-ориентированной парадигмы. |
|
CITForum © 1997–2025