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

БД "Библиотека" из учебника В.В.Кириллова (ЛИТМО)
(вторая серия)

       Прошло время и профессор Кириллов В.В. выпустил в издательстве "БХВ-Петербург" учебник "Введение в реляционные базы данных", [Kirillov_2008] который в основном построен на предыдущем учебнике. Учебник подписан в печать 01.09.2008г. Следовательно, можно допустить что профессор Кириллов В.В. ознакомился в предыдущим анализом, тем более что некоторые особо грубые ошибки, например, то что читатель и писатель может быть одно и то же лицо, были исправлены. Однако, база данных "Библиотека" так и не стала работоспособной. И, несмотря на то, что в учебнике достаточно глупостей, остановимся только на базе данных "Библиотека", которая описана в главе 12 (стр.224-238). Более того, для начала проанализируем только одну таблицу "ЛЮДИ", не отвлекаясь на остальные аспекты этой базы данных.
       Итак, повторим здесь описание таблицы "ЛЮДИ" так, как оно приведено в учебнике.

Листинг 12.1 Люди
-- Предложение для создания таблицы
CREATE TABLE ЛЮДИ (
    ИД               NUMBER (6,0) NOT NULL CONSTRAINT "ЛЮДИ_РК" PRIMARY KEY,
    ФАМИЛИЯ          NVARCHAR2(50) NOT NULL,
    ИМЯ              NVARCHAR2(50) NOT NULL,
    ОТЧЕСТВО         NVARCHAR2(50) NOT NULL,
    ПСЕВДОНИМ        NVARCHAR2(50),
    ДАТА_РОЖДЕНИЯ    DATE NOT NULL,
    ПОЛ              NCHAR(l) NOT NULL CONSTRAINT "Пол может быть М или Ж"
                     CHECK (ПОЛ IN ('М','Ж')),
    АДРЕС            NVARCHAR2(200),
    ТЕЛЕФОН          NVARCHAR2(50),
    CONSTRAINT "ЛЮДИ_UK" UNIQUE (ФАМИЛИЯ, ИМЯ, ОТЧЕСТВО, ДАТА_РОЖДЕНИЯ, ПОЛ));
-- Комментарии для таблицы и ее столбцов
COMMENT ON TABLE ЛЮДИ IS 'Список читателей и/или создателей изданий';
COMMENT ON COLUMN ЛЮДИ.ИД IS 'Уникальный номер человека';
COMMENT ON COLUMN ЛЮДИ.ФАМИЛИЯ IS 'Фамилия человека';
COMMENT ON COLUMN ЛЮДИ.ИМЯ IS 'Имя человека';
COMMENT ON COLUMN ЛЮДИ.ОТЧЕСТВО IS 'Отчество человека';
COMMENT ON COLUMN ЛЮДИ.ПСЕВДОНИМ IS 'Псевдоним человека';
COMMENT ON COLUMN ЛЮДИ.ДАТА_РОЖДЕНИЯ IS 'Дата рождения человека';
COMMENT ON COLUMN ЛЮДИ.ПОЛ IS 'Пол человека';
COMMENT ON COLUMN ЛЮДИ.АДРЕС IS 'Адрес человека';
COMMENT ON COLUMN ЛЮДИ.ТЕЛЕФОН IS 'Телефон человека';
-- Создание генератора уникальной последовательности значений, которые
-- будут использоваться в триггере ЛЮДИ_BIR для выработки значений
-- первичного ключа таблицы Люди
CREATE SEQUENCE ЛЮДИ_ПОСЛ INCREMENT BY 1 START WITH 1;
Создание триггера для выработки значений первичного ключа таблицы,
преобразования с помощью функции InitCap первых букв фамилии, имени и
отчества в прописные, а также ввода в столбец ДАТА_РОЖДЕНИЯ даты
11.11.1111, если при вводе в него не вводилось никакого значения
CREATE OR REPLACE TRIGGER ЛЮДИ_BIR
    BEFORE INSERT ON люди
    FOR EACH ROW
BEGIN
  SELECT ЛЮДИ_ПOCЛ.NEXTVAL INTO :new.ид FROM dual;
  :new.фамилия := InitCap(:new.фамилия);
  :new.имя := InitCap(:new.имя);
  :new.отчество := InitCap(:new.отчество);
IF :new.дата_рождения IS NULL THEN
   :new.дaтa_poждeния := to_date('11.11.1111','DD.MM.YYYY'); END IF;
END люди_bir;
 /

       Анализ будем делать по отдельным пунктам в порядке повышения важности проблемы.

Основные проблемы

TRIGGER ЛЮДИ_BIR
       Итак, первое что вызывает удивление, это обязательное изменение первого символа Фамилии, Имени, Отчества на прописные. На чём основано такое правило? Во-первых, автор почему то подумал, что если у него фамилия Кириллов, то и в остальных случаях фамилии будут подчиняться таким же правилам. Вроде бы такое правило защитит от ошибок оператора. Во-вторых, автор не сделал то, что необходимо делать в начале ЛЮБОГО проектирования — определение области применимости проекта.
       Если бы это была система кадрового учета на очень маленьком предприятии, на котором работают только люди с русскими фамилиями, то возможно это правило имело бы смысл. Хотя и это не так. Но в библиотеке присутствуют книги любых стран. Следовательно, Фамилии (имена, Отчества) будут подчиняться не только правилам русского языка, но и правилам других языков. Например, триггер совершенно неправильно изменит д'Артаньян на Д'артаньян. Более того, даже в русском языке триггер будет вносить ошибки, например, в случае двойных фамилий. Так фамилия Голенищев-Кутузов превратится Голенищев-кутузов. А это неправильно.
       Таким образом, это правило "высосано из пальца", ничем не обосновано и приводит к ошибкам в данных даже при том, что оператор введет их правильно. Автор не сделал элементарного анализа предметной области. В любом случае правило изменяющее входные данные должно быть объяснено не только в документации на базу данных, но и в руководстве пользователя. И уж тем более должно быть расжевано в учебнике.

       Второе правило! В случае если дата рождения человека неизвестна, то в таблицу вводится произвольно выбранная дата. Это правило нельзя объяснить здравым смыслом. Это похоже на действия "блондинки", которая когда не знает что делать, делает хоть чего-нибудь.
       Опять вспоминаем, что назначение базы данных "Библиотека" хранение данных о книгах разных времен. Следовательно, в ней могут быть книги любых авторов от Аристотеля (384 г. до н.э) до Кирилов В.В. (сегодняшние дни). Выбор любой даты в пределах этого диапазона в качестве неизвестной будет приводить к искажениям. Подобный эффект можно наблюдать в БД "Прописка Москвы и МО". Так как первые варианты БД были написаны с помощью программы FoxPro, то в случае неизвестной даты рождения вводился "0". Но при экспорте данных в другую программу эта дата заменялась на 01.01.1900г и, как результат, для многих людей дата рождения становилась неопределенной — либо он действительно родился 01.01.1900г (что вполне могло быть), либо это отсутствующая (неизвестная) дата.
       А если бы профессор Кириллов В.В. хотя бы на минуту задумался о тестировании базы данных, то он взял бы свою книгу и попробовал ввести ее данные в свою базу данных. Тогда бы он увидел, что в подавляющем большинстве книг не то что дата рождения не указывается, но и Имя/Отчество не указывается. Даже в книге приведенной в качестве примера в начале главы для автора указаны только инициалы. И, как результат, в качестве даты рождения почти у всех авторов будет указана неправильная дата (11.11.1111г), что равносильно отсутствию поля как такового. Но тогда идентифицировать человека практически невозможно. Например, для Москвы людей с одинаковыми Фамилией, Именем и Отчеством достигает 530 человек, в зависимости от распространенности фамилии.
       На самом деле в данном случае проблема заключается в том, что не все СУБД позволяют иметь в уникальном ключе значения NULL. Так, например, в очень близких по структуре СУБД — Firebird и Interbase — в первой значения NULL допускаются, а во второй нет. А так как предполагается, что книга является учебником по реляционным базам данных, а не рекламный буклет по СУБД Oracle, то эта проблема должна быть обсуждена весьма подробным образом, включая и такие случаи. Также нужно обсудить само значение NULL, так как разные СУБД его понимают по разному.

