Размещайте ограничения СНЕСК() табличного уровня в конце объявления таблицы

Обоснование
В SQL-продуктах эти ограничения поддерживаются не особенно широко, хотя и являются законной частью синтаксиса SQL-92. Их предикаты действуют на всю таблицу, а не на отдельные строки, что предполагает использование агрегирующих функций.

CREATE TABLE Prizes

(...

CONSTRAINT only_5_prizes_each_winner

CHECK (NOT EXISTS (SELECT *

FROM Prizes AS P1

GROUP BY P1.contestant_id HAVING COUNT(*) > 5

)

),

CONSTRAINT nojnissing_ticket_nbrs

CHECK ((SELECT MAX(ticket_nbr) - MIN(ticket_nbr) + 1

FROM Prizes AS P1)

= (SELECT COUNT(ticketjibr)

FROM Prizes AS P1)

);

Исключения
Нет.

Используйте для многотабличных ограничений выражение CREATE ASSERTION

Обоснование
В SQL-продуктах эти ограничения поддерживаются не особенно широко, хотя и являются законной частью синтаксиса SQL-92. Их предикаты действуют не на одну, а сразу на несколько таблиц. Это означает, что и описываться они должны на более высоком уровне. Размещайте многотабличные ограничения СНЕСК() в выражениях CREATE ASSERTION, а не в описаниях таблиц. С практической точки зрения, все ограничения, примененные к пустой таблице, должны возвращать значение TRUE. Выражение CREATE ASSERTION позволяет задавать такое поведение. Имя утверждения ведет себя так же, как имя ограничения.

CREATE ASSERTION enough_money_to_pay_prizes

AS

CHECK ((SELECT SUM(pnze_money)

FROM Prizes AS P1)

<= (SELECT SUM(cash_on_hand)

FROM Bank));

Исключения
Если ваш SQL-продукт не поддерживает выражение CREATE ASSERTION, ничего, конечно, нельзя поделать. Если же оно поддерживается, для нарушения данного правила должно быть очень серьезное основание, связанное с дизайном схемы.

Используйте для каждой проверки собственное ограничение СНЕСК()

Обоснование
Создавайте несколько простых ограничений CHECK() с собственной конструкцией для каждого, вместо написания одного сложного ограничения со множеством тестов.
Имя, присвоенное ограничению, отображается в сообщении об ошибке, когда ограничение нарушено. Если все проверки проводятся в рамках единой конструкции CHECK(), какое имя ей дать? Представьте себе, что в одном ограничении вы одним махом проверяете правильное использование прописных букв, пробелов и длину строки почтового адреса. Можно, конечно, присвоить этому ограничению имя наподобие “ошибочный адрес” и надеяться, что пользователь сам сообразит, что сделал неправильно. Но гораздо лучше будет организовать отдельные проверки, тем самым дав пользователю более конкретное указание на ошибку.

Исключения
Если ваш SQL-продукт поддерживает предикат SIMILAR TO (схожий с функцией grep из стандарта POSIX), иногда оказывается удобным создание длинных регулярных выражений.
Возможно, вы захотите создать составное ограничение с невнятным именем из соображений безопасности, но мне такую ситуацию представить довольно трудно.

Если у таблицы нет ключа, это не таблица

Обоснование
Здесь мы подбираемся к самой сути таблицы. Беда в том, что многие новички вообще не понимают, что такое ключ. Ключ должен состоять из подмножества атрибутов (столбцов) таблицы. Нет и не может быть универсального “безразмерного” ключа. Поскольку не существует двух одинаковых наборов сущностей, уникальные атрибуты для них должны подбираться на индивидуальной основе. Господь, к несчастью, не присвоил каждой созданной им вещи 17-буквенный код на иврите.
В табл. 3.1 приводится классификация ключей.

Табл. 3.1. Типы ключей

  Естественный ключ Искусственный ключ Явный физический указатель Системный суррогатный ключ
Строится по реальной модели данных Да Нет Нет Нет
Проверяем по реальной модели Да Нет, исходит из надежного источника Нет Нет
Проверяем сам по себе Да Да, например, по синтаксису, по контрольному разряду Нет Нет
Переносим на другую платформу Да Да Нет Нет
Доступен пользователю Да Да Да Нет, может быть изменен системой

1. Естественный ключпредставляет собой набор атрибутов из таблицы и действует как уникальный идентификатор. Он виден пользователю.Его можно проверить на корректность как по реальной модели данных,так и сам по себе. Пример, универсальный код продукта UPC можно прочитать на упаковке, проверить сканером, сравнить с данными на Web-узле производителя.
2. Искусственный ключпредставляет собой дополнительный атрибут, специально введенный в таблицу для использования в качестве ключа. Он виден пользователю, не связан напрямую с реальной моделью данных, но может быть проверен сам по себе — по синтаксису, по контрольному разряду. Пример: свободные коды из схемы UPC, которые пользователь может присвоить своему продукту. Корректность кодов можно проверять только в пределах вашей организации. Если вы занимаетесь разработкой ключа самостоятельно, помните, что эго дело не из легких. Подробнее об этом — в главе 5.
3. Явный физический указательне основан на модели данных и доступен пользователю. Предсказать или проверить его значение нельзя. Система вычисляет его, основываясь на физическом хранении данных. Пример: поля IDENTITY в семействе T-SQL, другие нестандартные нереляционные средства автонумерации, указатели, основанные на номерах цилиндра и дорожки жесткого диска в Oracle. Технически, это вообще не ключи, так как к логической модели данных они не имеют никакого отношения. Удобны для ленивых, не желающих думать программистов-“чайников”. Наихудший способ программирования на SQL
4. Системный суррогатный ключгенерируется системой для замещения реального ключа на основе атрибутов из таблицы; пользователю недоступен. Пример: алгоритмы хэширования Teradata. Определяющее значение имеет тот факт, что пользователь ни при каких обстоятельствах не видит суррогатный ключ, не может использовать его в командах DELETE и UPDATE или создать командой INSERT. Если бы он мог это сделать, то немедленно повредил бы целостность данных, нарушив соответствие между реальными и суррогатными ключами. Суррогатные ключи поддерживаются системой.
Обратите внимание, что суррогатные ключи иногда путают с физическими указателями; на самом же деле они концептуально различны.



Наши рекомендации