Связь между таблицами в реляционной модели реализуется внешним ключом.
Внешний ключ — множество колонок подчинённой таблицы, соответствующее ключу главной таблицы
Я намеренно опустил уточняющее прилагательное «первичный», потому что связь в реляционной модели может проходить по любому ключу. Многие СУБД поддерживают декларативную ссылочную целостность, позволяющую определить внешний ключ со ссылкой не только на первичный ключ таблицы, но и на любой другой набор её колонок, объявленных уникальными.
В приведённом примере связь между таблицами профилей (profiles) и сообщений (messages) осуществляется по первичному ключу. Связь является обязательной (mandatory).
Обязательная связь — строки в подчинённой таблице не могут существовать без соответствующих строк в главной таблице
Обязательная связь реализуется объявлением соответствующего столбца внешнего ключа как не допускающего неопределённых значений NOT NULL.
С таблицей очереди отправки (mailing_queue) связь осуществляется по ключу «адрес электропочты»; соответствующий столбец объявлен уникальным. Кроме того, вторая связь является ключевой.
Рис. 1. Примеры связей
Ключевая связь — связь, при которой внешний ключ таблицы входит в состав одного из её ключей.
Из этого определения следует также, что ключевая связь всегда является обязательной.
Ключевая связь на практике встречается часто, например, таблица жилых домов имеет ключ в виде идентификатора улицы и номера дома. Таким образом, между улицами и расположенными на них домами существует ключевая связь, даже если вы используете для домов суррогатный автоинкрементный первичный ключ, а колонки «Улица» и «Номер дома» забыли пометить ограничениями уникальности.
Если представить приведённую схему в виде SQL-скрипта, то в реализации SQL Server получим следующий код.
CREATE TABLE mailing queue (
email VARCHAR (100) NOT NULL,
sending_status TINYINT NOT NULL,
CONSTRAINT PK mailing queue
PRIMARY KEY CLUSTERED (sending_status, email)
CREATE TABLE messages (
id_message INTEGER NOT NULL, title VARCHAR (50) NOT NULL,
msg_text VARCHAR(MAX), id_owner INTEGER NOT NULL,
CONSTRAINT PK_messages PRIMARY KEY (id_message)
CREATE TABLE profiles (
id_profile INTEGER NOT NULL, logon_name VARCHAR (30) NOT NULL,
email VARCHAR (100) NOT NULL,
CONSTRAINT PK_profiles PRIMARY KEY (id_profile)
GO
ALTER TABLE mailing queue
ADD CONSTRAINT FK mailing queue profiles FOREIGN KEY (email)
REFERENCES profiles (email)
GO
ALTER TABLE messages
ADD CONSTRAINT FK messages profiles FOREIGN KEY (id_owner)
REFERENCES profiles (id profile)
GO