Уникальные индексы: UNIQUE INDEX

Что такое UNIQUE INDEX и зачем он нужен? 🔍

UNIQUE INDEX — это особый тип индекса в SQL, который не только ускоряет поиск данных, но и гарантирует уникальность значений в столбце (или группе столбцов).

Почему это важно?

Представьте базу данных интернет-магазина:

  • Два пользователя с одинаковыми email — катастрофа для авторизации ❌
  • Дубликаты артикулов товаров — хаос в каталоге 🛒
  • Повторяющиеся номера заказов — финансовый кошмар 💸

UNIQUE INDEX решает эти проблемы элегантно и эффективно.

-- Пример создания уникального индекса для email пользователей
CREATE UNIQUE INDEX idx_unique_email ON users(email);

Как работает UNIQUE INDEX под капотом? ⚙️

Технически это B-дерево (как и обычный индекс), но с дополнительной проверкой:

  1. При вставке/обновлении СУБД проверяет значение на уникальность
  2. При нарушении — операция отклоняется с ошибкой
  3. Оптимизатор запросов использует индекс для быстрого поиска

Интересный факт:
В PostgreSQL при создании PRIMARY KEY автоматически создаётся UNIQUE INDEX с тем же именем!


Разбираем на примерах: от простого к сложному 🏗️

Базовый вариант (один столбец)

-- Для таблицы сотрудников (никто не должен "делиться" табельным номером)
CREATE UNIQUE INDEX idx_unique_employee_code ON employees(employee_code);

Составной индекс (несколько столбцов)

-- В университете: уникальная комбинация номера группы и порядкового номера студента
CREATE UNIQUE INDEX idx_unique_student_id ON students(group_id, student_number);

Частичный уникальный индекс (только для некоторых строк)

-- Для архивированных заказов разрешаем дубли, для активных — нет
CREATE UNIQUE INDEX idx_unique_active_order ON orders(order_number)
WHERE status != 'archived';

Ошибки и как их избежать 🚨

Типичные грабли:

-- 1. NULL-значения считаются разными (в большинстве СУБД)
INSERT INTO products (sku, name) VALUES (NULL, 'Товар 1'); -- ОК
INSERT INTO products (sku, name) VALUES (NULL, 'Товар 2'); -- Тоже ОК!

-- Решение: добавить NOT NULL или использовать COALESCE
CREATE UNIQUE INDEX idx_sku_not_null ON products(COALESCE(sku, ''));

-- 2. Неочевидные дубли при разных регистрах (зависит от COLLATION)
CREATE UNIQUE INDEX idx_unique_name ON users(username); 
INSERT INTO users VALUES ('Admin'), ('admin'); -- Ошибка или нет?

-- Решение: явно указывать COLLATION
CREATE UNIQUE INDEX idx_unique_name_ci ON users(username COLLATE utf8mb4_bin);

Производительность: скрытые нюансы ⚡

UNIQUE INDEX обычно быстрее обычного, потому что:

  • СУБД может остановить проверку при первом совпадении
  • Часто используется для точных поисков (WHERE x = 123)

Лайфхак:
Если столбец уже имеет UNIQUE INDEX, не создавайте для него обычный — это пустая трата ресурсов.

-- Так делать не нужно!
CREATE INDEX idx_email ON users(email); -- Избыточно, если есть UNIQUE INDEX

Практическое задание 🛠️

1. Создайте таблицу для хранения ISBN книг с гарантией уникальности:

CREATE TABLE books (
    id SERIAL PRIMARY KEY,
    isbn VARCHAR(13) NOT NULL,
    title VARCHAR(255) NOT NULL
);

CREATE UNIQUE INDEX idx_unique_isbn ON books(isbn);

2. Попробуйте вставить дубликат и поймайте ошибку:

INSERT INTO books (isbn, title) VALUES 
    ('978-3-16-148410-0', 'Чистый код'),
    ('978-3-16-148410-0', 'Пиратская копия'); -- Будет ошибка

3. Добавьте составной индекс для автора и названия (чтобы один автор не мог выпустить две одинаковые книги):

CREATE UNIQUE INDEX idx_unique_author_title ON books(author_id, title);

Когда UNIQUE INDEX — не лучший выбор 🤔

Альтернативы:

  1. PRIMARY KEY — если нужен уникальный идентификатор
  2. Обычный INDEX + триггеры — для сложных правил уникальности
  3. Ограничение CHECK — для простых условий

Золотое правило:

Используйте UNIQUE INDEX, когда важно и ускорение поиска, и контроль уникальности. Для только уникальности лучше UNIQUE CONSTRAINT (они часто реализуются через UNIQUE INDEX, но семантически правильнее).


Фишка напоследок:
В некоторых СУБД можно создать отложенную проверку уникальности (DEFERRED), которая сработает только при коммите транзакции — полезно для сложных операций!

Скрыть рекламу навсегда

📘 VK Видео — обучение без ограничений

Все уроки доступны без VPN, без блокировок и зависаний.

Можно смотреть с телефона, планшета или компьютера — в любое время.

▶️ Смотреть на VK Видео