Создается ли индекс автоматически при объявлении первичного ключа (PRIMARY KEY)?

Ответ

Да, в подавляющем большинстве реляционных СУБД при создании ограничения PRIMARY KEY автоматически создается уникальный индекс. Это необходимо для обеспечения уникальности и быстрого поиска по первичному ключу.

Как это работает в разных СУБД:

  • MySQL / PostgreSQL / SQLite: Создается UNIQUE INDEX с тем же именем, что и у первичного ключа.
    CREATE TABLE users (
        id INT PRIMARY KEY, -- Автоматически создаст уникальный индекс на id
        name VARCHAR(100)
    );
  • Oracle: Также автоматически создается уникальный индекс. Можно явно указать табличное пространство для индекса.
  • SQL Server: По умолчанию создается кластерный индекс (clustered index), что означает, что данные в таблице физически упорядочены по первичному ключу. Это можно изменить, указав NONCLUSTERED.
    CREATE TABLE users (
        id INT PRIMARY KEY NONCLUSTERED, -- Явно создаст некластерный индекс
        name VARCHAR(100)
    );

Практические следствия:

  1. Не создавайте индекс вручную: Дополнительный индекс CREATE INDEX idx_id ON users(id) будет избыточным и станет бесполезной нагрузкой на систему при вставке/обновлении.
  2. В JPA/Hibernate: При использовании @Id или @EmbeddedId для определения первичного ключа, создаваемая схема БД также будет содержать соответствующий индекс (если DDL-генерация включена).
  3. Составной первичный ключ: Для PRIMARY KEY (col1, col2) также создается составной уникальный индекс на (col1, col2).

Исключение: Некоторые СУБД (как старые версии) или особые конфигурации могут требовать явного создания индекса, но в современной Java-экосистеме это крайне редкий случай.

Ответ 18+ 🔞

А, ну вот, классика жанра! Сидишь такой, думаешь: "А не создать ли мне индекс на первичный ключ, для скорости?" А потом оказывается, что ты уже в десятой степени еблан, потому что индекс там УЖЕ ЕСТЬ, блядь!

Слушай сюда, расписываю по полочкам, чтобы в голове осело, а не как у мартышлюшки.

Короче, да, ёпта. В 99.9% случаев, когда ты пишешь PRIMARY KEY, база данных, не спрашивая твоего высочайшего разрешения, тупо создаёт уникальный индекс на эту колонку (или колонки). Зачем? Ну, бля, логично же: чтобы быстро проверять, уникален ли новый вставляемый ключ, и чтобы по нему так же быстро искать. Без индекса это был бы пиздец, а не поиск.

А вот как эта магия выглядит в разных конторах:

  • MySQL, PostgreSQL, SQLite: Просто берут и лепят UNIQUE INDEX с таким же именем, как у ключа. Никаких тебе церемоний.
    CREATE TABLE users (
        id INT PRIMARY KEY, -- Система уже шепчет: "Индекс? Сделано, ёпта!"
        name VARCHAR(100)
    );
  • Oracle: Тоже самое, только может с важным видом спросить про табличное пространство для этого индекса.
  • SQL Server: А вот эти ребята оригинальничают. По умолчанию они создают кластерный индекс (clustered index). Это значит, что все строки в таблице физически лежат в порядке возрастания первичного ключа. Представь, что ты сортируешь папки в шкафу по номеру — вот это оно. Но если тебе не нравится, можешь сказать NONCLUSTERED, и будет обычный, некластерный индекс.
    CREATE TABLE users (
        id INT PRIMARY KEY NONCLUSTERED, -- Явно говорим: "Не кластеризуй, мудила!"
        name VARCHAR(100)
    );

А теперь практические выводы, чтобы не облажаться:

  1. Не выёбывайся лишний раз. Если ты после создания PRIMARY KEY напишешь CREATE INDEX idx_id ON users(id), то ты создашь второй, абсолютно такой же и нахуй не нужный индекс. Зачем? Чтобы база зря тратила силы на его поддержку при каждой вставке? Ты чё, садомазохист?
  2. В мире JPA/Hibernate (а ты ж джавист, я смотрю) — та же фигня. Поставил @Id на поле, и когда хибер генерит схему, он автоматом прилепляет и индекс. Расслабься.
  3. Составной ключ — тоже не проблема. PRIMARY KEY (col1, col2) породит составной индекс на (col1, col2). Всё логично, как дважды два.

Исключения? Ну, теоретически, в каких-нибудь древних или дико кастомизированных системах может и не быть. Но в нормальной, современной Java-практике — это из разряда "увидеть единорога". Так что не парься и не плоди сущностей сверх необходимого, а то овердохуища индексов потом понаделаешь!