Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Подвергается ли индексации 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
На собеседовании
Вопросы, которые могут задать:
-
"Индексируется ли PRIMARY KEY?"
- Ответ: Да, всегда
-
"Какой тип индекса используется?"
- Ответ: По умолчанию B-Tree
-
"Почему нельзя иметь PRIMARY KEY без индекса?"
- Ответ: Потому что нужна гарантия уникальности и быстрого поиска
-
"Какая сложность поиска по PRIMARY KEY?"
- Ответ: O(log n) благодаря B-Tree индексу
-
"Можно ли отключить индекс на 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 ожидают, что вы будете знать.