====== CONSTRAINT ====== ===== Версии сервера ===== ^ 0.9 ^ 1.0 ^ 1.5.3 ^ 1.5.4 ^ 1.5.5 ^ 2.0 ^ 2.0.3 ^ 2.0.4 ^ 2.1 ^ 2.5 ^ 3.0 ^ | Да | Да | Да | Да | Да | Да | Да | Да | Да | Да | ? | ===== Доступно в ===== [[raznovidnosti_jazyka_sql|ISQL]] ===== Формат ===== ..... ,[CONSTRAINT < constraint_name > ] { PRIMARY KEY ( < domain1 > [,< domainN >] ) [USING [ASC|DESC] INDEX < index_name > ]| FOREIGN KEY ( < domain1 > [,< domainN >] ) REFERENCES < table_name >( < domain1 > [,< domainN >] ) [ ON UPDATE < rule > ] [ ON DELETE < rule > ] [USING INDEX < index_name> ] | UNIQUE ( < domain1 > [,< domainN >] ) [USING [ASC|DESC] INDEX < index_name > ] | CHECK } ... ^ Параметр ^ Значение ^ | constraint_name | Имя создаваемого ограничения ссылочной целостности. При выполнении оператора может быть опущено, тогда сервер создаст имя автоматически в формате INTEG_NNNN. Соответственно, рекомендуется всегда указывать имя constraint. Внимание: если при создании ограничения ссылочной целостности Вы не указываете имя ограничения, то зарезервированное слово CONSTRAINT нужно пропускать тоже. | | domain1 | Имя домена (или имена доменов, перечисленные через запятую), по которому накладывается ограничение на таблицу. | | rule | Правило автоматической установки новых значений записей в таблице на которую накладывается ограничение ссылочной целостности, при изменении значения записи в таблице, на которую ссылаются записи. Подробно описание видов правил см. ниже. | | check_condition | Логическое условие проверки значения, по которому накладывается ограничение на таблицу. Подробнее, см. [[CHECK]] | | index_name | Явно задаваемое имя индекса. Если не указано, то SQL-сервер создаст индекс с системным именем. | :!: Начиная с Firebird 1.5 имена индексов, автоматически создаваемых для PRIMARY, FOREIGN и UNIQUE constraint, при явном указании имени CONSTRAINT принимают это же имя. Например, если PRIMARY KEY создан как constraint PK_TABLE primary key, то индекс по этому constraint будет иметь имя PK_TABLE. ===== Описание ===== ==== Объявление ограничения ссылочной целостности ==== Зарезервированное слово CONSTRAINT языка [[raznovidnosti_jazyka_sql|SQL]] сервера Firebird служит для работы с ограничениями ссылочной целостности создаваемых в базе данных таблиц. Ограничения ссылочной целостности бывают двух уровней: ограничения, накладываемые на отдельный столбец, и ограничения, накладываемые на всю таблицу. Одноименный оператор CONSTRAINT служит для работы с ограничениями ссылочной целостности, накладываемых на таблицу. Для наложения ограничений ссылочной целостности на столбец см. [[CREATE DOMAIN]]. Оператор ограничения ссылочной целостности CONSTRAINT не употребляется самостоятельно, а выполняется в рамках операторов [[CREATE TABLE]] и [[ALTER TABLE]], например: CREATE TABLE MY_TABLE( ID INTEGER NOT NULL, SOME_ID INTEGER NOT NULL, ...... CONSTRAINT PK_MY_TABLE PRIMARY KEY (ID) ); или в рамках оператора [[ALTER TABLE]] ALTER TABLE MY_TABLE ADD CONSTRAINT FK_MY_TABLE_SOME_ID FOREIGN KEY (SOME_ID) REFERENCES SOME_TABLE(ID) ON DELETE CASCADE ON UPDATE CASCADE; ==== Виды ограничений ссылочной целостности ==== === 1.Первичный ключ === Первичный ключ - домен или несколько доменов таблицы, однозначно характеризующие запись согласно третьей нормальной форме Бойесса-Кода. Объявляется при помощи служебных слов PRIMARY KEY( < domain1 > [,< domainN >]), где < domainN > - имя домена или имена доменов, перечисленные через запятую. Первичный ключ также может быть задан при создании домена таблицы. Например: CREATE TABLE MY_TABLE( ID INTEGER NOT NULL PRIMARY KEY, .... ); или (рекомендуемый вариант, с указанием имени constraint) CREATE TABLE MY_TABLE( ID INTEGER NOT NULL, .... CONSTRAINT PK_MY_TABLE PRIMARY KEY (ID), ); :!: При создании первичного ключа, необходимо еще также накладывать дополнительное ограничение ссылочной целостности на домены, входящие в первичный ключ NOT NULL. Подробнее, см. [[CREATE DOMAIN]] :!: У таблицы может быть только один первичный ключ. :!: Первичный ключ также можно создать командой [[ALTER TABLE]] === 2.Внешний ключ === Внешний ключ служит для связки родительской и дочерней таблиц в базе данных, когда одной записи в родительской таблице соответствует множество записей в дочерней таблице. На этом условии могут быть построены отношения сущностей в базе данных "один-к-одному" и "один-ко-многим". Внешний ключ строится по столбцам __в дочерней__ таблице, значения которых ссылаются на значения записей в родительской таблице. Формат объявления оператора: FOREIGN KEY ( < domain1 > [,< domainN >] ) REFERENCES < table_name > [ < Rdomain1 > [,< RdomainN >] ] [ON DELETE < rule > ] [ON UPDATE < rule > ]; где < rule > = {NO ACTION | CASCADE | SET DEFAULT | SET NULL }; ^ Параметр ^ Значение ^ | < domain1 > [,< domainN >] | определяет столбцы дочерней таблицы, по которым строится внешний ключ. | | < table_name > | Определяет таблицу, в которой описан первичный ключ (или столбец с атрибутом UNIQUE, см. ниже). На этот ключ (столбец) должен ссылаться внешний ключ дочерней таблицы для обеспечения ссылочной целостности. | | < Rdomain1 > [,< RdomainN > ] | необязателен при ссылке на первичный ключ родительской таблицы. При ссылке на ограничение ссылочной целостности с атрибутом UNIQUE (см. ниже) этот список требуется привести. | Правило < rule >, применяемое в необязательных атрибутах ON UPDATE и ON DELETE определяет поведение сервера для изменения записей в дочерних таблицах при изменении или удалении соответственно записей в родительской таблице. Ниже определены следующие правила. ^ Правило ^ Поведение сервера ^ | NO ACTON | запрет изменения/удаления записи в родительской таблице при наличии записей в дочерней подчиненной таблице. Если правило ON UPDATE или ON DELETE не задано явно (пропущено при объявлении оператора), то действует по умолчанию правило NO ACTION. | | CASCADE | для оператора [[DELETE]]: при удалении записей в родительской таблице приведет к удалению всех записей в подчиненной таблице, зависящих по внешнему ключу от записей в родительской таблице. Для оператора [[UPDATE]] при изменении полей связи в родительской таблице приведет к автоматическому обновлению записей в дочерней таблице на новое значение записей в родительской таблице. | | SET DEFAULT | в столбец (столбцы) внешнего ключа у записей дочерней таблицы заносятся значения столбца по-умолчанию, указанное при определении столбца (параметр DEFAULT, см. [[CREATE DOMAIN]]); если это значение отсутствует, возбуждается исключение. | | SET NULL | в столбец (столбцы) внешнего ключа дочерней таблицы заносятся значения NULL | **Пример:** (рекомендуемый вариант, с указанием имени constraint) CREATE TABLE MY_TABLE( ..., CID INTEGER NOT NULL, ..., CONSTRAINT FK_MY_TABLE_TABLE2 FOREIGN KEY (CID) REFERENCES TABLE2(ID)) :!: Внешний ключ также можно создать командой [[ALTER TABLE]]. Автоматические генераторы скриптов обычно создают описание Внешних ключей именно через [[ALTER TABLE]], и располагают их после создания всех таблиц, т.к. это позволяет избежать проблем, когда Внешний ключ ссылается на таблицу, которая еще не создана скриптом. === 3.Уникальный ключ === Уникальный ключ - дополнительная возможность ограничения значений записей таблицы с целью профилактики занесения в нее двух и более записей, имеющих одинаковое значение указанного столбца (столбцов). В отличие от PRIMARY KEY количество уникальных ключей в таблице неограничено (точнее, ограничено максимальной комбинаторной суммой вариантов комбинации имен доменов, входящих в таблицу). Уникальный ключ также называется "альтернативным", и чаще всего предназначен не для однозначной идентификации столбца, как Первичный ключ, а для указания столбца, который позволяет осуществить дополнительную идентификацию строки. Например - номер паспорта, код ИНН, номер пенсионной страховки, и т.д. :!: Указание NOT NULL для UNIQUE, начиная с Firebird 1.5, не является обязательным. При этом уникальный индекс, который будет контролировать данное ограничение UNIQUE, может содержать NULL. Такой индекс невозможно создать командой [[CREATE INDEX]]. Уникальный ключ может быть объявлен как и при описании домена: CREATE TABLE MY_TABLE( ...... FIELD1 INTEGER NOT NULL UNIQUE, ..... ); так и при описании таблицы (рекомендуемый вариант, с указанием имени constraint) CREATE TABLE MY_TABLE( .... FIELD1 INTEGER NOT NULL, FIELD2 INTEGER NOT NULL, .... CONSTRAINT UNQ_MY_TABLE_1 UNIQUE(FIELD1, FIELD2), .... ); :!: При создании уникального ключа для версий Firebird ниже 1.5, столбец или домен должен содержать дополнительное ограничение ссылочной целостности NOT NULL. Подробнее см. [[CREATE DOMAIN]] === 4.Проверка значений === Ограничение CHECK позволяет задать проверочное выражение, которое будет вычисляться при каждой вставке или обновлении данных. В случае, если выражение будет вычислено в true (истина), операция DML будет разрешена. И напротив, если выражение будет вычислено в false (ложь), операция будет прервана с выдачей соответствующего исключения о нарушении ограничения CHECK. :!: В случае, если выражение CHECK вычисляется в NULL, конечный результат проверки зависит от версии сервера:\\ До FB2.0 NULL вычислялось в false, и тем самым, ограничение считалось нарушенным.\\ Начиная с FB2.0 поведение сервера было скорректировано в соответствие стандарту: итоговое значение NULL в контексте CHECK эквивалентно true, и тем самым, ограничение считается выполненным. CREATE TABLE DRINK_VODKA( MAN_NAME VARCHAR(50) NOT NULL, MAN_AGE INTEGER NOT NULL, VODKA_VOL NUMERIC(12,3) NOT NULL, CONSTRAINT CHK1_DRINK_VODKA CHECK (MAN_AGE>=21), CONSTRAINT CHK2_DRINK_VODKA CHECK (VODKA_VOL between 0.05 and 0.5) ); :!: Ограничение CHECK также можно создать командой [[ALTER TABLE]]. ===== См. также ===== [[CREATE TABLE]], [[ALTER TABLE]] ===== Источник ===== 2008-05-02