Первичные и внешние ключи в базах данных относятся к ограничению. Оно включает в себя различные модификаторы колонок в базе данных, которые добавляют ограничения на их содержимое. В этом уроке мы рассмотрим уже известные ограничения, а также изучим новые.
Первичный ключ
Первичный ключ однозначно идентифицирует каждую запись внутри таблицы. Задается с помощью фразы PRIMARY KEY
, которая добавляется после указания типа, когда создается таблица. Первичный ключ в таблице может быть только один, и для него используется суррогатный ключ — идентификатор, у которого нет физического смысла:
CREATE TABLE products (
id bigint PRIMARY KEY,
name text,
price numeric
);
Внешний ключ
Внешний ключ — это ограничение, которое связывает указанную колонку с данными из другой таблицы. Такое ограничение гарантирует целостность данных. То есть попытка удалить данные, у которых есть зависимые данные, приведет к ошибке:
CREATE TABLE orders (
id bigint PRIMARY KEY,
product_id bigint REFERENCES products (id),
quantity integer
);
В данной таблице атрибут product_id
связан с атрибутом id
таблицы products
. Синтаксически для этого добавляется ключевое слово REFERENCES после типа поля. Затем добавляется имя таблицы, на которую идет связь. В скобках указывается поле, с которым эта связь создается. Наличие такой связи проявляется следующим образом:
- Если попробовать вставить в
orders
запись со значениемproduct_id
, которого нет в таблицеproducts
, то возникнет ошибка - Если попытаться удалить запись из
products
, на которую есть ссылки из таблицыorders
, то возникнет ошибка
Внешний ключ проверяет целостность данных и не позволяет появляться «мусору». Поэтому лучше ставить внешние ключи на все идентификаторы, для которых есть родительская таблица в базе.
Внешние ключи поддерживают несколько вариаций. Таким образом они поддерживают целостность, но не приводят к ошибкам при попытке удалить запись.
Вариант 1 — Каскадное удаление:
CREATE TABLE orders (
product_id bigint REFERENCES products (id) ON DELETE CASCADE,
);
В таком варианте при попытке удалить родительскую запись (products) будут удалены все записи в orders, которые ссылаются на этот продукт. Каскадное удаление — опасная опция, так как можно случайно лишиться данных. Стоит хорошо подумать, прежде чем включать ее.
Вариант 2 — Записи остаются, но вместо идентификатора проставляется null
:
CREATE TABLE orders (
product_id bigint REFERENCES products (id) ON DELETE SET NULL
);
Используется нечасто, но иногда может быть полезно.
Not Null
Not Null — это ограничение указывает на то, что колонка не может содержать null
значения. Его можно комбинировать с другими ограничениями, например, внешними ключами. Первичный ключ является NOT NULL
по умолчанию:
CREATE TABLE products (
id bigint PRIMARY KEY,
name text NOT NULL,
price numeric
);
CREATE TABLE orders (
id bigint PRIMARY KEY,
product_id bigint REFERENCES products (id) NOT NULL,
quantity integer
);
Уникальность
Чтобы гарантировать уникальность значений одного поля, используется ключевое слово UNIQUE
. Обычно его используют в описании конкретного поля, когда создается таблица:
CREATE TABLE products (
id bigint PRIMARY KEY,
name text UNIQUE,
price numeric
);
UNIQUE
никогда не используется совместно с первичным ключом, так как он уникален по определению.
Иногда бывает нужно реализовать уникальность по двум или более атрибутам. Для этого нужно описать UNIQUE
отдельно от конкретного поля:
CREATE TABLE products (
id bigint PRIMARY KEY,
name text,
locale varchar,
price numeric,
UNIQUE(name, locale)
);
Существует ситуация, в которой ограничение уникальности не срабатывает. Такое происходит, если хотя бы в одном из столбцов, включенных в ограничение, встречается NULL
. По стандарту, NULL
никогда не равен самому себе.
Выводы
В этом уроке мы узнали чуть больше об ограничении первичного и внешнего ключей. Еще познакомились с новыми полезными ограничениями: Not Null и уникальность. Они указывают на то, что колонка не может содержать null
значения и гарантируют уникальность поля, соответственно.
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты