Шрифт:
Интервал:
Закладка:
CREATE DOMAIN D_IDENTITY AS BIGINT NOT NULL;
COMMIT;
CREATE TABLE PERSON (
PERSON_ID D_IDENTITY PRIMARY KEY,
Firebird создает ограничение таблицы с именем INTEG_M и индекс с именем RDB$PRIMARYnn. (пл в каждом случае - число, полученное от генератора. Эти два числа не связаны друг с другом.) Вы не можете повлиять на то, какими будут эти имена, и не можете поменять их.
Результат будет похожим, если вы используете тот же подход при добавлении столбца, используя оператор ALTER TABLE и создавая первичный ключ в одном предложении:
ALTER TABLE BOOK
ADD BOOK_ID D_IDENTITY PRIMARY KEY;
Определение первичного ключа как именованного ограниченияДругой способ определения первичного ключа в определении таблицы - добавить объявление ограничения в конце определений столбцов. Объявления ограничений помещаются последними, потому что они зависят от существования столбцов, к которым они обращаются. Этот метод дает вам возможность именования ограничений. Следующее объявление именует ограничение первичного ключа как PK_ATABLE:
CREATE TABLE ATABLE (
ID BIGINT NOT NULL,
ANOTHER_COLUMN VARCHAR (20),
CONSTRAINT PK_ATABLE PRIMARY KEY(ID) );
Теперь вместо использования сгенерированного системой имени RDB$PRIMARYnnn Firebird использует PK_ATABLE В качестве имени этого ограничения. В Firebird 1.5 и выше он также применяет определенное пользователем имя ограничения для поддерживающего уникального индекса. В этом примере индекс получит имя PK_ATABLE, когда в других версиях его имя будет RDB$PRIMARYnnn.
Firebird 1.5 также позволяет использовать определенные пользователем имена для ограничения и поддерживающего его индекса.
Использование пользовательского индексаДо Firebird 1.5 не было возможности использовать убывающий индекс для поддержки первичного ключа. Начиная с версии 1.5, можно поддерживать первичный ключ убывающим индексом. Чтобы это сделать, в Firebird 1.5 добавляется расширение синтаксиса в форме предложения USING, позволяющего создавать индекс ASC[ENDING] (по возрастанию) или DESC [ENDING] (по убыванию) и присваивать ему имя, отличное от имени ограничения.
AS с и DESC определяют направление поиска. Подробнее эта концепция обсуждается в главе 18.
Следующий оператор создаст ограничение первичного ключа с именем PK ATEST и поддерживающий его убывающий индекс с именем IDX_PK_ATEST:
CREATE TABLE ATEST (
ID BIGINT NOT NULL,
DATA VARCHAR(10));
COMMIT;
ALTER TABLE ATEST
ADD CONSTRAINT PK_ATEST PRIMARY KEY(ID)
USING DESC INDEX IDX_PK_ATEST;
COMMIT;
Альтернативный синтаксис также будет работать:
CREATE TABLE ATEST (
ID BIGINT NOT NULL,
DATA VARCHAR(10),
CONSTRAINT PK_ATEST PRIMARY KEY(ID)
USING DESC INDEX IDX PK ATEST;
! ! !
ВНИМАНИЕ! Если вы создаете индекс DESCENDING для ограничения первичного или уникального ключа, вы должны указать USING DESC INDEX для всех ссылающихся на него внешних ключей.
. ! .
Добавление первичного ключа к существующей таблицеДобавление в таблицу ограничений может быть отложенным. Это общая практика разработчиков определять все свои таблицы без ограничений таблицы, а затем добавлять их, используя отдельный скрипт. Основная причина такой практики: большие скрипты часто дают сбой, потому что авторы забывают про некоторые зависимости. Просто будет меньше головной боли, если создавать базу данных в последовательности, которая уменьшает время и раздражение при исправлении ошибок зависимостей и нового запуска скриптов.
Обычно в первом скрипте мы объявляем таблицы и подтверждаем их создание:
CREATE TABLE ATABLE (
ID BIGINT NOT NULL,
ANOTHER_COLUMN VARCHAR (20),
< другие столбцы > ) ;
CREATE TABLE ANOTHERTABLE (
. . .
COMMIT;
ALTER TABLE ATABLE
ADD CONSTRAINT PK_ATABLE
PRIMARY KEY(ID);
ALTER TABLE ANOTHERTABLE...
и т.д.
В следующей главе при рассмотрении определений FOREIGN KEY станут очевидными преимущества создания базы данных в последовательности надежных зависимостей.
Ограничения CHECK
Ограничение CHECK используется для проверки достоверности вводимых значений данных. Оно реализует условия или требования, которым должно удовлетворять значение для успешного добавления или обновления. Оно не может изменять вводимое значение; оно лишь вернет исключение проверки достоверности, если значение не будет соответствовать условию.
! ! !
СОВЕТ. Ограничения CHECK применяются после выполнения триггеров "before". Используйте триггер, если вы хотите выполнить проверку и присвоить данным допустимые значения.
. ! .
В определении таблицы это ограничение на уровне таблицы. В отличие от ограничений CHECK, применимых к определению домена, его элемент VALUE является ссылкой на столбец. Например, для домена предложение CHECK может быть следующим:
CHECK(VALUE > 10)
В определении таблицы то же самое условие для столбца с именем ACOLUMN будет представлено как:
CHECK (ACOLUMN > 10)
Ограничение CHECK будет активным для операций INSERT и UPDATE. Хотя это ограничение на уровне таблицы, его область действия может выходить за пределы уровня столбца на уровень строки и, хотя это не рекомендуется, на уровень таблицы и даже за пределы таблицы. Ограничение CHECK гарантирует целостность данных, только если значения, включенные в проверку, находятся в той же самой строке, что и проверяемое значение.
! ! !
ВНИМАНИЕ! Вы не должны использовать выражения, которые сравнивают значение со значениями из других строк этой же таблицы или других таблиц, потому что любая строка, отличная от текущей, может находиться в процессе изменения или удаления в другой транзакции. В особенности не полагайтесь на ограничение CHECK для проверки ссылочных отношений!
. ! .
Условие поиска может:
* проверять, что вводимое значение находится в указанном диапазоне;
* проверять, что значение присутствует в списке допустимых значений;
* сравнивать значение с константой, выражением или со значением данных другого столбца из этой же строки.
Замечания по использованию CHECKСуществуют определенные условия использования ограничений CHECK.
* Столбец может иметь только одно ограничение CHECK, хотя его логика может быть представлена как сложное условие поиска - одно ограничение, много условий.
* Ограничение CHECK для столбца, основанного на домене, не может перекрывать наследуемую от домена проверку. Определение столбца может использовать обычное предложение CHECK, чтобы добавить дополнительную логику ограничения в наследуемое ограничение. Оно будет соединено с наследуемым ограничением конъюнкцией (логической операцией И).
* Ограничение CHECK не может ссылаться на домен. Синтаксис ограничения CHECK:
CHECK (<условие-поиска>);
<условие-поиска> =
<val> <operator> {<val> | {<выбор-одного>) }
| <val> [NOT] BETWEEN <val> AND <val>
| <val> [NOT] LIKE <val> [ESCAPE <val>]
| <val> [NOT] IN (<val> [, <val> ...] | <список-выбора>)
| <val> IS [NOT] NULL
| <val> { [NOT] { = | < | > } |>=|<=}
{ ALL | SOME | ANY }(<список-выбора>)
| EXISTS (<выражение-выбора>)
| SINGULAR (<выражение-выбора>)
| <val> [NOT] CONTAINING <val>
| <val> [NOT] STARTING [WITH] <val>
| (<условие-поиска>)
| NOT <условие-поиска>
| <условие-поиска> OR <условие-поиска>
l <условие-поиска> AND <условие-поиска>
Диапазон возможностей при определении ограничений CHECK действительно весьма широк - теоретически в нем может быть использовано почти любое условие поиска. Для разработчика важно выбрать разумные и безопасные условия, т. к. они действуют для каждой операции INSERT и UPDATE для таблицы.
В части V данной книги описывается синтаксис установки различных стилей условия поиска.
Пример. Следующее ограничение проверяет значения двух столбцов для гарантии, что одно больше другого. Хотя оно также предполагает условия NOT NULL для обоих столбцов - проверка будет ошибочной, если хотя бы один столбец будет иметь пустое значение, - оно не устанавливает ограничение NOT NULL для столбца:
CHECK (COL_1 > COL_2);
Проверка даст ошибку, если арифметическая проверка будет ошибочной или если любой из столбцов COL_1 или COL_2 имеет значение NULL. Следующая операция будет успешной:
INSERT INTO TABLE_1 (COL_1, COL_2) VALUES (6,5);
Ограничения UNIQUE
Ограничение UNIQUE, как и ограничение первичного ключа, гарантирует, что никакие две строки не будут иметь то же значение указанного столбца или группы столбцов. Вы можете объявить для таблицы более одного ограничения UNIQUE, но оно не может использовать тот же набор столбцов, который был использован для ограничения PRIMARY KEY или другого UNIQUE.
Ограничение UNIQUE фактически создает уникальный ключ, который виртуально имеет те же возможности, что и первичный ключ. Он может быть выбран как управляющий ключ для ограничения ссылочной целостности. Это делает его полезным в ситуациях, когда вы определяете небольшой суррогатный первичный ключ для его атомарности и улучшения производительности в соединениях и операциях поиска, но при этом хотите сохранить режим формирования альтернативной связи внешнего ключа с уникальным ключом для нерегулярного использования.
- Delphi. Учимся на примерах - Сергей Парижский - Программирование
- Сделай видеоигру один и не свихнись - Слава Грис - Программирование / Руководства
- Психбольница в руках пациентов - Алан Купер - Программирование