CONSTRAINT "ЛЮДИ_UK" UNIQUE(ФАМИЛИЯ, ИМЯ, ОТЧЕСТВО, ДАТА_РОЖДЕНИЯ, ПОЛ)
       С одной стороны здесь все правильно — теоретически. Есть несколько полей, сочетание значений которых должно быть уникальным. Ничего удивительного. НО!
       Во-первых, автор должен был в рамках проектирования представить себе кто и как будет вводить данные в таблицу. А это, как правило, "блондинки", которых взяли на работу оператора только потому, что на другое они не способны. Если бы у них было хоть какое-то образование, то они бы делали более полезную работу.
       Во-вторых, автор, также в рамках проектирования, должен был проанализировать какие данные вводятся в таблицу. Почему в стране существует Институт Русского Языка, почему в стране (и в мире) существует так много специалистов-лингвистов. Да просто потому что в русском языке (и не только) далеко не все однозначно. Даже очень грамотный человек встречается с трудностями. Одна только буква Ё доставляет столько хлопот, что ей нужно посвящать отдельную главу в руководстве.
       Но так как этого сделано не было, то сделаем простое тестирование этой базы данных. База данных "ГИБДД Москвы 2002г." построена точно по такому же принципу. В результате фамилия "Филиппов" записана 11 способами, имя "Александр" записано 153 способами, отчество "Владимирович" записано 117 способами. Таким образом если сотне операторов поручить ввести данные о "Филиппове Александре Владимировиче", то по статистике мы получим 196911 различных записей об ОДНОМ И ТОМ ЖЕ человеке. И никакой уникальный ключ этому не помешает!!!
       Единственный случай, когда на текстовое поле можно ставить уникальный ключ — это использование таблицы как справочника. При этом заполнение таблицы осуществляется специально обученным человеком, которого можно назвать редактором, специалистом в данной предметной области. На таблицу должны быть наложены права доступа, ограничивающие изменение таблицы другими пользователями. И не грех, добавить в систему средства по поиску ошибок в справочнике в помощь редактору.
       В-третьих, включение поля "ПОЛ" в уникальный индекс мало что дает с точки зрения защиты от ошибок пользователя. Вообще, использование поля "ПОЛ" только в таблице "ЛЮДИ" никак не помешает ввести, например, следующую запись:
       Иванов Анастасия Георгиевич, М
       Такого типа записи во множестве присутствуют в базе данных "Прописка Москва и МО 2005г"
       Кроме того, есть правильные записи, которые однозначно вызывают трудности. Например, кавалер ордена Славы 3-х степеней Караев Анна [02.02.1914-24.07.1975], с очень большой вероятностью будет записан как женщина. Несмотря на то, что это мужчина.
       Таким образом, это решение взято "с потолка" и никак не подвергалось анализу.

