Sql Server - внешний ключ, ссылающийся на несколько столбцов, один из которых отсутствует в исходной таблице - PullRequest
1 голос
/ 20 февраля 2011

У меня проблема с внешним ключом. Это моя структура БД (упрощенная):

Таблица «Языки»

LanguageID - primary key
LanguageName - string (for example 'English')
..

Таблица «Пользователи»

UserID - primary key
LanguageID - byte (FK to Languages.LanguageID)
..

Таблица «Локализация»

LocalizationID - / compound primary key
LanguageID     - \ compound primary key (FK to Languages.LanguageID)
Data - string (for example 'My Program' in English)

Таблица «Локализация пользователей»

UserLocalizationID - primary key
UserID - which user (FK to Users.UserID)
..
some other useful columns -> this table cannot be removed **EDITED**
..
LocalizationID - what string (FK to Localization.?) <- oops, not really because 
                                                       LanguageID is needed 
                                                       for FK to 'Localization' 

Как сделать FK (или любую другую проверку целостности) от 'UserLocalization' до 'Localization'. Возможно ли в этой конфигурации? Или это не хорошо, и поэтому необходима некоторая реструктуризация? Если да, то как это сделать?

Редактировать: Немного очищен для лучшей ясности.

Ответы [ 2 ]

2 голосов
/ 20 февраля 2011

Простой ответ: если ваша таблица Localization выглядит следующим образом:

LocalizationID - / compound primary key
LanguageID     - \ compound primary key (FK to Languages.LanguageID)
Data - string (for example 'My Program' in English)

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

Таблица 'UserLocalization'

UserLocalizationID - primary key
UserID - which user (FK to Users.UserID)
(LocalizationID, LanguageID) - FK to Localization

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

Это одно изпричины, по которым я часто рассматривал бы добавление искусственного суррогатного ключа в таблицы, в которых у меня есть только составной PK - просто для упрощения соединений с ним FK.

1 голос
/ 20 февраля 2011

Избавьтесь от таблицы UserLocalization.Вместо этого используйте этот SQL, чтобы найти локализованные строки для пользователей:

SELECT * FROM Users INNER JOIN Localization ON Users.LanguageID = Localization.LanguageID

Все пользователи на одном языке нуждаются / имеют одинаковые записи локализации, поэтому вам не нужно добавлять больше проверок целостности;Вы делаете все проверки уже с FK на LanguageID в таблицах Users и Localization.

Если вы хотите найти локализованные данные / строки конкретного пользователя, просто введите WHERE UserID = [Whatever]в конце SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...