Предисловие переводчика
Статья "Ссылочная целостность является важной для баз данных", написанная Майклом Блахой в 2005 г. специально для портала www.odbms.org, возможно, покажется очевидной, тривиальной и немного путанной специалистам в области реляционных баз данных. Но она и не адресована подобным специалистам. Основная идея состоит в том, что ссылочной целостностью нельзя пренебрегать и в области проектирования баз данных (не обязательно реляционных), и в области моделирования и разработки приложений (не обязательно приложений баз данных). Опыт автора показывает, что, несмотря на очевидную фундаментальность понятия ссылочной целостности, большая часть разработчиков программного обеспечения (в том числе, и приложений баз данных) совершенно не заботится о ссылочной целостности своих данных, что приводит к плачевным последствиям.
1. Введение
Ссылочная целостность – это ограничение базы данных, гарантирующее, что ссылки между данными являются действительно правомерными и неповрежденными. Ссылочная целостность является фундаментальным принципом теории баз данных и проистекает из той идеи, что база данных должна не только сохранять данные, но и активно содействовать обеспечению их качества. Вот несколько дополнительных определений, найденных в Web:
- «Ссылочная целостность в реляционной базе данных – это согласованность между связанными таблицами. Ссылочная целостность обычно поддерживается путем комбинирования первичного ключа и внешнего ключа. Для соблюдения ссылочной целостности требуется, чтобы любое поле в таблице, объявленное внешним ключом, могло содержать только значения из поля первичного ключа родительской таблицы …»
[5]
- «[Ссылочная целостность – это] свойство, обеспечиваемое реляционными системами управления базами данных (РСУБД), которое предотвращает ввод несогласованных данных пользователями или приложениями. В большинстве РСУБД имеются различные правила ссылочной целостности, которые можно применить при создании связи между двумя таблицами.» [6]
- «[Ссылочная целостность – это] предохранительное устройство системы управления базами данных, гарантирующее, что каждый внешний ключ соответствует первичному ключу. Например, номера заказчиков являются первичными ключами в файле заказчиков и внешними ключами в файле заказов. При удалении записи заказчика должны быть удалены соответствующие записи заказов; в противном случае они останутся без исходной связи. Если СУБД не проверяет этого, соответствующий механизм должен программироваться в приложении.» [7]
Поддержка ссылочной целостности в базе данных обеспечивает много преимуществ.
- Улучшенное качество данных. Очевидным преимуществом является поддержка качества данных, хранимых в базе данных. Ошибки могут по-прежнему существовать, но, по крайней мере, ссылки будут подлинными и неповрежденными.
- Убыстрение разработки. Ссылочная целостность объявляется. Это гораздо продуктивнее (на один или два порядка), чем написание специального программного кода.
- Меньшее число ошибок. Объявления ссылочной целостности являются гораздо более лаконичными, чем эквивалентный программный код. По существу, такие объявления приводят к повторному использованию проверенного и оттестированного кода общего назначения в сервере баз данных, а не к новой реализации одной и той же логики от случая к случаю.
- Согласованность между приложениями. Ссылочная целостность обеспечивает качество данных для нескольких прикладных программ, которые могут обращаться к базе данных.
Заметим, что определения, взятые из Web, выражаются в терминах реляционных баз данных. Однако принципы ссылочной целостности применяются в более широком контексте. Ссылочная целостность применима как к реляционным, так и к объектно-ориентированным (ОО) базам данных, а также к языкам программирования и моделированию.
2. Ссылочная целостность и РСУБД
Синтаксис SQL для определения ссылочной целостности выглядит, по существу, подобно следующему. Слова из прописных буква обозначают ключевые слова. Квадратные скобки выделяют необязательные параметры. Столбцы внешнего ключа находятся в таблице table1, а столбцы первичного ключа (или другой комбинации столбцов со свойством уникальности значений) – в таблице table2.
ALTER TABLE tableName1
ADD CONSTRAINT constraintName
FOREIGN KEY (columnList)
REFERENCES tableName2 [(columnList)]
[onDeleteAction] [onUpdateAction];
В SQL внешний ключ может ссылаться на любую комбинацию столбцов со свойством уникальности в таблице, на которую ведет ссылка. В стандарте SQL [3] обеспечиваются следующие действия по поддержанию ссылочной целостности при удалениях строк.
- Cascade. Удаление записи может привести к удалению записей с соответствующим значением внешнего ключа. Например, можно захотеть, чтобы при удалении записи о компании удалялись все адреса компании.
- No action. В качестве альтернативы можно запретить удаление записи, если имеются зависимые записи с соответствующим значением внешнего ключа. Например, если вы продали некоторой компании товары, то вы можете захотеть предотвратить удаление записи об этой компании.
- Set null. Удаление записи может приводить к установке в соответствующие внешние ключи неопределенного значения. Например, при замене самолета для выполнения рейса может понадобиться анулировать некоторые назначения посадочных мест. (Таким пассажирам придется запросить другие посадочные места.)
- Set default. Можно потребовать, чтобы при удалении записи во внешний ключ устанавливалось значение по умолчанию, а не неопределенное значение.
В стандарте SQL эти действия обеспечиваются и при модификации записей. Поддержка стандарта различается в разных продуктах.
- SQL Server. В SQL Server 2000 внешний ключ может ссылаться на первичный ключ или на комбинацию столбцов со свойством уникальности. Не поддерживаются опции set null и set default. Однако опции cascade и no action поддерживаются полностью, и на практике этого часто оказывается достаточно. Заметим также, что синтаксис для no action отличается от стандарта SQL. В SQL Server при отсутствии явного указания ссылочного действия подразумевается no action.
- Oracle. В Oracle 10g внешний ключ также может ссылаться на первичный ключ или на комбинацию столбцов со свойством уникальности. В Oracle поддерживаются ссылочные действия при удалении записей, но отсутствуют действия при модификации. Для действий при удалении поддерживаются опции cascade, no action и set null. Поддержка опции set default отсутствует. Как и в SQL Server, синтаксис no action отличается от стандарта SQL. При отсутствии явного указания ссылочного действия подразумевается no action.
- MySQL. Поддержка ссылочной целостности появилась в MySQL 5.0 (при использовании InnoDB). В MySQL стандарт SQL поддерживается в более полном объеме, чем в SQL Server и Oracle. Поддерживаются варианты on delete и on update со всеми четырьмя ссылочными действия. В MySQL требуется, чтобы для внешнего ключа и ключа, на который ведет ссылка, поддерживались индексы базы данных – это хороший обычай, которому мы советуем следовать.* Столбцы, на которые ведет ссылка, могут быть первичным ключом или комбинацией столбцов со свойством уникальности.
- MS-Access. В MS-Access команды SQL для определения ссылочной целостности поддерживаются только частично, но средство графического связывания является более сильным. С помощью графического интерфейса можно определить ссылочную целостность, а также ссылочные действия cascade и no action.
3. Ссылочная целостность и ООСУБД
Понятие ссылочной целостности применимо и к ООСУБД. Между объектами имеются связи, которые приводят к их взаимной зависимости, и поддержку этих зависимостей не следует возлагать на код приложения.
Ссылочная целостность поддерживается в некоторых ООСУБД . Например, в ObjectStore ссылочная целостность реализуется с использованием сдвоенных указателей между парой объектов, которые поддерживаются СУБД во взаимно согласованном состоянии [1]. Таким образом, в ObjectStore сохраняется стиль языков программирования – указатель представляет собой всего лишь еще одну переменную экземпляра, скрытую внутри объекта. Однако в системе соблюдается и смысл ссылочной целостности путем поддержки зависимостей между объектами и предотвращения «висящих» ссылок.
Эти пары взаимно согласованных указателей называются в ObjectStore инверсными партнерами (inverse members). В ObjectStore поддерживается целостность инверсных партнеров; при изменении одного партнера ObjectStore прозрачным образом изменяет другого партнера. Аналогично, при удалении объекта ObjectStore автоматически обновляет всех инверсных партнеров, чтобы предотвратить появление «висящих» ссылок.
4. Ссылочная целостность и языки
В языках программирования (с небольшим числом исключений) ссылочной целосности не придается значение. Вместо этого в них делается упор на инкапсуляции, на том, что детали реализации следует скрывать в классе. Проблема состоит в том, что инкапсуляция часто подрывается наличием зависимостей между объектами. Значение оказывается недостаточным для обеспечения ссылки на объект.
Например, объект Занятость (Employment) ссылается на объекты Человек (Person) и Компания (Company). Невозможно иметь дело с изолированной Занятостью. Если удаляется Человек, то должны быть удалены и связанные с ним объекты Занятость, потому что иначе образуются «висящие» ссылки на объект. Нельзя создать объект Занятость без объектов Человек и Компания.
Как демонстриуется в [4], в языке программирования можно поддерживать ссылочную целостность. В GE R&D (General Electric Corporate Research and Development) Рэмбо (Rumbaugh) реализовал объектно-ориентиованный язык программирования DSM с семантической поддержкой зависимостей (называемых в статье отношениями) между объектами.
5. Ссылочная целостность и UML
При использовании UML за счет семантической поддержки ассоциаций также возникает ссылочная целостность. Ассоциация (association) – это описание группы соединений (link) с общей структурой и семантикой. Соединение – это физическая или концептуальная связь между объектами.
При конструировании моделей классов UML важно явно представить зависимости между объектами в виде ассоциаций и не скрывать их в виде атрибутов. Традиционные языки программирования вынуждают понижать статус ассоциаций, но они должны быть понятны, по крайней мере, на уровне мышления. Тогда можно придумать наилучший обходной путь в пределах возможностей языка.
6. Используется ли ссылочная целостность?
Ссылочная целостность является выдающимся аспектом теории реляционных баз данных. Но действительно ли она используется на практике? Мы можем ответить на этот вопрос, поскольку на основе своих исследований в области обратной инженерии обладаем данными о 50 существующих базах данных [2].
На практике ссылочная целостность обеспечивается редко. Насколько нам известно, она не поддерживается в большинстве программ, поскольку в языках программирования отсутствует соответствующий механизм, что затрудняет поддержку. Однако проблема является более глубокой. В большинстве реализаций реляционных СУБД также отсутствует ссылочная целостность. Даже в тех случаях, когда в РСУБД поддерживается механизм ссылочной целостности, многие разработчики его не используют. Наши исследования в области обратной инженерии [2] показали, что 90% разработчиков реляционных баз данных не используют ссылочную целостность в своих приложениях.
Последствия прискорбны, и мы видем их повседневно – программное обеспечение содержит ошибки, работает медленно, его трудно расширять. Одним из характерных примеров может служить стандарт LDAP. В LDAP не включены средства подержки ссылочной целостности, и это приводит к печальным последствиям.
7. Заключение
Обычно термин «ссылочная целостность» ассоциируется только с реляционными СУБД. Но в действительности этот термин обладает более широким смыслом и относится в базам данных вообще, а также к языкам программирования и моделированию. Смысл «ссылочной целостности», происходящий из реляционных СУБД, относится к механизму реализации. Однако более глубокий смысл связан с зависимостями между объектами. В этом расширенном смысле ссылочная целостность является существенным аспектом нашего осмысления проблем и представления их на основе моделей. Поэтому ссылочную целостность необходимо учитывать вне зависимости от реализационной платформы – РСУБД, ООСУБД или языка программирования.
8. Литература
[1] Michael Blaha and William Premerlani. Object-Oriented Modeling and Design for Database Applications. Upper Saddle River, New Jersey: Prentice Hall, 1998.
[2] Michael Blaha. A retrospective on industrial database reverse engineering projects—part 2. Eighth Working Conference on Reverse Engineering, October 2001, Stuttgart, Germany, 147–153.
[3] Jim Melton and Alan R. Simon. Understanding the New SQL: A Complete Guide. San Francisco, California: Morgan Kaufmann, 1993.
[4] James Rumbaugh. Relations as semantic constructs in an object-oriented language. OOPSLA’87 as ACM SIGPLAN 22, 12 (Dec. 1987), 466–481.
[5] en.wikipedia.org/wiki/Referential_integrity
[6] www.webopedia.com/TERM/R/referential_integrity.html
[7] computing-dictionary.thefreedictionary.com/referential+integrity
Об авторе
Майкл Блаха (Michael Blaha) защитил кандидатскую диссертацию в области баз данных в Университете им. Вашингтона г. Санкт-Луи, шт. Миссури. Восемь лет он проработал в Центре исследований и разработок компании General Electric в компании Джеймса Рэмбо (James Rumbaugh). С 1993 г. Блаха является консультантом и преподавателем в областях моделирования, архитектуры программного обеспечения, проектирования баз данных и обратной инженерии. Блаха - автор четырех книг и многочисленных статей. В 2005 г. вышло второе издание его книги (в соавторстве с Рэмбо) "Объектно-ориентированное моделирование и проектирование c использованием UML" (Object-Oriented Modeling and Design with UML, Second Edition, Prentice Hall, 2005, ISBN 0130159204).
* Не могу не отметить наивность автора, связанную с его отдаленностью от аспектов реализации СУБД. Насколько мне известно, испокон веков, во всех развитых РСУБД, начиная с проекта System R, при объявлении в таблице возможных и внешних ключей система автоматически создавала индексы (уникальные для возможных ключей). (прим. переводчика).