Andmebaasivõtmed

🔑 Основные типы ключей

Ключ (на англ.)Название на русскомПростое объяснение — зачем он нужен
Primary KeyПервичный ключЭто основной идентификатор записи. Он обязателен и уникален. Без него не будет порядка в таблице.
Foreign KeyВнешний ключСвязывает одну таблицу с другой. Помогает SQL понять, где связь между таблицами, например, студент и его курсы.
Unique KeyУникальный ключГарантирует, что в этом поле не будет повторов, но это не основной ключ. Уникальность — да, главность — нет.
Simple KeyПростой ключКлюч из одного столбца. Например, OpilaseID — это простой ключ, потому что он один.
Composite KeyСоставной ключКлюч из нескольких полей, которые вместе дают уникальность. Например, StudentID + CourseCode.
Compound KeyКомбинированный ключТо же самое, что и составной, но подчеркивает, что поля могут быть разного типа или смысла.
SuperkeyСуперключЛюбая комбинация полей, которая делает запись уникальной, даже если лишняя. Например, ID + Email.
Candidate KeyКандидат на основной ключЛюбое поле (или комбинация), которое могло бы быть Primary Key. SQL «выбирает» один из них.
Alternate KeyАльтернативный ключТе candidate key, которые не выбраны как основной. Например, Isikukood, если Primary — OpilaseID.

💡 Примеры из жизни

  • Primary Key — как ID-паспорт: у каждого человека один, и он уникален.
  • Foreign Key — как ссылка на родителя в школе: ученик связан с родителем.
  • Unique Key — как номер телефона: у каждого свой, но он не определяет тебя полностью.
  • Composite Key — как ФИО + дата рождения: вместе точно уникальны, по отдельности — нет.
  • Superkey — как ID + номер обуви + рост: делает тебя уникальным, но не нужно столько.

Возьмем пример БД школа

CREATE DATABASE KoolAndmebaas;
use KoolAndmebaas
CREATE TABLE Opilased (
    OpilaseID INT PRIMARY KEY,    -- PRIMARY KEY: основной уникальный ключ
    Eesnimi NVARCHAR(50),
    Perenimi NVARCHAR(50),
    Isikukood CHAR(11) UNIQUE,   -- UNIQUE KEY: каждый ученик имеет уникальный ID-код
    Email NVARCHAR(100),
    Telefon NVARCHAR(15),
    CONSTRAINT UQ_Email_Telefon UNIQUE (Email, Telefon)  -- COMPOUND KEY: уникальность комбинации email и телефона
);
INSERT INTO Opilased (OpilaseID, Eesnimi, Perenimi, Isikukood, Email, Telefon)
VALUES 
(3, 'Anna', 'Ivanova', '12345678901', 'anna@kool.ee', '5551111'),
(2, 'Mati', 'Tamm', '98765432100', 'mati@kool.ee', '5552222');

SELECT * FROM Opilased
-- Таблица учителей с UNIQUE KEY
CREATE TABLE Opetajad (
    OpetajaID INT PRIMARY KEY,
    Email NVARCHAR(100) UNIQUE  -- UNIQUE: email должен быть уникальным
);


INSERT INTO Opetajad (OpetajaID, Email)
VALUES 
(1, 'opetaja.liisa@kool.ee'),
(2, 'opetaja.jaanus@kool.ee');

SELECT * FROM Opetajad
-- Таблица регистраций с COMPOSITE KEY и FOREIGN KEY
CREATE TABLE Registreerimised (
    OpilaseID INT,
    KursuseKood NVARCHAR(10),
    RegistreerimiseKuupäev DATE,
    PRIMARY KEY (OpilaseID, KursuseKood),  -- COMPOSITE KEY: уникальная пара
    FOREIGN KEY (OpilaseID) REFERENCES Opilased(OpilaseID)   -- FOREIGN KEY: связь с учениками
);

INSERT INTO Registreerimised (OpilaseID, KursuseKood, RegistreerimiseKuupäev)
VALUES 
(3, 'MAT101', '2024-09-01'),
(2, 'BIO102', '2024-09-03');

SELECT * FROM Registreerimised
SELECT * FROM Opilased
-- Таблица оценок с COMPOSITE KEY
CREATE TABLE Hindamised (
    OpilaseID INT,
    KursuseKood NVARCHAR(10),
    Hinne INT,
    PRIMARY KEY (OpilaseID, KursuseKood)
);

