Оценить:
 Рейтинг: 0

Вечный двигатель третьего рода. Неканонические размышления о бизнес-системах, или О чём стоит сначала подумать. Модели данных и бизнес-логика

<< 1 2 3 >>
На страницу:
2 из 3
Настройки чтения
Размер шрифта
Высота строк
Поля

– рукописи,

– ксерокопии,

– микрофильмы,

– микрофиши,

– магнитные, оптические и прочие современные нам носители,

– и т. д., и т. п. – в общем, всё, что только может содержать информацию.

Здесь надо немного остановиться. Вопрос касается файлов.

С одной стороны, файл – отдельная законченная единица информации. С другой стороны, в одном файле может содержаться несколько независимых единиц информации – например, оцифрованных книг, репродукций и т. п. И с третьей стороны – один хранимый экземпляр носителя информации (например, компакт-диск) может содержать несколько файлов. Кстати, этот компакт-диск может быть не самостоятельным – а приложением к какой-либо книге…

Остановка получается недолгая, ибо решение очевидно и просто: каждая единица информации (Unity) может быть в то же время и собранием (Collection) подобных единиц.

Вернёмся к теме – Unity.

Каждый экземпляр этой сущности должен представлять собой сочетание атрибутов, уникальным образом характеризующих хранимую единицу информации. На сами же отдельные атрибуты требование уникальности значений может распространяться не всегда. Если атрибут должен иметь уникальное значение, то оно обычно автоматически генерируется программным способом при создании экземпляра сущности (например, в случае целочисленных величин или весовых значений символов логично применить автоинкремент). Если значение атрибута может быть не уникальным, то возможны случаи:

– значение атрибута абсолютно произвольно (так называемый «мануальный ввод»), либо

– значение атрибута должно быть задано из определённого списка значений (выбор из справочника).

В первом случае атрибут должен быть членом структуры объекта (сущности). Во втором же логичнее создать отдельный список возможных значений атрибутов (или же в качестве справочника может выступить список любых других – в том числе и той же самой – сущностей) и устанавливать связь между ним и основным объектом. В конкретных имплементациях такая связь со справочником может устанавливаться либо посредством кросс-структуры (таблицы перекрёстных ссылок), либо прямой ссылкой на запись справочника – но не будем этим заморачиваться, ибо сие суть не принципиально, а исключительно по обстоятельствам.

Отметим, что и уникальные атрибуты могут выбираться из справочников – например, при наличии неких доменных ограничений. В этом случае необходим дополнительный контроль единственности выбора… но, как говорится – любой каприз за ваши ресурсы.

Итак:

Разберём по позициям. На первый раз – подробно.

Unity::id

Уникальный идентификатор, который будет использоваться для организации связей с другими структурами данных библиотеки. Требования к нему:

– лёгкость автоматического генерирования уникальных значений,

– достаточный (для конкретной информационной системы – в нашем случае это библиотека) диапазон возможных значений,

– минимальный физический размер поля.

Третий пункт в современном дизайне баз данных как-то особенно не подчёркивается, однако – при всём уважении к постоянно возрастающему быстродействию вычислительной техники, не стоит заниматься наплевательским расходованием её ресурсов – поиск в двоичном дереве в итоге тем быстрее, чем короче ключевое поле.

Всем необходимым условиям вполне (на мой взгляд; можете не соглашаться) удовлетворяет тип integer (unsigned integer – если оперировать терминами языков программирования типа C/C++): при длине поля в четыре байта диапазон значений составляет от 0 до 4 294 967 295 (0xffffffff в шестнадцатеричном представлении). К примеру, для типа numeric, представляющего собой фактически вариант формата char, потребовалось бы поле длиной в десять байт. Уникальность значений легко обеспечивается автоинкрементом (большинство современных реляционных баз данных обеспечивают это на стороне сервера БД – достаточно задать полю соответствующее свойство). Для быстрого поиска идентификатора в таблице по этому полю должен существовать индекс.

И, естественно, поле идентификатора должно быть заполнено всегда.

Unity::code

Уникальный библиотечный код – своего рода инвентарный номер, присваиваемый хранимой единице (книге, журналу и т. п.) при поступлении в фонд библиотеки.

Условный формат string подразумевает возможность наличия в коде не только цифр, но также букв и спецсимволов. Код может состоять из нескольких частей, несущих в себе, например, классификационную информацию, информацию о месте хранения и т. д. Всё это специфично для каждой конкретной библиотеки – поэтому конкретный размер поля не предлагается. В принципе, если это целесообразно, то вместо одного поля (атрибута) может быть несколько – по числу обязательных частей; полный код в таком случае собирается из этих полей по соответствующему правилу.

Естественно, код должен быть уникальным. Однако, учитывая специфику предлагаемой модели данных, а именно: то, что единица информации может быть одновременно собранием (коллекцией) единиц, – это поле может оставаться незаполненным. Может и вообще отсутствовать – если система учёта в конкретной библиотеке такого кода не предусматривает.

Для возможности быстрого поиска, сортировки и группировок по коду – индексация.

Unity::name

Имя хранимой единицы. Название книги, рукописи, имя файла и т. п. Также – в случае сборников-коллекций – наименование собрания сочинений, серии книг («Миры Клиффорда Саймака», например, или «Мир приключений»), журнала (элементы коллекции – отдельные номера) и т. д.

Значение поля может быть (и чаще всего так оно и есть) не уникальным, однако – в отличие от библиотечного кода – оно должно быть обязательно. Насчёт длины поля (поле, естественно, должно быть произвольно-символьным) чёткие рекомендации давать трудно… приведу пример названия одного широко известного произведения (которое вполне может встречаться в виде отдельной книги): «Жизнь, необыкновенные и удивительные приключения Робинзона Крузо, моряка из Йорка, прожившего 28 лет в полном одиночестве на необитаемом острове у берегов Америки близ устьев реки Ориноко, куда он был выброшен кораблекрушением, во время которого весь экипаж корабля кроме него погиб, с изложением его неожиданного освобождения пиратами; написанные им самим». В этом плане проще с именами файлов: операционные системы налагают конкретные ограничения на их длину (Unix – 255, Windows – 257, Mac OS X – 256 символов соответственно). В зависимости от конкретной задачи – т. е., планируемого основного содержания библиотеки и платформы реализации – string может быть реализован, например, как TEXT, CHAR (n) либо VARCHAR (n), где n – длина поля.

Индексация по этому полю желательна как для возможности сортировки по алфавиту, так и для структурного поиска (по вхождению слов). Частный пример реализации второго случая – использование DB2 Text Extender.

Unity::path

Местоположение хранимой единицы. Как и в случае библиотечного кода, формат данного поля представлен чисто условно. В реальной системе это должен быть либо конкретный адрес, где находится книга (либо другой хранимый объект) – комната, шкаф/стеллаж, полка/ячейка, – и тогда рациональней использовать набор из нескольких полей (атрибутов), либо путь к файлу – тогда, как и для поля name, будут действовать зависящие от платформы реализации ограничения на длину. Но и в этом случае – поскольку полный путь включает сетевое имя сервера (или сетевого диска; или локального диска – если сервер один) и иерархию каталогов – удобнее всё же будет использовать набор полей.

Естественно, требование уникальности неприменимо к местоположению/пути в любом случае: как на одной полке может стоять много книг, так и в одном каталоге может находиться множество файлов.

Если сущность определяется как Collection – то единого пути может не быть (подшивка Chemical Abstracts за несколько десятков лет ну никак не вместится на одну полку), и атрибут (или набор атрибутов) будет не заполнен. Но это – только для Collection, все единичные Unity – в том числе и входящие в различные Collection – должны где-то находиться, и path у них должен быть заполнен (см., впрочем, 

).

Совершенно закономерен здесь вопрос (если следить за процессом рассуждений внимательно – а не по принципу «в одно ухо вошло – из другого… м-м-м…») о правомерности существования этого самого атрибута: зачем он здесь, если местоположение хранимой единицы достаточным образом описывается связью placed_on к объекту Placeholder?

Атрибут Unity::path является производным (образно говоря, суммой по некоторым – конкретным для каждой имплементации – правилам) от полной иерархии связанных по placed_on объектов Placeholder, а именно атрибутов Placeholder::path. Содержимое его, соответственно, меняется синхронно изменениям в иерархии связанных объектов Placeholder (как это будет реализовано – на уровне базы данных, или же на уровне приложения – целиком на совести имплементатора).

Возможно, это некое нарушение «стройности изложения», но подобные – явно необходимые – случаи денормализации всё же лучше предусматривать заранее, чтобы по возможности избегать множественных итераций при дизайне структур данных.

*)

Поскольку информация о местоположении хранимой единицы может либо содержаться в атрибуте Unity::path, либо быть закодирована в поле Unity::code, то для случая обязательного наличия информации о местоположении Unity должно существовать и быть заполнено хотя бы одно из этих полей.

Коллекции (Collection)

Добавим теперь «второе лицо» сущности Unity – способность представлять собой объект Collection. Сделать это можно разными способами – в зависимости от конкретной концепции организации коллекций.

Для простоты и наглядности просто представим ситуацию в виде графа:

То есть, каждая единица может быть (либо не быть) коллекцией ненулевого числа отдельных хранимых единиц (связь collection_of), а каждая хранимая единица заведомо существует и может входить (либо не входить) в различное число коллекций (показано связью collected_in).

Например, роман «Война и мир» Льва Николаевича Толстого (бумажная книга без приложений в виде компакт-диска с аудио-версией или ролевой игрой по сюжету) коллекцией сам не является, но в принципе может являться частью коллекции «Сочинения Л. Н. Толстого» (если какое-либо издательство выпустило такую серию). Но: если коллекцией является некое «Собрание сочинений Л.Н.Толстого в… томах», то элементом такой коллекции будет не конкретное произведение, а «Том номер такой-то». А какие произведения будут в этом томе – уже дело содержания. В общем, хозяин – барин, но принцип понятен.

Оговорка насчёт «бумажной книги без приложений» весьма существенна: книга по какой-либо проблеме программирования, к которой прилагается диск с примерами, в данной схеме – уже коллекция.
<< 1 2 3 >>
На страницу:
2 из 3