Ключи базы данных
Ключ — набор атрибутов, однозначно идентифицирующий строку или связывающий отношения.
Кандидатный и первичный ключ
Кандидатный ключ минимален и уникален. Один кандидат выбирают первичным:
CREATE TABLE users (
id BIGINT PRIMARY KEY,
email VARCHAR(320) NOT NULL UNIQUE
);Здесь id — primary key, а email — альтернативный кандидатный ключ, если бизнес гарантирует его стабильную уникальность.
Первичный ключ может быть составным:
CREATE TABLE order_tags (
order_id BIGINT NOT NULL,
tag VARCHAR(50) NOT NULL,
PRIMARY KEY (order_id, tag)
);В таблице один constraint PRIMARY KEY, но он может включать несколько столбцов.
Естественный и суррогатный
Естественный ключ имеет смысл в домене: код страны, номер документа в пределах эмитента. Суррогатный создается системой: sequence/identity, UUID.
Суррогатный ключ не отменяет бизнес-уникальность:
CREATE TABLE items (
id BIGINT PRIMARY KEY,
order_id BIGINT NOT NULL,
sku VARCHAR(100) NOT NULL,
UNIQUE (order_id, sku)
);Внешний ключ
FOREIGN KEY (user_id)
REFERENCES users(id)
ON DELETE RESTRICTFK защищает ссылочную целостность. Он не обязательно создает индекс на дочернем столбце автоматически; индекс часто нужен для join и операций над родительской строкой.
Выбор идентификатора
Нужно оценить:
- стабильность и область уникальности;
- размер всех ссылающихся индексов;
- локальность вставки;
- генерацию в распределенной системе;
- возможность угадать идентификатор — это не замена авторизации.
Связано: Ограничения, constraints, Нормализация денормализация, Индексы SQL, Шардирование базы данных.
Вопросы
Чем primary key отличается от unique? Primary key выбран главным идентификатором и не допускает NULL; нюансы UNIQUE и NULL зависят от СУБД.
Может ли primary key быть составным? Да.
Зачем UNIQUE при суррогатном id? Чтобы база защищала реальный бизнес-инвариант.
Создается ли индекс для foreign key? Не гарантированно; это проверяют и часто добавляют вручную на дочерней стороне.
Является ли UUID безопасным токеном доступа? Нет, авторизацию нужно проверять независимо.