поля "Фамилия", "Имя", Отчество"
       Автор посмотрел на себя в зеркало и решил: "Если у меня фамилия, имя, отчество — Кириллов Владимир Васильевич, то и у других они строятся подобным образом". Очередной чудовищный пример решения, которое "взято с потолка" и полного отсутствия анализа и тестирования. Итак, первый этап тестирования:
       Айтаков Недирбай [__.__.1894-28.10.1938] — С января 1924г. председатель Туркестанского ЦИК
       Акаев Аскар [10.11.1944] — Президент Республики Кыргызстан
       Ахмедов Хан [16.06.1936] — С августа 1992г. Чрезвычайный и Полномочный Посол Туркменистана в Турции
       Исанов Насирдин [07.11.1943-29.11.1991] — С 1983г. министр строительства Киргизской ССР
       Караманов Узакбай [20.08.1937] — С ноября 1990г. Премьер-министр Кабинета Министров Казахской ССР
       Кахаров Абдулахад [17.04.1913-12.02.1984] — С апреля 1961г. Председатель Совета Министров Таджикской ССР
       Лутфулаев Нусратулло [01.07.1881-31.10.1937] — С сентября 1929г. председатель ЦИК Таджикской ССР
       Максум Нусратулла [01.07.1881-31.10.1937] — С сентября 1929г. председатель ЦИК Таджикской ССР
       Овезов Балыш [29.12.1915-__.10.1975] — В июне 1960 - январе 1970гг. первый секретарь ЦК КП Туркменистана
       Суеркулов Абды [25.12.1912] — С февраля 1959г. министр торговли Киргизской ССР
       Хаеев Изатулло [22.06.1936] — В июне 1991 - январе 1992гг. Премьер-министр Республики Таджикистан
       Ходжамурадов Аннамурад [11.07.1935] — С января 1986г. Председатель Совета Министров Туркменской ССР
       Шаяхметов Жумабай [30.08.1902-17.10.1966] — В марте 1954 - январе 1955гг. - первый секретарь Южно-Казахстанского обкома партии
       Язкулиев Баллы [02.01.1930] — С декабря 1978г. Председатель Президиума Верховного Совета Туркменской ССР
       Это примеры только из одного справочника "Государственная власть СССР 1923-1991гг". Всех этих людей нельзя ввести в базу данных только потому, что у них нет отчества, а значения NULL в уникальном ключе (в данном случае) не допускаются. Это та же проблема, что и с днем рождения, которую профессор Кириллов В.В. решил с помощью "страусинной позиции". И что должна при этом делать "блондинка"-оператор неизвестно.

Второй этап тестирования:
       Алиев Гейдар Али Рза оглы [10.05.1923-12.12.2003] — С октября 1993г. Президент Азербайджанской Республики
       Гасанов Гасан Азиз оглы [20.10.1940] — В феврале 1991 - апреле 1992гг. Премьер-министр Азербайджанской Республики
       Ибрагимов Али Измаил оглы [01.10.1913] — С апреля 1970г. Председатель Совета Министров Азербайджанской ССР
       Искендеров Мамед Абдул оглы [17.12.1915-28.05.1985] — С декабря 1961г. Председатель Президиума Верховного Совета Азербайджанской ССР
       Мусабеков Газанфар Махмуд оглы [26.07.1888-09.02.1938] — В 1929-1931гг. председатель ЦИК Азербайджанской ССР
       Муталибов Аяз Ниязи оглы [12.05.1938] — С мая 1992г. Президент Азербайджанской Республики
       Нариманов Нариман Кербалай Наджаф оглы [14.04.1870-19.03.1925] — С апреля 1920г. председатель Азербайджанского ревкома
       Сеидов Гасан Неймат оглы [16.08.1932] — С января 1981г. Председатель Совета Министров Азербайджанской ССР
       Это примеры из того же справочника. Этих людей нельзя ввести только потому, что количество имен у них больше предложенного количества полей. И это только люди занимавшие значительные посты в государственной власти. А в библиотеке могут быть книги не только авторов из СССР, но и из любой страны. Как там строятся имена и фамилии — одному богу известно. А кто объяснит это "блондинке"-оператору?
       Третий этап тестирования:
       Для полей ничего не сказано о наборе символов, какая кодировка используется? Для библиотеки с ее чрезвычайно широким языковым диапазоном, этот вопрос не праздный. С одной стороны в русском языке есть множество фамилий, которые при изменении рода начинают совпадать с другой правильной фамилией. Например:
       Мужская фамилия - Малин, женская фамилия - Малина — склоняется
       Мужская фамилия - Малина, женская фамилия - Малина — не склоняется.
       Что приводит к путанице.
       Множество иностранных имен и фамилий в оригинале пишутся по разному, а на русском языке — одинаково. Эта проблема, которая требует отдельного исследования, и, по крайне мере, должна быть упомянута в учебнике.
       Таким образом, и по этой причине база данных "не работает". Как выходить из этой ситуации? Исследования, Анализ, Проектирование и Тестирование — вот что должно быть сделано прежде чем публиковать базу данных в учебнике.

