Fox7777
@Fox7777
Люблю python

Как правильно использовать составные первичные ключи в таблицах?

вопрос по поводу использования составных первичных ключей (PRIMARY KEY, состоящий из двух и более колонок) в таблицах баз данных.
разрабатываю проект, в котором требуется связывать несколько таблиц между собой через промежуточные таблицы. Например, есть таблицы Staff, Services и промежуточная таблица StaffServices, которая связывает сотрудников с услугами, которые они предоставляют. Вот пример структуры таблицы:
CREATE TABLE StaffServices (
    staffId INT,
    serviceId INT,
    PRIMARY KEY (staffId, serviceId),
    FOREIGN KEY (staffId) REFERENCES Staff(id),
    FOREIGN KEY (serviceId) REFERENCES Services(id)
);

Также есть аналогичные промежуточные таблицы для связи между другими сущностями:
CREATE TABLE StaffBusiness (
    staffId INT,
    businessId INT,
    PRIMARY KEY (staffId, businessId),
    FOREIGN KEY (staffId) REFERENCES Staff(id),
    FOREIGN KEY (businessId) REFERENCES Businesses(id)
);

CREATE TABLE StaffBusinessSchedules (
    staffId INT,
    businessId INT,
    scheduleId INT,
    PRIMARY KEY (staffId, businessId, scheduleId),
    FOREIGN KEY (staffId) REFERENCES Staff(id),
    FOREIGN KEY (businessId) REFERENCES Businesses(id),
    FOREIGN KEY (scheduleId) REFERENCES Schedules(id)
);

  1. Насколько правильным и общепринятым является использование составных первичных ключей в таких случаях?
  2. Какие могут быть плюсы и минусы данного подхода?
  3. Есть ли альтернативы, которые стоит рассмотреть в подобных ситуациях?
  4. Как это влияет на производительность базы данных и целостность данных?
  5. Какие best practices существуют для таких случаев?
  6. Буду рад услышать ваши мнения и советы!
  • Вопрос задан
  • 102 просмотра
Решения вопроса 1
ThunderCat
@ThunderCat
{PHP, MySql, HTML, JS, CSS} developer
0)
Staff, Services и промежуточная таблица StaffServices
https://brainstation.io/learn/sql/naming-conventions , https://www.sqlshack.com/learn-sql-naming-conventions/

1)
Насколько правильным и общепринятым является использование составных первичных ключей в таких случаях?
В общем случае это неверный подход, отдельный id для каждой сущности, включая пивоты, является хорошим тоном.

2)
Какие могут быть плюсы и минусы данного подхода?
Да нет тут плюсов. Уникальность записи через 2 значения даже из приложения юзать неудобно, особенно когда работаешь с фреймворками, которые соблюдают какой-никакой конвеншн.

3)
Есть ли альтернативы, которые стоит рассмотреть в подобных ситуациях?
Нормальный первичный ключ через автоинкремент и уник на составной.

4)
Как это влияет на производительность базы данных и целостность данных?
Зависит. Если внешние ключи настроены правильно, то консистентность бд будет гарантироваться правилами ключей (в рамках их описания конечно), отсюда все вытекающие, которые сильно зависят от остального построения связей. Производительность будет сильно зависеть от конкретной насторйки бд, машины/образа, но в основном от количества записей, так то движку фиолетово какие индексы использовать, главное чтобы они были.

5)
Какие best practices существуют для таких случаев?
Собсно выше основное описал.

6)
Буду рад услышать ваши мнения и советы!
Велком.
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
@Everything_is_bad
По опыту, в подавляющем большинстве случаев, используют суррогатный первичный ключ, а если хочешь именно составной первичный ключ, ты точно должно понимать и главное доказать, почему нужен именно он.
Ответ написан
Комментировать
@Tannenfels
Объясните, зачем вам потребовался составной первичный ключ? Он абсолютно излишен тут.
Ответ написан
Комментировать
@mvv-rus
Настоящий админ AD и ненастоящий программист
Хоть помеченный ответ уже есть, но лучше поздно, чем никогда.
Ответ на вопрос зависит от того, являются ли ли эти таблицы отображением самостоятельных сущностей или просто реализацией связи "многие-ко-многим". Понять, являются ли эти таблицы сущностями, можно ответив себе на простой вопрос: есть ли и будут ли у этих кандидатов в сущности какие-либо атрибуты, которые зависят сразу от комбинации PK обеих связываемых таблиц с сущностями. Если ответ на это вопрос - "нет", то эти таблицы самостоятельных сущностей не содержат а потому составной первичный ключ для них - правильное решение, хотя и вопреки существующей моде.
Если же такие атрибуты есть или, хотя бы, допускаются, то к этим таблицам надо относиться как к таблицам для сущностей, и здесь суррогатный первичный ключ может оказаться полезен.

PS Вообще, при выборе решения надо исходить из условия задачи, а не из соответствия решения какому-нибудь "единственно верному учению", или из текущей моды AKA "best practices".

PPS Разницы по скорости вы, скорее всего не заметите.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы