Можно ли вставить дублирующую запись в столбец с PRIMARY KEY?

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

Ответ

Нет, вставка дубликата значения в столбец, объявленный как PRIMARY KEY (или UNIQUE), приведет к ошибке нарушения ограничения целостности (constraint violation).

Поведение СУБД: При попытке такой вставки СУБД отклонит операцию и выбросит исключение.

  • В Java (JDBC) это будет SQLIntegrityConstraintViolationException.
  • В PostgreSQL часто сопровождается кодом ошибки 23505 (unique_violation).
  • В MySQL — кодом ошибки 1062 (Duplicate entry).

Пример (JDBC):

String sql = "INSERT INTO users (id, name) VALUES (?, ?)"; // 'id' - PRIMARY KEY
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
    pstmt.setInt(1, 1);
    pstmt.setString(2, "Alice");
    pstmt.executeUpdate(); // Успешная вставка первой записи.

    pstmt.setInt(1, 1); // То же самое значение PK!
    pstmt.setString(2, "Bob");
    pstmt.executeUpdate(); // ВЫБРОСИТ SQLIntegrityConstraintViolationException
} catch (SQLIntegrityConstraintViolationException e) {
    System.err.println("Duplicate primary key: " + e.getMessage());
}

Стратегии обработки дубликатов (UPSERT): Для безопасной вставки или обновления при конфликте ключей используются специальные конструкции:

  1. PostgreSQL / SQLite: INSERT ... ON CONFLICT (id) DO UPDATE SET ...
  2. MySQL: INSERT ... ON DUPLICATE KEY UPDATE ...
  3. SQL Server / Oracle: Использование MERGE statement.

Пример для PostgreSQL:

INSERT INTO users (id, name)
VALUES (1, 'Bob')
ON CONFLICT (id)
DO UPDATE SET name = EXCLUDED.name; -- Если запись с id=1 есть, обновит имя на 'Bob'.

Вывод: PRIMARY KEY гарантирует уникальность. Попытка вставить дубликат вызывает ошибку, которую необходимо обрабатывать на уровне приложения или использовать UPSERT-операции.