поле "Псевдоним"
       1) Глупый вопрос — "А почему размер поля "Псевдоним" равен размеру поля "Фамилия"?"
       2) Более серьезный вопрос — "А что такое псевдоним?"
       Например:
       Челыдов Михаил Александрович [01.04.1890-02.02.1973] — доктор юридических наук, профессор.
       Челыдов-Бебутов Михаил Александрович [01.04.1890-02.02.1973] — доктор юридических наук, профессор.
       Чельцов Михаил Александрович [01.04.1890-02.02.1973] — доктор юридических наук, профессор.
       Чельцов-Бебутов Михаил Александрович [01.04.1890-02.02.1973] — доктор юридических наук, профессор.
       Это один и тот же человек, но в документах у него указано 4 варианта фамилии.
       А сколько псевдонимов у знаменитой Амалии&Амалии — ну любит девушка выходить замуж и менять фамилию.
       А прибалтийские женские фамилии, которые изменяются в случае выхода женщины замуж.
       А переводные книги, где каждый переводчик пишет фамилию автора так как ему нравится.
       Таким образом, отдельное маленькое поле "Псевдоним" типичный пример халтуры. Вроде как слышали что-то про псевдоним, но разбираться с этим не хочется. Кинем поле в таблицу, а там будь что будет. На самом деле, псевдоним это еще один идентификатор человека, такой же как и обычные фамилия, имя, отчество. Следовательно, в таблице необходимо построить древовидную структуру по псевдонимам. И даже в этом случае возникает куча проблем. Например, что делать с порядком появления псевдонимов — это тоже полезная информация. Т.е. это проблема, которую необходимо обсудить в учебнике, показать возможные пути решения.

 

Прочие проблемы

       Кроме того в таблице есть множество мелких проблем, которые не влияют на общую работоспособность базы данных, но при этом должны быть объяснены в документации и, тем более, в учебнике.

поле ИД NUMBER (6,0)
       Вообще-то поле "ИД" это суррогатный ключ, который должен иметь простой тип. Самый простой тип — Integer. Использование в этом случае типа Numeric(6,0) даже с нулевым количеством разрядов мантисы оставляет число в формате с плавающей запятой. А работа с такими числами как минимум в три раза медленнее, чем с целыми числами.

поле "АДРЕС NVARCHAR2(200)"
       Во-первых, здесь применимо все что сказано выше о текстовых полях. Либо это справочное поле, по которому не производится поиск (что довольно странно), либо оно бесполезно, так как данные в нем вряд ли будут достоверными.
       Во-вторых, все что в учебнике сказано про нормализацию в данном случае просто забыто, как будто профессор не слышал об этом. Адрес — это самостоятельный очень сложный объет, который должен быть спроекторован отдельно. И таблица будет нормализована, и эффективность повысится, и, при правильном проектировании, достоверность данных будет гарантирована.

поле "ПОЛ NCHAR(1) NOT NULL CONSTRAINT CHECK (ПОЛ IN ('М','Ж'))
       Во-первых, использование для пола текстового поля — это признак дилентантизма. Пол ведь может указываться не только как "М" и "Ж", но и "M" и "F". Или другим способом, если потребуется перевести интерфейс на другой язык. Сравнение текстовых данных происходит много медленнее чем числовых. Поэтому правильным будет использование здесь целого числа со значениями 1 и 2. что делает это поле независимым от языка пользователя.
       Во-вторых, в международных стандартах ISO пол кодируется следующим образом:
       Sex as Integer default 0 check (value in (0,1,2,9));
       0 – неизвестный, 1 – Мужской, 2 – Женский, 9 – неопределен;

