Spec-Zone.ru › MariaDB

ОГРАНИЧЕНИЯ

MariaDB поддерживает реализацию ограничений на уровне таблицы с помощью операторов CREATE TABLE или ALTER TABLE. Ограничение таблицы ограничивает данные, которые вы можете добавить в таблицу. Если вы попытаетесь вставить неверные данные в столбец, MariaDB выдаст ошибку.

Синтаксис

[CONSTRAINT [symbol]] constraint_expression

constraint_expression:
  | PRIMARY KEY [index_type] (index_col_name, ...) [index_option] ...
  | FOREIGN KEY [index_name] (index_col_name, ...) 
       REFERENCES tbl_name (index_col_name, ...)
       [ON DELETE reference_option]
       [ON UPDATE reference_option]
  | UNIQUE [INDEX|KEY] [index_name]
       [index_type] (index_col_name, ...) [index_option] ...
  | CHECK (check_constraints)

index_type:
  USING {BTREE | HASH | RTREE}

index_col_name:
  col_name [(length)] [ASC | DESC]

index_option:
  | KEY_BLOCK_SIZE [=] value
  | index_type
  | WITH PARSER parser_name
  | COMMENT 'string'
  | CLUSTERING={YES|NO}

reference_option:
  RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT

Описание

Ограничения накладывают ограничения на данные, которые вы можете добавить в таблицу. Это позволяет вам обеспечивать целостность данных из MariaDB, а не через логику приложения. Когда оператор нарушает ограничение, MariaDB выдаёт ошибку.

Существует четыре типа ограничений таблицы:

Ограничение Описание
PRIMARY KEY Устанавливает столбец для ссылки на строки. Значения должны быть уникальными и не нулевыми.
FOREIGN KEY Устанавливает столбец для ссылки на первичный ключ другой таблицы.
UNIQUE Требует, чтобы значения в столбце или столбцах встречались только один раз в таблице.
CHECK Проверяет, соответствуют ли данные заданному условию.

Таблица Information Schema TABLE_CONSTRAINTS содержит информацию о таблицах, которые имеют ограничения.

Ограничения внешних ключей

InnoDB поддерживает ограничения внешних ключей. Синтаксис определения ограничения внешнего ключа в InnoDB выглядит так:

[CONSTRAINT [symbol]] FOREIGN KEY
    [index_name] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name,...)
    [ON DELETE reference_option]
    [ON UPDATE reference_option]

reference_option:
    RESTRICT | CASCADE | SET NULL | NO ACTION

Таблица Information Schema REFERENTIAL_CONSTRAINTS содержит дополнительную информацию об внешних ключах.

Ограничения CHECK

Ограничения применяются. Перед MariaDB 10.2.1 выражения ограничений принимались в синтаксисе, но игнорировались.

Вы можете определить ограничения двумя способами:

  • CHECK(expression) указанные как часть определения столбца.
  • CONSTRAINT [constraint_name] CHECK (expression)

Перед вставкой или обновлением строки все ограничения оцениваются в порядке их определения. Если любое выражение ограничения возвращает false, то строка не будет вставлена или обновлена. В ограничении можно использовать большинство детерминированных функций, включая UDF.

CREATE TABLE t1 (a INT CHECK (a>2), b INT CHECK (b>2), CONSTRAINT a_greater CHECK (a>b));

Если вы используете второй формат и не задаёте имя ограничению, то ограничение получит автоматически сгенерированное имя. Это делается для того, чтобы вы могли позже удалить ограничение с помощью ALTER TABLE DROP constraint_name.

Можно отключить все проверки выражений ограничений, установив переменную check_constraint_checks в значение OFF. Это полезно, например, при загрузке таблицы, которая нарушает некоторые ограничения, которые вы хотите найти и исправить позже в SQL.

Репликация

В базовой репликации только мастер проверяет ограничения, а невыполненные операторы не будут реплицированы. В операторной репликации клиенты также будут проверять ограничения. Поэтому ограничения должны быть идентичными и детерминированными в среде репликации.

Автоинкремент

