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

Создавал ли таблицу без primary key

2.3 Middle🔥 111 комментариев
#Python Core

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

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

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

Таблицы без primary key

Что говорит практика

Да, в реальных проектах иногда создаются таблицы без явно определённого primary key. Однако это редко бывает хорошей идеей, и я расскажу почему.

Когда таблицы создаются без primary key

Исторические системы и легаси-код — многие старые базы данных были спроектированы без строгих ограничений, и миграция затратна.

Промежуточные таблицы логирования — например, таблица событий может создаться без PK для простоты:

# SQL для таблицы событий без PK
CREATE TABLE event_log (
    event_id UUID,
    user_id UUID,
    action VARCHAR(255),
    created_at TIMESTAMPTZ
);

Join таблицы со сложным ключом — иногда разработчики забывают добавить PK:

CREATE TABLE user_permissions (
    user_id UUID,
    permission_id UUID,
    granted_at TIMESTAMPTZ
);

Проблемы без primary key

1. Дубликаты строк — база позволяет вставить одинаковые записи:

INSERT INTO user_permissions (user_id, permission_id) 
VALUES (123, 456);

INSERT INTO user_permissions (user_id, permission_id) 
VALUES (123, 456);  -- ДОПУСТИМО, если нет PK

2. Неэффективные обновления — UPDATE без PK может затрагивать множество строк:

# Опасно! Может обновить все строки пользователя
UPDATE user_permissions 
SET granted_at = NOW() 
WHERE user_id = 123;

3. Проблемы с индексацией — без PK сложнее оптимизировать запросы.

4. Невозможность уникально идентифицировать строку — для удаления или обновления одной конкретной строки.

5. Внешние ключи — другие таблицы не могут ссылаться на строку без уникального идентификатора:

CREATE TABLE user_permission_audit (
    id SERIAL PRIMARY KEY,
    permission_id UUID,
    FOREIGN KEY (permission_id) REFERENCES user_permissions(???)  -- На что ссылаться?
);

Правильный подход

Всегда добавляй primary key:

CREATE TABLE user_permissions (
    id SERIAL PRIMARY KEY,
    user_id UUID NOT NULL,
    permission_id UUID NOT NULL,
    granted_at TIMESTAMPTZ NOT NULL,
    UNIQUE(user_id, permission_id)  -- Гарантируем уникальность
);

Или для UUID:

CREATE TABLE user_permissions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL,
    permission_id UUID NOT NULL,
    granted_at TIMESTAMPTZ NOT NULL,
    UNIQUE(user_id, permission_id)
);

Вывод

Таблицы без primary key — это признак плохого дизайна. Даже для промежуточных таблиц или логов рекомендуется добавлять PK. Это требует дополнительное место в памяти, но гарантирует целостность данных и позволяет корректно работать с остальной системой.

Если ты наследуешь легаси-базу без PK — начни с добавления их постепенно, начиная с критичных таблиц.