Внешний ключ как первичный ключ или просто отдельный суррогатный первичный ключ, отличный от внешнего ключа в контексте JPA

Какова лучшая практика для использования FK в качестве PK или использования суррогатных PK и FK в качестве FK в контексте JPA? Я видел, как несколько раз люди говорили, что им нужно отобразить FK как PK, потому что у них была устаревшая база данных. Значит ли это, что для новых таблиц, если у вас есть контроль над их созданием, лучше использовать следующую структуру:

TABLE_1
-------
ID (PK)
...

TABLE_2
-------
ID (PK) 
TABLE_1_ID (FK)

вместо:

TABLE_2
-------
TABLE_1_ID (PK) and (FK)

3 ответа

Для отношений один-на-один всегда используйте первую представленную вами альтернативу.

Для некоторых отношений один-к-одному таблицы могут быть объединены без вредных последствий.

Ваш второй вариант действительно становится полезным при реализации иерархий суперклассов-подклассов с использованием модели наследования таблиц классов, представленной Мартином Фаулером. В этом случае вы хотите, чтобы таблицы подклассов отличались от таблиц суперкласса, чтобы уменьшить количество NULLS. Но отношения один на один.

Создавая ту же функцию ключа, что и для PK, и для FK в таблицах подклассов, и заставляя FK ссылаться на совпадающую запись в таблице суперклассов, это упрощает объединение специализированных данных с обобщенными данными, когда это необходимо. Это можно назвать "наследством бедняка".

Я думаю, вы ищете @MapsId аннотаций.

В этом конкретном случае (отношение от 1 до 0..1) рассмотрите возможность объединения двух таблиц в одну.

Если они разделены преднамеренно (например, для "вертикального" разделения), предпочтите одно и то же поле как PK, так и FK.

Рассмотрите возможность добавления еще одного ключа, только если вы можете сделать его меньше 1, но уравновесите его с необходимостью дополнительного индекса 2, потенциальной враждебностью к кластеризации 3 и необходимостью моделирования ромбовидных зависимостей 4.


1 Например, потому что TABLE_2.TABLE_1_ID строка, и вы можете сделать TABLE_2.ID целое число.

2 Каждый новый индекс замедляет INSERT и может замедлять UPDATE и DELETE в зависимости от их предложения WHERE. Кроме того, любые дополнительные данные оказывают дополнительное давление на кэш, делая его "меньшим".

3 Вторичный индекс в кластерной таблице должен содержать копию PK и может вызывать двойной поиск (сначала для индекса, а затем для PK) при поиске строк.

4 Использование идентифицирующих связей на обоих "краях" "бриллианта" может быть необходимо для того, чтобы "низ" алмаза ссылался на одну "вершину".

Другие вопросы по тегам