Комментарии к полям
       Комментарии показывают, что создание базы данных происходило с помощью визуальных инструментов, и никакой другой документации к ней не создавалось. А это означает, что автор проектированием никогда не занимался. Комментарий, расположенный в самой базе данных, можно посмотреть только запустив базу данных на сервере и сделав запрос к ней с помощью какого-либо инструмента. В других случаях он бесполезен. А как быть если необходимо получить мнение специалистов, у которых нет соответствующих инструментов? Если бы была документация, то достаточно предоставить ее специалистам. Лучшей документацией для базы данных является SQL-скрипт для ее создания. А в SQL-скрипте можно писать комментарии не внедряя их в саму базу данных.

Резюме

       1. Метод тестирования, которое было проведено выше Роберт Гласс называет "Проверка за столом" или "Инспекция за столом" (впервые описанный им в книге "Руководство по надежному программированию" [Glass_1982]. Через 30 лет в книге "Факты и заблуждения профессионального программирования" [Glass_2007] в фактах 21, 36 Роберт Гласс пишет, что этот метод тестирования самый мощный и доступный. Правда предварительно мной были выполнены довольно значительные исследования по реальным именам и фамилиям. Но кто мешал провести такие же исследования профессору Кириллову В.В., тем более что и возможностей у него в разы больше.
       2. Все ошибки, которые показаны в вышеприведенном анализе, являются ошибками проектирования. Но проектирования не было. Любое проектирование начинается с исследования проектной ситуации и определения требований. Джонс в книге "Методы проектирования" [Jones_1986] (глава 9. Методы исследования проектных ситуаций) описывает следующий план действий:
       1) Охарактеризовать ситуацию функционирования объекта.
       2) Определить характерные для ситуации условия, которым должен отвечать объект, чтобы он был принят заказчиком.
       3) Обеспечить, чтобы условия, характеризующие главные задачи, были совместимы как друг с другом, так и с информацией, используемой в процессе проектирования.
       Результатом этого процесса является техническое задание и исходные требования к продукту. Т.е. это самый первый этап проектирования. Ничего этого не было сделано. И как пишет Роберт Гласс [Glass_2007] "Факт 25. Требования, которых нет, — это такая ошибка, исправить которую труднее всего." Оба автора читают курс "Проектирование баз данных". В учебнике есть часть IV "Основы проектирования баз данных", иллюстрацией к которой и является анализируемая база данных "Библиотека". И если при анализе видно, что никакого проектирования не было, то возникает сомнение что курсы "проектирование..." действительно обучают проектированию.
       3. Так как не было проектирования, то и о тестировании базы данных не могло быть и речи. О нем просто не задумывались. Невозможно проверить требования, которых нет. Это и привело к тому, что в учебнике была опубликована НЕРАБОТАЮЩАЯ база данных. Если бы авторы действительно занимались проектированием, то они бы знали, что проект — это предположение, о том насколько правильно база данных отражает реальную предметную область. Тестирование доказывает или опровергает это предположение.
       4. По описанной методике построено подавляющее большинство баз данных. Разработчики этих баз данных утверждают, что "уж их то базы данных работают". Но в дальнейшем разговоре оказывается, что они даже не представляют как доказать, что база данных работает. Они считают, что если удалось ввести имя "Вася", а потом удалось его найти и прочитать, то все в порядке. Их заказчики и, в дальнейшем, пользователи вообще не задумываются о том, что базу данных нужно протестировать. Когда они покупают электрический чайник в магазине, они его даже на зуб попробуют. А база данных работает только потому, что об этом сказали разработчики. В чем поблема? В образовании. Как разработчиков учили, так они и делают впоследствии.

Совет для преподавателей
       Во многих курсах по базам данных (различные ВУЗы) в качестве учебного задания используется база данных "Библиотека". Почему-то считается, что это самая простая предметная область. На самом деле "Библиотека" одна из сложнейших тем, просто потому что область используемых данных чрезвычайно широка. Это все языки и страны, это все времена. И для исследования всех требований требуется много усилий. Бухгалтерский учет на каком-нибудь небольшом предприятии в тысячи раз проще, чем описание "Библиотеки".

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





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


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