Какие типы ключей (constraints) существуют в SQL?

«Какие типы ключей (constraints) существуют в SQL?» — вопрос из категории Базы данных, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В 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 - бизнес-правила, а индексы - производительность.