Столбцы auto_increment не допускаются в ограничениях CHECK. Перед MariaDB 10.2.6 они допускались, но не работали правильно. См. MDEV-11117.

Примеры

CREATE TABLE product (category INT NOT NULL, id INT NOT NULL,
                      price DECIMAL,
                      PRIMARY KEY(category, id)) ENGINE=INNODB;
CREATE TABLE customer (id INT NOT NULL,
                       PRIMARY KEY (id)) ENGINE=INNODB;
CREATE TABLE product_order (no INT NOT NULL AUTO_INCREMENT,
                            product_category INT NOT NULL,
                            product_id INT NOT NULL,
                            customer_id INT NOT NULL,
                            PRIMARY KEY(no),
                            INDEX (product_category, product_id),
                            FOREIGN KEY (product_category, product_id)
                              REFERENCES product(category, id)
                              ON UPDATE CASCADE ON DELETE RESTRICT,
                            INDEX (customer_id),
                            FOREIGN KEY (customer_id)
                              REFERENCES customer(id)) ENGINE=INNODB;

Следующие примеры будут работать начиная с MariaDB 10.2.1.

Числовые ограничения и сравнения:

CREATE TABLE t1 (a INT CHECK (a>2), b INT CHECK (b>2), CONSTRAINT a_greater CHECK (a>b));

INSERT INTO t1(a) VALUES (1);
ERROR 4022 (23000): CONSTRAINT `a` failed for `test`.`t1`

INSERT INTO t1(a,b) VALUES (3,4);
ERROR 4022 (23000): CONSTRAINT `a_greater` failed for `test`.`t1`

INSERT INTO t1(a,b) VALUES (4,3);
Query OK, 1 row affected (0.04 sec)

Удаление ограничения:

ALTER TABLE t1 DROP CONSTRAINT a_greater;

Добавление ограничения:

ALTER TABLE t1 ADD CONSTRAINT a_greater CHECK (a>b);

Сравнения дат и длина символов:

CREATE TABLE t2 (name VARCHAR(30) CHECK (CHAR_LENGTH(name)>2), start_date DATE, 
  end_date DATE CHECK (start_date IS NULL OR end_date IS NULL OR start_date<end_date));

INSERT INTO t2(name, start_date, end_date) VALUES('Ione', '2003-12-15', '2014-11-09');
Query OK, 1 row affected (0.04 sec)

INSERT INTO t2(name, start_date, end_date) VALUES('Io', '2003-12-15', '2014-11-09');
ERROR 4022 (23000): CONSTRAINT `name` failed for `test`.`t2`

INSERT INTO t2(name, start_date, end_date) VALUES('Ione', NULL, '2014-11-09');
Query OK, 1 row affected (0.04 sec)

INSERT INTO t2(name, start_date, end_date) VALUES('Ione', '2015-12-15', '2014-11-09');
ERROR 4022 (23000): CONSTRAINT `end_date` failed for `test`.`t2`

Неправильная скобка:

CREATE TABLE t3 (name VARCHAR(30) CHECK (CHAR_LENGTH(name>2)), start_date DATE, 
  end_date DATE CHECK (start_date IS NULL OR end_date IS NULL OR start_date<end_date));
Query OK, 0 rows affected (0.32 sec)

INSERT INTO t3(name, start_date, end_date) VALUES('Io', '2003-12-15', '2014-11-09');
Query OK, 1 row affected, 1 warning (0.04 sec)

SHOW WARNINGS;
+---------+------+----------------------------------------+
| Level   | Code | Message                                |
+---------+------+----------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: 'Io' |
+---------+------+----------------------------------------+

Сравните определение таблицы t2 с таблицей t3. CHAR_LENGTH(name)>2 существенно отличается от CHAR_LENGTH(name>2), так как последнее ошибочно выполняет числовое сравнение поля name, что приводит к неожиданным результатам.

См. также

  • Внешние ключи
Содержимое, воспроизведённое на этом сайте, является собственностью соответствующих владельцев, и это содержание не проверяется заранее MariaDB. Мнения, информация и мнения, выраженные в этом содержании, не обязательно отражают точку зрения MariaDB или любой другой стороны.

© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/constraint/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API