Sql Server - 外键引用多列,其中一列不在源表中

发布于 2024-10-18 11:59:40 字数 1041 浏览 2 评论 0原文

我的外键有问题。这是我的数据库结构(简化):

表“语言”

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(或任何其他完整性检查)。这个配置可以吗?或者这不行,因此需要进行一些重组(真的吗?)?如果是的话如何实现呢?

编辑:为了更清晰而进行了一些清理。

I've got a problem with foreign key. This is my DB structure (simplified):

Table 'Languages'

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

Table 'Users'

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

Table 'Localization'

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

Table 'UserLocalization'

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' 

How to make a FK (or any other integrity check) in 'UserLocalization' to 'Localization'. Is it possible in this configuration ? Or is it not ok, and therefore some restructuralization (really ?) is needed ? If so how to accomplish it ?

Edit: A bit cleaned up for better clarity.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

時窥 2024-10-25 11:59:40

简单的答案是:如果您的表本地化如下所示:

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 连接。

The simple answer is: if you have your table Localization like this:

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

and you want to add a foreign key to another table referencing this table, that foreign key needs to have both columns of your PK here at hand, so it could be:

Table 'UserLocalization'

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

That's one of the downsides of compound primary keys - any FK referencing them must also include all columns of the compound PK - no exceptions / tricks / workarounds possible. With two columns, that's still doable, but with four, five, ten columns it gets really really messy. It also means any JOIN to that table must contain all common fields - and again, with two it's still ok, but with more, it gets really messy.

This is one of the reasons I would often consider adding an artificial surrogate key to tables where I only have a compound PK - just to simplify FK joins to it.

≈。彩虹 2024-10-25 11:59:40

删除UserLocalization 表。使用此 SQL 来查找用户的本地化字符串:

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

具有相同语言的所有用户都需要/具有相同的本地化记录,因此您不需要添加任何更多的完整性检查;您已经对 UsersLocalization 表中 LanguageID 上的 FK 进行了所有检查。

如果您想查找特定用户的本地化数据/字符串,只需在 SQL 末尾添加 WHERE UserID = [Whatever] 即可。

Get rid of the UserLocalization table. Use this SQL instead to find the localized strings for the users:

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

All users with the same language need/have the same localization records, so you don't need to add any more integrity checks; you're doing all the checks already with the FKs on LanguageID in the Users and Localization tables.

If you want to find a specific user's localized data/strings just put a WHERE UserID = [Whatever] on the end of the SQL.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文