Ответ
Да, в подавляющем большинстве реляционных СУБД при создании ограничения 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) );
Практические следствия:
- Не создавайте индекс вручную: Дополнительный индекс
CREATE INDEX idx_id ON users(id)будет избыточным и станет бесполезной нагрузкой на систему при вставке/обновлении. - В JPA/Hibernate: При использовании
@Idили@EmbeddedIdдля определения первичного ключа, создаваемая схема БД также будет содержать соответствующий индекс (если DDL-генерация включена). - Составной первичный ключ: Для
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) );
А теперь практические выводы, чтобы не облажаться:
- Не выёбывайся лишний раз. Если ты после создания
PRIMARY KEYнапишешьCREATE INDEX idx_id ON users(id), то ты создашь второй, абсолютно такой же и нахуй не нужный индекс. Зачем? Чтобы база зря тратила силы на его поддержку при каждой вставке? Ты чё, садомазохист? - В мире JPA/Hibernate (а ты ж джавист, я смотрю) — та же фигня. Поставил
@Idна поле, и когда хибер генерит схему, он автоматом прилепляет и индекс. Расслабься. - Составной ключ — тоже не проблема.
PRIMARY KEY (col1, col2)породит составной индекс на(col1, col2). Всё логично, как дважды два.
Исключения? Ну, теоретически, в каких-нибудь древних или дико кастомизированных системах может и не быть. Но в нормальной, современной Java-практике — это из разряда "увидеть единорога". Так что не парься и не плоди сущностей сверх необходимого, а то овердохуища индексов потом понаделаешь!