← Назад к вопросам

Подвергается ли индексации Primary Key

2.2 Middle🔥 151 комментариев
#Другое

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Подвергается ли индексации Primary Key

Прямой ответ: ДА! Primary Key автоматически индексируется в любой RDBMS (MySQL, PostgreSQL, Oracle, SQL Server). Это одно из фундаментальных правил баз данных, которое критично для собеседования.

Почему Primary Key всегда индексируется

Primary Key гарантирует:

  • Уникальность — не может быть двух строк с одинаковым PK
  • Быстрый поиск — нужен для эффективного JOIN'а и фильтрации
  • Ссылочная целостность — Foreign Key указывают на PK

Всё это требует индекса.

Как это работает на практике

SQL:

-- При создании таблицы с PRIMARY KEY
CREATE TABLE users (
    id INT PRIMARY KEY,  -- Автоматически индексируется!
    name VARCHAR(100),
    email VARCHAR(100) UNIQUE  -- Этот индекс создается отдельно
);

-- Это эквивалентно:
CREATE TABLE users (
    id INT,
    name VARCHAR(100),
    email VARCHAR(100) UNIQUE,
    PRIMARY KEY (id)
    -- Индекс на id создается автоматически
);

В PostgreSQL:

CREATE TABLE users (
    id SERIAL PRIMARY KEY,  -- Индекс создается автоматически
    name VARCHAR(100)
);

-- Проверить индексы
\d users

-- Output:
-- ...
-- Indexes:
--     "users_pkey" PRIMARY KEY, btree (id)

В MySQL:

CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,  -- Индекс автоматический
    name VARCHAR(100)
);

-- Проверить индексы
SHOW INDEXES FROM users;

-- Output:
-- Table | Non_unique | Key_name | Seq_in_index | Column_name
-- users | 0          | PRIMARY  | 1            | id

Типы индексов для PRIMARY KEY

B-Tree (по умолчанию)

Это стандартный индекс для PRIMARY KEY. Он обеспечивает O(log n) поиск:

Б-дерево:
        [5]
       /   \
     [2]   [8]
    /  \   /  \
  [1] [3][6] [9]

Поиск id=6:

  • Начинаем с корня: 6 > 5, идем вправо
  • Ищем в [8]: 6 < 8, идем влево
  • Находим [6]

Примерная сложность: O(log n) вместо O(n) полного сканирования

На Java это выглядит так

import jakarta.persistence.*;

@Entity
@Table(name = "users")
public class User {
    @Id  // Это PRIMARY KEY
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;  // Этот поле автоматически индексируется!
    
    @Column(name = "name")
    private String name;
    
    @Column(name = "email", unique = true)
    private String email;  // Этот индекс создается ОТДЕЛЬНО
}

// Hibernate/JPA автоматически создает индекс на id (PRIMARY KEY)
// Это соответствует @Id аннотации

Практические примеры

Пример 1: Поиск по Primary Key

-- Этот запрос использует индекс PRIMARY KEY
SELECT * FROM users WHERE id = 5;

-- Выполнение:
-- Index lookup на B-Tree индексе -> O(log n)
-- Очень быстро!

Пример 2: JOIN с использованием PRIMARY KEY

SELECT u.name, o.total
FROM users u
JOIN orders o ON u.id = o.user_id;

-- Выполнение:
-- 1. Сканируем таблицу orders
-- 2. Для каждого row в orders используем индекс PRIMARY KEY на users.id
-- 3. Это эффективно благодаря индексу!

Пример 3: Индекс есть, он работает

-- Посмотрить план выполнения (PostgreSQL)
EXPLAIN SELECT * FROM users WHERE id = 5;

-- Output:
-- Seq Scan on users  (cost=0.00..35.50 rows=1 width=100)
--   Filter: (id = 5)
-- ИЛИ (если база знает, что есть индекс):
-- Index Scan using users_pkey on users  (cost=0.29..8.30 rows=1 width=100)
--   Index Cond: (id = 5)

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

Performance:

// Плохой запрос (без использования PK индекса)
public User findUserByName(String name) {
    // SELECT * FROM users WHERE name = 'John'
    // Сканирует ВСЮ таблицу -> O(n) -> МЕДЛЕННО
    return repository.findByName(name);
}

// Хороший запрос (использует PK индекс)
public User findUserById(Long id) {
    // SELECT * FROM users WHERE id = 1
    // Использует индекс PRIMARY KEY -> O(log n) -> БЫСТРО
    return repository.findById(id);
}

// Если нужно часто искать по имени, создайте индекс:
// CREATE INDEX idx_users_name ON users(name);

Может ли быть PRIMARY KEY без индекса

В классических RDBMS: НЕТ

Индекс на PRIMARY KEY создается ОБЯЗАТЕЛЬНО. Это часть определения PRIMARY KEY.

В NoSQL (например, MongoDB): МОЖЕТ БЫТЬ

Alternatively, some NoSQL databases don't automatically index _id:

// MongoDB
db.users.createIndex({ _id: 1 });  // Можно создать индекс явно

Иерархия индексов

Индексы в таблице
├── PRIMARY KEY индекс (обязательно, автоматически)
│   └── B-Tree, O(log n) поиск
├── UNIQUE индексы (если добавлены)
│   └── B-Tree, обеспечивают уникальность
└── Обычные индексы (если создали явно)
    └── B-Tree, B+ Tree, Hash, Full-text

На собеседовании

Вопросы, которые могут задать:

  1. "Индексируется ли PRIMARY KEY?"

    • Ответ: Да, всегда
  2. "Какой тип индекса используется?"

    • Ответ: По умолчанию B-Tree
  3. "Почему нельзя иметь PRIMARY KEY без индекса?"

    • Ответ: Потому что нужна гарантия уникальности и быстрого поиска
  4. "Какая сложность поиска по PRIMARY KEY?"

    • Ответ: O(log n) благодаря B-Tree индексу
  5. "Можно ли отключить индекс на PRIMARY KEY?"

    • Ответ: НЕТ, это технически невозможно

Практический совет

-- ВСЕГДА используйте PRIMARY KEY для таблиц
CREATE TABLE users (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,  -- ✅ Правильно
    email VARCHAR(255) UNIQUE NOT NULL,    -- Индекс тоже создается
    name VARCHAR(100) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Дополнительные индексы для часто используемых фильтров
CREATE INDEX idx_email ON users(email);
CREATE INDEX idx_created_at ON users(created_at);

Заключение

PRIMARY KEY ВСЕГДА индексируется в любой реляционной базе данных:

  • ✅ MySQL — автоматически
  • ✅ PostgreSQL — автоматически
  • ✅ Oracle — автоматически
  • ✅ SQL Server — автоматически

Это базовое правило баз данных, которое на собеседовании для Java Developer ожидают, что вы будете знать.