Ответ
В SQL используются следующие типы ограничений (ключей), которые обеспечивают целостность данных и определяют отношения между таблицами:
1. PRIMARY KEY (Первичный ключ)
- Уникально идентифицирует каждую запись в таблице
- Не может содержать
NULLзначения - В таблице может быть только один первичный ключ
- Часто используется с
AUTO_INCREMENTдля автоматической генерации значений
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL
);
2. FOREIGN KEY (Внешний ключ)
- Создает связь между двумя таблицами
- Обеспечивает ссылочную целостность (нельзя удалить запись, на которую есть ссылки)
- Значение должно существовать в связанной таблице или быть
NULL
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT,
amount DECIMAL(10,2),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
3. UNIQUE (Уникальный ключ)
- Гарантирует уникальность значений в столбце или группе столбцов
- Отличается от PRIMARY KEY тем, что может содержать
NULLзначения (в большинстве СУБД только одинNULL) - В таблице может быть несколько UNIQUE ограничений
CREATE TABLE employees (
id INT PRIMARY KEY,
email VARCHAR(100) UNIQUE, -- Уникальный email
phone VARCHAR(20) UNIQUE -- Уникальный телефон
);
4. CHECK (Проверочное ограничение)
- Проверяет условие перед вставкой или обновлением данных
- Обеспечивает бизнес-логику на уровне базы данных
CREATE TABLE products (
id INT PRIMARY KEY,
price DECIMAL(10,2) CHECK (price > 0),
quantity INT CHECK (quantity >= 0),
category VARCHAR(50) CHECK (category IN ('Electronics', 'Books', 'Clothing'))
);
5. NOT NULL (Запрет NULL)
- Требует, чтобы столбец всегда содержал значение
- Хотя технически это не "ключ", но важное ограничение целостности
CREATE TABLE customers (
id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
registration_date DATE NOT NULL DEFAULT CURRENT_DATE
);
6. INDEX (Индекс)
- Хотя индекс не является ограничением в строгом смысле, он часто упоминается вместе с ключами
- Ускоряет поиск и сортировку, но замедляет вставку и обновление
- Может быть уникальным (
UNIQUE INDEX) или неуникальным
-- Создание индекса для ускорения поиска по email
CREATE INDEX idx_email ON users(email);
-- Составной индекс для поиска по имени и фамилии
CREATE INDEX idx_name ON users(last_name, first_name);
Практический пример с несколькими ограничениями:
CREATE TABLE library_books (
book_id INT PRIMARY KEY AUTO_INCREMENT,
isbn VARCHAR(13) UNIQUE NOT NULL,
title VARCHAR(200) NOT NULL,
author_id INT NOT NULL,
published_year INT CHECK (published_year >= 1450 AND published_year <= YEAR(CURDATE())),
available_copies INT DEFAULT 1 CHECK (available_copies >= 0),
FOREIGN KEY (author_id) REFERENCES authors(author_id) ON DELETE RESTRICT,
INDEX idx_title (title),
INDEX idx_author_year (author_id, published_year)
);
Каждый тип ключа решает конкретную задачу: PRIMARY KEY обеспечивает идентификацию, FOREIGN KEY - связи между таблицами, UNIQUE и CHECK - бизнес-правила, а индексы - производительность.
Ответ 18+ 🔞
А, слушай, вот про SQL ключи рассказывать — это как объяснять, зачем в машине тормоза. Без них поедет, конечно, но потом охуеешь на первом же повороте, когда в дерево врежешься. Так что давай по порядку, а то чувствую, тут удивление пиздец может наступить, если не разобраться.
1. PRIMARY KEY (Первичный ключ)
Это типа твой паспорт в таблице. Без него ты — манда с ушами, никто тебя не узнает. Он должен быть уникальным, не может быть пустым (никаких NULL, блядь), и на всю таблицу такой ключ — один, как царь в государстве. Часто его делают с AUTO_INCREMENT, чтобы он сам себе номера придумывал, а ты не парился.
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL
);
2. FOREIGN KEY (Внешний ключ) Вот это уже связь между таблицами, ёпта. Как верёвка, которая привязывает одну к другой. Нельзя удалить запись в главной таблице, если на неё где-то ссылаются — иначе получится хуй в пальто, данные посыпятся. Либо каскадом удалит всё связанное, либо запретит — как настроишь.
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT,
amount DECIMAL(10,2),
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
3. UNIQUE (Уникальный ключ) Тоже уникальность, но не такая строгая, как у первичного ключа. Может быть NULL (хотя обычно один), и таких ограничений можно навесить овердохуища. Например, чтобы почта или телефон не повторялись у разных людей. А то представь: два чувака с одинаковой почтой — доверия ебать ноль к такой системе.
CREATE TABLE employees (
id INT PRIMARY KEY,
email VARCHAR(100) UNIQUE,
phone VARCHAR(20) UNIQUE
);
4. CHECK (Проверочное ограничение) Это твой внутренний голос, который говорит: «Мужик, не надо так». Проверяет данные перед тем, как их запихнуть в таблицу. Цена не может быть отрицательной, количество товара — меньше нуля, категория должна быть из списка. Короче, бизнес-логика прямо в базе, чтобы с клиентской части не прилетела какая-нибудь хитрая жопа с минусовой ценой.
CREATE TABLE products (
id INT PRIMARY KEY,
price DECIMAL(10,2) CHECK (price > 0),
quantity INT CHECK (quantity >= 0),
category VARCHAR(50) CHECK (category IN ('Electronics', 'Books', 'Clothing'))
);
5. NOT NULL (Запрет NULL) Технически не ключ, но ограничение важное, бля. Просто говорит: «Это поле должно быть заполнено, идиот». Без имени пользователь? Да похуй, не регистрируйся тогда. Дата регистрации? Ставь текущую автоматом, но пустой не оставляй.
CREATE TABLE customers (
id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
registration_date DATE NOT NULL DEFAULT CURRENT_DATE
);
6. INDEX (Индекс) А вот это магия производительности, ёбать мои старые костыли. Сам по себе не ограничивает данные, но ускоряет поиск по ним в разы. Правда, за это придётся платить: вставка и обновление будут чуть медленнее, потому что индекс тоже надо поддерживать. Но без него на больших таблицах запросы будут идти как черепаха в сиропе — терпения ноль ебать.
CREATE INDEX idx_email ON users(email);
CREATE INDEX idx_name ON users(last_name, first_name);
Ну и пример, где всё вместе, как в хорошем борще:
CREATE TABLE library_books (
book_id INT PRIMARY KEY AUTO_INCREMENT,
isbn VARCHAR(13) UNIQUE NOT NULL,
title VARCHAR(200) NOT NULL,
author_id INT NOT NULL,
published_year INT CHECK (published_year >= 1450 AND published_year <= YEAR(CURDATE())),
available_copies INT DEFAULT 1 CHECK (available_copies >= 0),
FOREIGN KEY (author_id) REFERENCES authors(author_id) ON DELETE RESTRICT,
INDEX idx_title (title),
INDEX idx_author_year (author_id, published_year)
);
Короче, каждый ключ — как инструмент в мастерской. Первичный — это молоток, без него вообще нихуя не соберёшь. Внешний — отвёртка, скрепляет детали. Уникальный и CHECK — это уровень и уголок, чтобы ровно делать. А индексы — это шуруповёрт, чтобы быстрее закручивать. Используй с умом, и база будет летать, а не ползать, как мартышлюшка пьяная.