Можно ли создать таблицу в реляционной БД без первичного ключа (PRIMARY KEY)?

«Можно ли создать таблицу в реляционной БД без первичного ключа (PRIMARY KEY)?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, технически можно, но это крайне не рекомендуется для большинства практических случаев. Стандарт SQL не требует обязательного наличия первичного ключа.

Пример создания таблицы без PRIMARY KEY:

CREATE TABLE log_entries (
    timestamp TIMESTAMP,
    message TEXT,
    severity VARCHAR(10)
);
-- Таблица создана, но строки нельзя однозначно идентифицировать.

Почему PRIMARY KEY важен:

  • Уникальная идентификация: Гарантирует, что каждая строка уникальна.
  • Индексирование: Автоматически создает clustered или unique индекс, что резко ускоряет поиск, соединения (JOIN) и операции обновления/удаления.
  • Целостность данных: Предотвращает дублирование строк.
  • Требование ORM: Фреймворки вроде Hibernate/JPA обязательно требуют первичный ключ (@Id) для сущности.

Проблемы при отсутствии PRIMARY KEY:

  1. Невозможность однозначного обращения к строке. Запрос UPDATE ... WHERE ... может затронуть несколько одинаковых строк.
  2. Низкая производительность последовательных сканирований (full table scans) вместо поиска по индексу.
  3. Сложности с репликацией и некоторыми инструментами резервного копирования.

Когда можно обойтись без PK (редкие случаи):

  • Временные таблицы-буферы.
  • Таблицы для хранения логов, где дублирование допустимо, а выборка всегда идет по дате (тогда нужен индекс по timestamp).
  • Статические справочники, которые только читаются и никогда не обновляются по отдельным строкам.

Рекомендация: Почти всегда определяйте первичный ключ. Если нет естественного ключа, используйте суррогатный (например, SERIAL/BIGSERIAL в PostgreSQL, AUTO_INCREMENT в MySQL).