Правильная ссылка на эту страницу
http://az-design.ru/Projects/AzBook/Review/LITMO.shtml

БД "Библиотека" из учебника В.В.Кириллова (ЛИТМО)
(http://www.citforum.ru/database/dbguide/index.shtml)

       Прежде чем рассматривать существующие БД, рассмотрим как учат проектированию БД в одном из очень приличных ВУЗов — Санкт-Петербургском Государственном институте точной механики и оптики. В 5 главе учебного пособия "Основы проектирования реляционных баз данных", написанного профессором Кирилловым Владимиром Васильевичем приведен пример проектирования очень простой (как кажется) БД "Библиотека". Чтобы иметь возможность ссылаться на отдельные фрагменты, приведем эту главу полностью.

Глава 5. Пример проектирования базы данных "Библиотека"

5.1. Назначение и предметная область

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

Д27

Дейт К. Руководство по реляционной СУБД DB2 / Пер. с англ. и предисл. М.Р.Когаловского. – М.: Финансы и статистика, 1988. – 320 с.: ил.

ISBN 5-279-00063-9

Книга американского специалиста в области реляционных баз данных К.Дейта, автора популярной в СССР монографии "Введение в системы баз данных" (М.: Наука, 1981), представляет собой руководство по перспективной СУБД фирмы ИБМ DB2, сочетающей возможности широко известной системы IMS/VS и реляционной СУБД.

Для специалистов по программному обеспечению информационных систем и студентов вузов.

ББК 32.973


Рис. 5.1. Макет аннотированной каталожной карточки

       Для ведения библиотечных каталогов, организации поиска требуемых изданий и библиотечной статистики в базе должны храниться сведения, большая часть которых размещаются в аннотированных каталожных карточках (рис. 5.1). Анализ запросов на литературу (как читателями, так и сотрудниками библиотек) показывает, что для поиска подходящих изданий (по тематике, автору, художнику, издательству и т.п.) и отбора нужного (например, по аннотации) следует выделить следующие атрибуты каталожной карточки:
       1. Автор (фамилия и имена (инициалы) или псевдоним каждого автора издания).
       2. Название (заглавие) издания.
       3. Номер тома (части, книги, выпуска).
       4. Вид издания (сборник, справочник, монография, ...).
       5. Составитель (фамилия и имена (инициалы) каждого из составителе издания).
       6. Язык, с которого выполнен перевод издания.
       7. Переводчик (фамилия и инициалы каждого переводчика).
       8. Под чей редакцией (фамилия и имена (инициалы) каждого из титульных редакторов).
       9. Художник (фамилия и имена (инициалы) каждого художника-иллюстратора) — для художественных изданий, иллюстрируемых оригинальными рисунками.
       10. Повторность издания (второе, одиннадцатое и т.п.).
       11. Характер переиздания (исправленное, дополненное, переработанное, стереотипное и т.п.).
       12. Место издания (город).
       13. Издательство (название издательства).
       14. Год выпуска издания.
       15. Издательская аннотация или реферат.
       16. Библиотечный шифр (например, ББК 32.973).
       17. Авторский знак (например, Д27).

       Библиотечный шифр и авторский знак используются при составлении каталогов и организации расстановки изданий на полках: по содержанию (в соответствии с библиотечным шифром) и алфавиту (в соответствии с авторским знаком).
       Библиотечно-библиографическая классификация (ББК) распределяет издания по отраслям знания в соответствии с их содержанием. В ней используется цифро-буквенные индексы ступенчатой структуры.
       Каждый из девяти классов (1. Марксизм-ленинизм; 2. Естественные науки; 3. Техника. Технические науки; 4. Сельское и лесное хозяйство; 5. Здравоохранение; 6/8. Общественные и гуманитарные науки; 9. Библиографические пособия. Справочные издания. Журналы.) делится на подклассы и следующие ступени деления:

 3. Техника. Технические науки.
          32 Радиоэлектроника.
             32.97 Вычислительная техника.
                32.973 Электронные вычислительные-машины и устройства.
                   32.973.2 Электронно-вычислительные машины и устройства дискретного действия.

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

       К объектам и атрибутам, позволяющим охарактеризовать отдельные экземпляры изданий (переплеты), места их хранения и читателей, можно отнести:
       18. Номер комнаты (помещения для хранения переплетов).
       19. Номер стеллажа в комнате.
       20. Номер полки на стеллаже.
       21. Номер (инвентарный номер) переплета.
       22. Дата приобретения конкретного переплета.
       23. Цена конкретного переплета.
       24. Дата размещения конкретного переплета на конкретном месте.
       25. Дата изъятия переплета с установленного места.
       26. Номер читательского билета (формуляра).
       27. Фамилия читателя.
       28. Имя читателя.
       29. Отчество читателя.
       30. Адрес читателя.
       31. Телефон читателя.
       32. Дата выдачи читателю конкретного переплета.
       33. Срок, на который конкретный переплет выдан читателю.
       34. Дата возврата переплета.

5.2. Построение инфологической модели

       Анализ определенных выше объектов и атрибутов позволяет выделить сущности проектируемой базы данных и, приняв решение о создании реляционной базы данных, построить ее инфологическую модель на языке "Таблицы-связи" (рис. 5.2).
       К стержневым сущностям можно отнести:
       1. Создатели (Код создателя, Создатель).
       2. Эта сущность отводится для хранения сведений об основных людях, принимавших участие в подготовке рукописи издания (авторах, составителях, титульных редакторах, переводчиках и художниках). Такое объединение допустимо, так как данные о разных создателях выбираются из одного домена (фамилия и имена) и исключает дублирование данных (один и тот же человек может играть разные роли в подготовке разных изданий). Например, С.Я.Маршак писал стихи (Сказка о глупом мышонке) и пьесы (Двенадцать месяцев), переводил Дж.Байрона, Р.Бернса, Г.Гейне и составлял сборники стихов.
       3. Так как фамилия и имена (инициалы) создателя могут быть достаточно громоздкими (М.Е. Салтыков-Щедрин, Франсуа Рене де Шатобриан, Остен Жюль Жан-Батист Ипполит и т.п.) и будут многократно встречаться в разных изданиях, то их целесообразно нумеровать и ссылаться на эти номера. Для этого вводится целочисленный атрибут "Код_создателя", который будет автоматически наращиваться на единицу при вводе в базу данных нового автора, переводчика или другого создателя.
       4. Аналогично создаются: Код_издательства, Код_заглавия, Вид_издания, Код_характера, Код_языка, Номер_билета, Номер_переплета, Код_места и Код_издания, замещающие от одного до девяти атрибутов.
       5. Издательства (Код_издательства, Название, Город).
       6. Заглавия (Код_заглавия, Заглавие).
       7. Выделение этой сущности позволит сократить объем данных и снизить вероятность возникновения противоречивости (исключается необходимость ввода длинных текстовых названий для различных томов собраний сочинений, повторных изданий, учебников и т.п.).
       8. Вид_издания (Вид_издания, Название_вида).
       9. Характеры (Код_характера, Характер_переиздания).
       10. Языки (Код_языка, Язык, Сокращение).
       11. Кроме названия языка хранится его общепринятое сокращение (англ., исп., нем., фр.), если оно существует.
       12. Места (Код_места, Номер_комнаты, Номер_стеллажа, Номер_полки).
       13. Один из кодов этой сущности (например, "-1") отведен для описания обобщенного места, находящегося за стенами хранилища книг (издание выдано читателю, временно передано другой библиотеке или организации).
       14. Читатели (Номер_билета, Фамилия, Имя, Отчество, Адрес, Телефон).

Две ключевые сущности, описывающие издание и его конкретные экземпляры, оказываются зависимыми от других сущностей и попадают в класс обозначений:
       1. Издание (Код_издания, Код_заглавия, Вид_издания, Номер_тома, Авторский_знак, Библиотечн_шифр, Повторность, Код_издательства, Год_издания, Аннотация) [Заглавия, Вид_издания, Издательства];
       2. Переплеты (Номер_переплета, Код_издания, Цена, Дата_приобретения)[Издания];
       Стержневые сущности и обозначения связаны между собой ассоциациями:
       1. Авторы [Создатели M, Издание N] (Код_создателя, Код_издания).
       2. Составители [Создатели M, Издания N] (Код_создателя, Код_издания).
       3. Редакторы [Создатели M, Издания N] (Код_создателя, Код_издания).
       4. Художники [Создатели M, Издания N] (Код_создателя, Код_издания).
       5. Переводчики [Создатели M, Издания N] (Код_создателя, Код_издания, Язык).
       6. Переиздания [Характеры M, Издания N] (Код_характера, Код_издания).
       7. Размещение [Места M, Переплеты N] (Код_места, Номер_переплета, Дата_размещения, Дата_изъятия).
       8. Выдача [Читатели M, Переплеты N] (Номер_билета, Номер_переплета, Дата_выдачи, Срок, Дата_возврата).
       И, наконец, для уменьшения объема часто используемого обозначения "Издания" из него выделена характеристика:
       1. Аннотации (Код_издания, Аннотация) {Издание}.

Рис. 5.2. Инфологическая модель базы данных "Библиотека", построенная с помощью языка "Таблицы-связи"

5.3. Проектирование базы данных

       В соответствие с процедурой проектирования (п.4.4) каждая из полученных сущностей должна быть представлена базовой таблицей. Первый вариант этих таблиц описывается так:

СОЗДАТЬ ТАБЛИЦУ Создатели *( Стержневая сущность )
 ПЕРВИЧНЫЙ КЛЮЧ ( Код_создат )
           ПОЛЯ ( Код_создат Целое, Фам_ИО Текст 30 );
СОЗДАТЬ ТАБЛИЦУ Издательства *( Стержневая сущность )
 ПЕРВИЧНЫЙ КЛЮЧ ( Код_издательства )
           ПОЛЯ ( Код_издательства Целое, Название
                  Текст 40, Город Текст 25 );
СОЗДАТЬ ТАБЛИЦУ Заглавия *( Стержневая сущность )
 ПЕРВИЧНЫЙ КЛЮЧ ( Код_заглавия )
           ПОЛЯ ( Код_заглавия Целое, Заглавие Запись );
СОЗДАТЬ ТАБЛИЦУ Вид_издания *( Стержневая сущность )
 ПЕРВИЧНЫЙ КЛЮЧ ( Вид_издания )
           ПОЛЯ ( Вид_издания Целое, Название_вида Текст 16);
СОЗДАТЬ ТАБЛИЦУ Характеры *( Стержневая сущность )
 ПЕРВИЧНЫЙ КЛЮЧ ( Код_характера )
           ПОЛЯ ( Код_характера Целое, Характер_переиздания Текст 16 );
СОЗДАТЬ ТАБЛИЦУ Языки *( Стержневая сущность )
 ПЕРВИЧНЫЙ КЛЮЧ ( Код_языка )
           ПОЛЯ ( Код_языка Целое, Язык Текст 16, Сокращение Текст 6 );
СОЗДАТЬ ТАБЛИЦУ Места *( Стержневая сущность )
 ПЕРВИЧНЫЙ КЛЮЧ ( Код_места )
           ПОЛЯ ( Код_места Целое, Номер_комнаты Целое,
                  Номер_стелажа Целое, Номер_полки Целое );
СОЗДАТЬ ТАБЛИЦУ Читатели *( Стержневая сущность )
 ПЕРВИЧНЫЙ КЛЮЧ ( Ном_билета )
           ПОЛЯ ( Ном_билета Целое, Фамилия Текст 20, Имя Текст 16,
                  Отчество Текст 20, Адрес Текст 60, Телефон Текст 9 );
СОЗДАТЬ ТАБЛИЦУ Издание *( Обозначение )
 ПЕРВИЧНЫЙ КЛЮЧ ( Код_издания )
   ВНЕШНИЙ КЛЮЧ ( Код_заглавия ИЗ Заглавия
                  NULL-значения НЕ ДОПУСТИМЫ
                  УДАЛЕНИЕ ИЗ Заглавия ОГРАНИЧИВАЕТСЯ
                  ОБНОВЛЕНИЕ Заглавия.Код_заглавия ОГРАНИЧИВАЕТСЯ)
   ВНЕШНИЙ КЛЮЧ ( Вид_издания ИЗ Вид_издания
                  NULL-значения ДОПУСТИМЫ
                  УДАЛЕНИЕ ИЗ Вид_издания ОГРАНИЧИВАЕТСЯ
                  ОБНОВЛЕНИЕ Вид_издания.Вид_издания КАСКАДИРУЕТСЯ)
   ВНЕШНИЙ КЛЮЧ ( Код_издательства ИЗ Издательства
                  NULL-значения НЕ ДОПУСТИМЫ
                  УДАЛЕНИЕ ИЗ Издательства ОГРАНИЧИВАЕТСЯ
                  ОБНОВЛЕНИЕ Издательства.Код_издательства КАСКАДИРУЕТСЯ)
           ПОЛЯ ( Код_издания Целое, Код_заглавия Целое,
                  Вид_издания Текст 16, Номер_тома Целое,
                  Авторский_знак Текст 3, Библиотечн_шифр Текст 12,
                  Повторность Целое, Код_издательст- ва Целое,
                  Год_издания Целое )
    ОГРАНИЧЕНИЯ ( 1. Значения полей Код_заглавия, Вид_издания
                  и Код_издательства должны принадлежать набору значений
                  соответствующих полей таблиц Заглавия, Вид_издания
                  и Издательства; при нарушении вывод сообщения "Такого
                  заглавия нет", "Такого вида издания нет" или "Такого
                  издательства нет". );
СОЗДАТЬ ТАБЛИЦУ Переплеты *( Обозначение )
 ПЕРВИЧНЫЙ КЛЮЧ ( Номер_переплета )
   ВНЕШНИЙ КЛЮЧ ( Код_издания ИЗ Издания
                  NULL-значения НЕ ДОПУСТИМЫ
                  УДАЛЕНИЕ ИЗ Издания ОГРАНИЧИВАЕТСЯ
                  ОБНОВЛЕНИЕ Издания.Код_издания КАСКАДИРУЕТСЯ)
           ПОЛЯ ( Номер_переплета Целое, Код_издания Целое, Цена Деньги,
                  Дата_приобретения Дата )
    ОГРАНИЧЕНИЯ ( Значения поля Код_издания должны принадлежать набору
                  значений соответствующего поля таблицы Издания;
                  при нарушении вывод сообщения "Такого издания нет" );
СОЗДАТЬ ТАБЛИЦУ Аннотации *( Характеризует Издания )
 ПЕРВИЧНЫЙ КЛЮЧ ( Код_издания )
   ВНЕШНИЙ КЛЮЧ ( Код_издания ИЗ Издания
                  NULL-значения ДОПУСТИМЫ
                  УДАЛЕНИЕ ИЗ Издания ОГРАНИЧИВАЕТСЯ
                  ОБНОВЛЕНИЕ Издания.Код_издания КАСКАДИРУЕТСЯ)
           ПОЛЯ ( Код_издания Целое, Аннотация Запись )
    ОГРАНИЧЕНИЯ ( Значения поля Код_издания должны принадлежать набору
                  значений соответствующего поля таблицы Издания;
                  при нарушении вывод сообщения "Такого издания нет" );
СОЗДАТЬ ТАБЛИЦУ Авторы *( Связывает Создатели и Издания )
 ПЕРВИЧНЫЙ КЛЮЧ ( Код_создателя, Код_издания )
   ВНЕШНИЙ КЛЮЧ ( Код_создателя ИЗ Создатели
                  NULL-значения НЕ ДОПУСТИМЫ
                  УДАЛЕНИЕ ИЗ Создатели ОГРАНИЧИВАЕТСЯ
                  ОБНОВЛЕНИЕ Создатели.Код_создателя КАСКАДИРУЕТСЯ)
   ВНЕШНИЙ КЛЮЧ ( Код_издания ИЗ Издания
                  NULL-значения НЕ ДОПУСТИМЫ
                  УДАЛЕНИЕ ИЗ Издания ОГРАНИЧИВАЕТСЯ
                  ОБНОВЛЕНИЕ Издания.Код_издания КАСКАДИРУЕТСЯ)
           ПОЛЯ ( Код_создателя Целое, Код_издания Целое )
    ОГРАНИЧЕНИЯ ( Значения полей Код_создателя и Код_издания должны
                  принадлежать набору значений соответствующих полей
                  таблиц Создатели и Издание; при нарушении вывод
                  сообщения "Такого автора нет" или "Такого издания нет" );

Аналогичное содержание имеют описания таблиц Составители, Редакторы, Художники и Переиздания. Остальные же таблицы проектируемой базы данных описываются так:

СОЗДАТЬ ТАБЛИЦУ Переводчики *( Связывает Создатели, Издания и Языки)
 ПЕРВИЧНЫЙ КЛЮЧ ( Код_создателя, Код_издания )
   ВНЕШНИЙ КЛЮЧ ( Код_создателя ИЗ Создатели
                  NULL-значения НЕ ДОПУСТИМЫ
                  УДАЛЕНИЕ ИЗ Создатели ОГРАНИЧИВАЕТСЯ
                  ОБНОВЛЕНИЕ Создатели.Код_создателя КАСКАДИРУЕТСЯ)
   ВНЕШНИЙ КЛЮЧ ( Код_издания ИЗ Издания
                  NULL-значения НЕ ДОПУСТИМЫ
                  УДАЛЕНИЕ ИЗ Издания ОГРАНИЧИВАЕТСЯ
                  ОБНОВЛЕНИЕ Издания.Код_издания КАСКАДИРУЕТСЯ)
   ВНЕШНИЙ КЛЮЧ ( Код_языка ИЗ Языки
                  NULL-значения НЕ ДОПУСТИМЫ
                  УДАЛЕНИЕ ИЗ Языки ОГРАНИЧИВАЕТСЯ
                  ОБНОВЛЕНИЕ Языки.Код_языка КАСКАДИРУЕТСЯ)
           ПОЛЯ ( Код_создателя Целое, Код_издания Целое )
    ОГРАНИЧЕНИЯ ( Значения полей Код_создателя, Код_издания и
                  Код_языка должны принадлежать набору значений
                  соответствующих полей таблиц Создатели, Издание
                  и Языки; при нарушении вывод сообщения "Такого
                  автора нет" или "Такого издания нет" или "Такого
                  языка нет");
СОЗДАТЬ ТАБЛИЦУ Размещение *( Связывает Места и Переплеты )
 ПЕРВИЧНЫЙ КЛЮЧ ( Код_места, Номер_переплета )
   ВНЕШНИЙ КЛЮЧ ( Код_места ИЗ Места
                  NULL-значения НЕ ДОПУСТИМЫ
                  УДАЛЕНИЕ ИЗ Места ОГРАНИЧИВАЕТСЯ
                  ОБНОВЛЕНИЕ Места.Код_места КАСКАДИРУЕТСЯ)
   ВНЕШНИЙ КЛЮЧ ( Номер_переплета ИЗ Переплеты
                  NULL-значения НЕ ДОПУСТИМЫ
                  УДАЛЕНИЕ ИЗ Переплеты КАСКАДИРУЕТСЯ
                  ОБНОВЛЕНИЕ Переплеты.Ном_переплета КАСКАДИРУЕТСЯ)
           ПОЛЯ ( Код_места Целое, Номер_переплета Целое,
                  Дата_размещения Дата, Дата_изъятия Дата )
    ОГРАНИЧЕНИЯ ( Значения полей Код_места и Номер_переплета
                  должны принадлежать набору значений соответствующих
                  полей таблиц Переплеты и Места; при нарушении вывод
                  сообщения "Такого переплета нет" или "Такого места нет" );
СОЗДАТЬ ТАБЛИЦУ Выдача *( Связывает Читатели и Переплеты )
 ПЕРВИЧНЫЙ КЛЮЧ ( Ном_билета, Ном_переплета )
   ВНЕШНИЙ КЛЮЧ ( Ном_билета ИЗ Читатели
                  NULL-значения НЕ ДОПУСТИМЫ
                  УДАЛЕНИЕ ИЗ Читатели КАСКАДИРУЕТСЯ
                  ОБНОВЛЕНИЕ Читатели.Ном_билета КАСКАДИРУЕТСЯ)
   ВНЕШНИЙ КЛЮЧ ( Ном_переплета ИЗ Переплеты
                  NULL-значения НЕ ДОПУСТИМЫ
                  УДАЛЕНИЕ ИЗ Переплеты КАСКАДИРУЕТСЯ
                  ОБНОВЛЕНИЕ Переплеты.Ном_переплета КАСКАДИРУЕТСЯ)
           ПОЛЯ ( Ном_билета Целое, Ном_переплета Целое, Дата_выдачи Дата,
                  Срок Целое, Дата_возврата Дата )
    ОГРАНИЧЕНИЯ ( Значения полей Ном_билета и Ном_переплета должны
                  принадлежать набору значений соответствующих полей таблиц
                  Читатели и Переплеты; при нарушении вывод сообщения
                  "Такого читателя нет" или  "Такого переплета нет" );

       Теперь следует проверить, не нарушены ли в данном прокете какие-либо принципы нормализации (п.4.6), т.е. что любое неключевое поле каждой таблицы:
       — функционально зависит от полного первичного ключа, а не от его части (если ключ составной);
       — не имеет функциональной зависимости от другого неключевого поля.
       — Сущности Авторы, Составители, Редакторы, Художники и Переиздания, не имеющие неключевых полей, безусловно нормализованы. Нормализованы и сущности Создатели, Характеры, Заглавия, Вид_издания и Аннотации, состоящие из несоставного ключа и единственного неключевого поля.
       Анализ сущностей Переводчики, Размещение и Выдача, состоящих из составного ключа и неключевых полей, показал, что в них нет функциональных связей между неключевыми полями. Последние же не зависят функционально от какой-либо части составного ключа.
       Наконец, анализ сущностей Издания, Переплеты, Места, Читатели и Языки, показал, что единственной "подозрительной" сущностью является стержень Языки, имеющий два функционально связанных неключевых поля: Язык и Сокращение.
       Поле Язык стало неключевым из-за ввода цифрового первичного ключа Код_языка, заменяющего текстовый возможный ключ Язык. Это позволило уменьшить объем хранимых данных в таблице Переводчики, затраты труда на ввод множества текстовых значений и возможной противоречивости, которая часто возникает из-за ввода в разные поля ошибочных дубликатов (например, "Английский", "Англиский", "Анлийский", "Англйский" и т.п.). Если мы вспомним рекомендации п. 4.5 о замене на время нормализации цифровых заменителей первичных ключей (Код_языка) на исходный ключ (Язык) или воспользуемся формулировкой НФБК, то окажется, что таблица Языки – нормализована.
       Для завершения проекта необходимо было бы ввести в описания таблиц дополнительные сведения об ограничениях целостности (выше указан лишь минимальный их набор) и дать описание некоторых таблиц, но ограниченнный объем публикации не позволяет включать эти подробности, не являющиеся принципиальными для иллюстрации процедуры проектирования.

 

Перевод проекта в читабельный вид

       Использование искусственных языков, якобы для облегчения понимания процесса, начал еще А.П.Ершов со своим "райкиным" языком (РАЯ - русский алгоритмический язык). Но для описания БД лучше использовать стандартный язык SQL, оставив только русскими названия таблиц и полей.

Create table Создатели
      (Код_создат        Integer not null primary key,
       Фам_ИО            Char(30));
Create table Издательства
      (Код_издательства  Integer not null primary key,
       Название          Char(40)
       Город             Char(25));
Create table Заглавия
      (Код_заглавия      Integer not null primary key,
       Заглавие          Char(255)); -- Типа "Запись" не существует!!!!

 
Create table Вид_издания
      (Вид_издания       Integer not null primary key,
       Название_вида     Char(16));
Create table Характеры
      (Код_характера     Integer not null primary key,
       Характер_переиздания   Char(16));
Create table Языки
      (Код_языка         Integer not null primary key,
       Язык              Char(16),
       Сокращение        Char(6));
Create table Места
      (Код_места         Integer not null primary key,
       Номер_комнаты     Integer,
       Номер_стелажа     Integer,
       Номер_полки       Integer);
Create table Читатели
      (Ном_билета        Integer not null primary key,
       Фамилия           Char(20),
       Имя               Char(16),
       Отчество          Char(20),
       Адрес             Char(60),
       Телефон           Chat(9));
Create table Издание
      (Код_издания       Integer not null primary key,
       Код_заглавия      Integer not null references Заглавия on update cascade,
       Вид_издания       Char(16) not null references Вид_издания on update cascade,
       Номер_тома        Interger,
       Авторский_знак    Char(3),
       Библиотечн_шифр   Char(12),
       Повторность       Integer,
       Код_издательства  Integer not null references Издательства on update cascade,
       Год_издания       Integer);
Create table Переплеты
      (Номер_переплета   Integer not null primary key,
       Код_издания       Integer not null references Издания on update cascade,
       Цена              Money,
       Дата_приобретения Date);
Create table Аннотации
      (Код_издания       Integer not null references Издания on update cascade,
       Аннотация         Char(255),
Primary key (Код_издания));
Create table Авторы
      (Код_создателя     Integer not null references Создатели on update cascade,
       Код_издания       Integer not null references Издания on update cascade,
Primaty key(Код_создателя,Код_издания));
Create table Переводчики
      (Код_создателя     Integer not null references Создатели on update cascade,
       Код_издания       Integer not null references Издания on update cascade,
Primaty key(Код_создателя,Код_издания));
Create table Размещение
      (Код_места         Integer not null references Места on update cascade,
       Номер_переплета   Integer not null references Переплеты on update cascade,
       Дата_размещения   Date,
       Дата_изъятия      Date,
Primary key(Код_места,Номер_переплета));
Create table Выдача
      (Ном_билета        Integer not null references Читатели on update cascade,
       Ном_переплета     Integer not null references Переплеты on update cascade,
       Дата_выдачи       Date,
       Срок              Integer,
       Дата_возврата     Date,
Primary Key(Ном_билета,Ном_переплета));

       Первое, что бросилось в глаза — наличие ошибок в описании. Они выделены касным шрифтом. Если бы профессор Кирилов В.В. описывал БД в виде SQL-скрипта, то он мог был проверить его на ошибки простым способом — создать из него БД. И тогда ошибки типа неправильное наименование таблиц и не соответствующие типы данных в таблице "Издание" вызвали бы прерывание и отразились в протоколе.

       Урок. Описывайте БД на стандартном языке, который поддерживается реальной СУБД.

Анализ предметной области

       "... проект базы данных надо начинать с анализа предметной области..." так пишет професор Кириллов В.В. в параграфе 1.3 этого же учебного пособия. Что же анализирует профессор на самом деле?
       Карточку, взятую в институтской библиотеке!!!
       В начале он взял и переписал поля в "аннотированной каталожной карточке", тем самым создал плоскую таблицу, добавил к ним "...атрибуты, позволяющие охарактеризовать отдельные экземпляры изданий (переплеты), места их хранения и читателей". После чего применил к полученным полям таблицы правила нормализации и получил некоторый набор таблиц и связей. И объявил это БД и сказал "да будет так!".
       А как все должно быть на самом деле?
       Во-первых, нужно отвлечься от самой карточки, и перейти к реальному миру.
       Без объяснения причин профессор Кириллов В.В. объявил сущность "Создатели" стержневой и сказал, что в нее входят не только авторы, но и другие "люди принимающие участие в подготовке рукописи издания". А читатели уже не люди? По логике профессора Кириллова В.В. есть писатели, и есть читатели — это разные сущности. И писатель никогда не ходит в библиотеки и не читает книги? А что, если автор к тому же является работником библиотеки?
       Таким образом ключевой объект — Персона (человек). Все остальное — свойства объекта "Персона". Давайте их перечислим некоторые из них:
       — Фамилия,
       — Имя,
       — Отчество,
       — пол,
       — рост,
       — образование,
       — национальность,
       — читатель,
       — писатель,
       — переводчик,
       — и т.д.
       Часть из этих свойств имеет отношение к рассматриваемой проблеме, часть нет. Часть свойств позволяет идентифицировать человека, часть нет. Признак "читатель" не является идентифицирующим. Признак "Автор" также не может идентифицировать человека, особенно если он записан так как это обычно делают на книгах и каталожных карточках. В качестве примера возьмем справочник:
       Русская литература XX века. Прозаики, поэты, драматурги: био-библ.словарь: в 3т./под ред. Н.Н.Скатова. — М.: ОЛМА-ПРЕСС Инвест, 2005.
       Иванов Геннадий Викторович (14.03.1950г) - поэт (т.2 стр.82);
       Иванов Георгий Владимирович (29.10.1894-26.08.1958г) - поэт, мемуарист, прозаик, критик (т.2, стр.85);
       В каталожной карточке и на обложке книги (и кстати в "списке статей" стр.818, т.3 этого же издания) оба эти автора будут записаны как — "Иванов Г.В.".
       Таким образом простейшая проверка показала, что в разработанной профессором Кирилловым В.В. базе данных найти автора невозможно! Можно найти издание, у которого в качестве автора записаны некоторые слова. А это не одно и то же. Отдельные слова даже с буковками НЕ ИДЕНТИФИЦИРУЮТ объект.
       Для читателя также невозможна идентификация. Допустим, что библиотека находится в Москве, и посмотрим сколько людей носят одинаковые ФИО?

Иванов Александр Николаевич 533
Иванов Александр Владимирович 500
Иванов Александр Сергеевич 467
Иванов Владимир Николаевич 413
Кузнецов Александр Николаевич 413
Иванова Татьяна Николаевна 392
Иванов Сергей Александрович 389
Иванов Александр Александрович 388
Смирнов Александр Николаевич 381
Иванов Александр Иванович 377
Иванова Валентина Ивановна 377
Иванова Елена Владимировна 373
Иванов Владимир Иванович 370
Кузнецов Александр Сергеевич 369
Кузнецов Сергей Александрович 366
Иванов Сергей Владимирович 365
Кузнецов Владимир Иванович 365
Кузнецов Владимир Николаевич 359
Кузнецов Александр Иванович 358

       Красноречивые данные? Наверно поэтому профессор Кириллов В.В. не стал указывать уникальный индекс по этим полям. Он, и многие другие считают, что достаточно иметь номер читательского билета в качестве идентифицирующего признака. Но, это позволяет многократно записываться в библиотеку, получать несколько разных читательских билетов и воровать книги безбоязненно. А девочка, которая записывает читателя в библиотеку разве не ошибается?
       Для идентицикации человека требуется — Фамилия, Имя, Отчество, дата рождения. Если область применения расширяется как географически, так и во времени, то возможно потребуется добавить и место рождения.
       Профессор Кириллов В.В. пишет "— Сущности Авторы, Составители, Редакторы, Художники и Переиздания, не имеющие неключевых полей, безусловно нормализованы." На самом деле это не так. Сущности имеют ключевое поле, которое никак не связано с содержательным полем, а следовательно можно ввести множество строк с разными значениями ключевого поля и одинаковым значением поля "Автор" ("Составитель" и т.д.). Ценности такие таблицы не представляют.

Итак:
       В предложенной базе данных невозможно однозначно найти ни автора (переводчика, художника и прочих создателей), ни читателя. Так как сущности "читатель" и "писатель" различаются, то невозможно получить статистику "сколько читателей читало определенную книгу, не считая ее писателя". Т.е. с этой точки зрения база данных "Библиотека" не работоспособна.

       Но может быть больше повезет с объектом "Издания"?
       Рассуждения о библиотечном шифре бессмысленны, до тех пор пока не определен объект учета. Таких объектов на самом деле три — произведение, издание (как товар), экземпляр издания.
       Произведение — это то, что создал автор (или группа авторов). На него ставится код УДК и/или ББК (а возможно и других систем классификации). Его прежде всего ищет читатель.
       Издание — это вид товара, который продается в магазине и имеет определенную стоимость. Издание может содержать одно произведение одного автора или много произведений многих групп авторов. Издание может быть издано ГРУППОЙ издательств, каждое из которых имеет свой код ISBN.
       Экземпляр издания — конкретный объект учета в библиотеке, который имеет инвентарный номер.
       Так как профессор Кириллов В.В. не анализировал реальный мир, то он упустил, что читатель ищет не издание, а произведение конкретного автора. Таким образом, найти например это учебное пособие будет невозможно, если оно издано в сборнике "Все материалы ВУЗов".
       Следовательно, требуется отдельная сущность "Произведение" со своей идентификацией, классификацией и свойствами.
       Сущность "Издание" описывается также как товар, имеет такую же идентификацию, классификацию и свойства. Она связана с сущностью "Произведение" отношением многие-к-многим.
       И, наконец, объект "Экземпляр" связан с сущностью "Издание" и имеет инвентарный номер.

Итак:
       С точки зрения поиска произведения конкретного автора предложенная база данных "Библиотека" неработоспособна. Она также не полно описывает объекты в библиотеке.

       "... Наконец, анализ сущностей Издания, Переплеты, Места, Читатели и Языки, показал, что единственной "подозрительной" сущностью является стержень Языки, имеющий два функционально связанных неключевых поля: Язык и Сокращение.
       Поле Язык стало неключевым из-за ввода цифрового первичного ключа Код_языка, заменяющего текстовый возможный ключ Язык. Это позволило уменьшить объем хранимых данных в таблице Переводчики, затраты труда на ввод множества текстовых значений и возможной противоречивости, которая часто возникает из-за ввода в разные поля ошибочных дубликатов (например, "Английский", "Англиский", "Анлийский", "Англйский" и т.п.). Если мы вспомним рекомендации п. 4.5 о замене на время нормализации цифровых заменителей первичных ключей (Код_языка) на исходный ключ (Язык) или воспользуемся формулировкой НФБК, то окажется, что таблица Языки — нормализована.
"
       В этом абзаце два момента, которые стоит отметить:
       1) Рассуждения о том что "поле стало неключевым" больше относится ко всем остальным сущностям — Издания, Читатели, Авторы — так как у них возникает "... возможная противоречивость, которая часто возникает из-за ввода в разные поля ошибочных дубликатов". Как пример можно привести БД "ГИБДД 2002г", в которой слово "Александр" записано 153-мя способами. Но для этих полей профессор Кириллов В.В. даже не определяет уникальность текстовых полей.
       2) Именно к "Языку" эти рассуждения никак не относятся, так как существуют международные 2-х и 3-х символьные коды языков, стран, валют, и в данном случае правильней использовать естественный ключ с двухсимвольным кодом, например, "ru", "en", "fr" и другие.

       "База данных предназначена для хранения данных о приобретенных библиотекой изданиях (монографиях, справочниках, сборниках статей и т.п.), информации о местонахождении отдельных экземпляров (переплетов) каждого издания и сведений о читателях." С этого начиналась глава о базе данных "Библиотека". Эти общие слова позволяют сказать — профессор Кириллов В.В. ничего не знает о назначении базы данных "Библиотека".
       "Информация о местонахождении" ничего не говорит о том, почему экземпляр издания оказался там или здесь.
       "Сведения о читателях" — несут личную информацию, которую нельзя собирать в соответствии со ст.24 Конституции РФ.
       "...хранения данных о приобретенных библиотекой изданиях" — бессмысленно, так как эта информация есть у издательств.
       Если бы профессор Кириллов В.В. сходил бы в библиотеку и поговорил бы с ее работниками, то он узнал бы что база данных "Библиотека" нужна:
       — для УЧЕТА приобретенных изданий,
       — для поиска необходимых изданий и/или произведений,
       — для статистических исследований использования фондов,
       — для научных исследований.
       А раз требуется учет, то можно вспомнить, что в библиотеке уже есть (или должна быть) одна учетная система — бухгалтерия. Именно она учитывает, какие издания когда и по какой цене закуплены. В ней учитываются взаимоотношения с читателями, в случае порчи изданий или оказании дополнительных услуг. Объект "Издание" уже учитывается в бухгалтерии как "Товар" при его покупке. Часть читателей уже учитываются в бухгалтерии как работники библиотеки. Так почему бы там же не учитывать и остальных читателей. В бухгалтерии уже есть "система безопасности", которая защищает финансовые данные. Эта же система может защитить и личные данные читателей.
       Для поиска изданий служат многочисленные системы классификации — ББК, УДК и др., представление которых в БД само по себе представляют проблему. Например, УДК является многомерной и кроме самой классификации имеет систему ключевых слов для обратного поиска.

Резюме

       Предложенная база данных "Библиотека" не выполняет реальных функций, требуемых в библиотеке.
       В параграфе 4.3 "Почему проект БД может быть плохим?" профессор Кириллов В.В. описывает различные причины, по которым проект БД может быть плохим — Избыточность, Потенциальная противоречивость (аномалия обновления), Аномалия включения, Аномалия удаления. Конечно, указанные причины каким-то образом влияют на качество проекта. В таком случае можно определить правило, по которому проект БД является непригодным для использования:

Для проекта в целом и для каждого объекта должна быть определена область применимости (видимости) реального мира.
       В данном случае область применимости не определена. Т.е. не указано, что БД должна работать в Москве, Санкт-Петербурге, России или во всем мире. Не определено какое количество читателей может пользоваться библиотекой. Не определено какое количество книг и какой тематики может учитываться в БД. Если будет учитываться 10 книг, то проверить что они отличаются друг от друга легко. Если учитывается 10 млн. книг, то отличить книгу одного "Иванова Г.В." от другого "Иванова Г.В." уже невозможно.

Каждый объект (именно объект, а не его идентификатор) должен быть уникально определен (идентифицирован) в области применимости реального мира.
       Так как область применимости неопределена, то и выбрать способ идентификации или проверить, что выбранный способ идентификации работает, невозможно. Более того, в проекте не делается различий между идентификатором строки и идентификатором объекта. Почему то профессор Кириллов В.В. считает, что если строка таблицы имеет идентификатор, то сам экземпляр объекта идентифицировать не нужно. Ни в одной таблице не указано какой набор свойств (полей) однозначно идентифицирует экземпляр объекта. Например, таблица "Места" позволяет ввести "Номер_комнаты, Номер_стелажа, Номер_Полки" ввести несколько раз. Тогда одна и та же полка будет иметь несколько разных значений поля "Код_места", что введет путаницу для оператора. Часть книг будет приписана к одному месту, часть к другому.
       До тех пор, пока не выполняются эти два правила, БД таковой не является. Это то, что сейчас модно называть "Хранилищем данных". Т.е. данные хранятся, что-то можно извлечь из хранилища, но убедиться в правильности и достоверности данных невозможно.
       Это первый пример, когда на базе абсолютно верных математических методов, разработана абсолютно неработающая БД. Правда, ни пользователи, ни заказчики об этом не догадываются и еще долго будут оставаться в неведении.

(c) 17.07.2008г Архангельский Андрей





Дата последнего изменения:
Thursday, 21-Aug-2014 09:10:56 MSK


Постоянный адрес статьи:
http://az-design.ru/Projects/AzBook/Review/LITMO.shtml