INSERT INTO Hindamised (OpilaseID, KursuseKood, Hinne)
VALUES 
(2, 'MAT101', 5),
(3, 'BIO102', 4);

SELECT * FROM Registreerimised
SELECT * FROM Opilased
SELECT * FROM Hindamised
-- Таблица с COMPOUND UNIQUE KEY
CREATE TABLE Kontaktid (
    Email NVARCHAR(100),
    Telefon NVARCHAR(20),
    CONSTRAINT UQ_Kontakt UNIQUE (Email, Telefon)
);

INSERT INTO Kontaktid (Email, Telefon)
VALUES 
('anna@kool.ee', '5551111'),
('mati@kool.ee', '5552222');

SELECT * FROM Kontaktid
-- Таблица с SUPERKEY (PRIMARY KEY содержит "лишние" поля) поле Email здесь лишнее, потому что OpilaseID уже и так уникальный. // тестовая для SUPERKEY
CREATE TABLE Proov (
    OpilaseID INT,
    Email NVARCHAR(100),
    PRIMARY KEY (OpilaseID, Email)
);

INSERT INTO Proov (OpilaseID, Email)
VALUES 
(2, 'anna@kool.ee'),
(3, 'mati@kool.ee');

SELECT * FROM Proov
CREATE TABLE Opilased2 (
    ID INT,
    Isikukood CHAR(11),
    Email NVARCHAR(100),
    CONSTRAINT PK_Opilased2 PRIMARY KEY (ID),-- PRIMARY KEY
    CONSTRAINT UQ_Isikukood UNIQUE (Isikukood), -- ALTERNATE KEY
    CONSTRAINT UQ_Email UNIQUE (Email) -- ALTERNATE KEY
);

INSERT INTO Opilased2 (ID, Isikukood, Email)
VALUES 
(2, '11111111111', 'liis@kool.ee'),
(3, '22222222222', 'jaan@kool.ee');

SELECT * FROM Opilased2
SELECT * FROM Opilased;
SELECT * FROM Opetajad;
SELECT * FROM Registreerimised;
SELECT * FROM Hindamised;
SELECT * FROM Kontaktid;
SELECT * FROM Proov;
SELECT * FROM Opilased2;

ТаблицаКлючиЧто они делают
OpilasedPRIMARY KEY (OpilaseID)Уникальный ID ученика
UNIQUE (Isikukood)Гарантирует, что ID-код уникален
UNIQUE (Email, Telefon)Уникальная комбинация — ни один ученик не может повториться по этим 2 полям
OpetajadPRIMARY KEY (OpetajaID)ID учителя
UNIQUE (Email)У каждого учителя свой email
RegistreerimisedPRIMARY KEY (OpilaseID, KursuseKood)Один ученик не может дважды записаться на один курс
FOREIGN KEY (OpilaseID)Opilased.OpilaseIDСвязь с учениками
HindamisedPRIMARY KEY (OpilaseID, KursuseKood)Каждому ученику по курсу — одна оценка
KontaktidUNIQUE (Email, Telefon)Комбинация должна быть уникальной
ProovPRIMARY KEY (OpilaseID, Email)SUPERKEY: делает строку уникальной, но Email лишний
Opilased2PRIMARY KEY (ID)Основной ключ
UNIQUE (Isikukood) и UNIQUE (Email)Alternate Keys — тоже могли бы быть Primary

Проверка работы ограничений

-- Проверка UNIQUE
INSERT INTO Opilased (OpilaseID, Eesnimi, Perenimi, Isikukood, Email, Telefon)
VALUES (5, 'Test', 'Test', '12345678901', 'another@kool.ee', '9999999');

вызывает ошибку, потому что Isikukood = '12345678901' уже есть

Итог

Все ключи были созданы и протестированы. Таблица связана(Registreemised – Opilased), данные добавлены, ограничения работают. Понятие PRIMARY KEY, FOREIGN KEY, UNIQUE, COMPOSITE, SUPERKEY и другие отработаны на практике.

Источники

  1. w3schools: https://www.w3schools.com/sql/sql_primarykey.asp
  2. Habr: https://habr.com/ru/companies/oleg-bunin/articles/348172/
  3. Первичный ключ и внешний ключ: 9 важных отличий: https://www.astera.com/ru/type/blog/primary-key-vs-foreign-key/