SQL Server外键到多个表

时间:2013-04-10 20:06:31

标签: sql sql-server tsql foreign-keys referential-integrity

我有以下数据库架构:

members_company1(id, name, ...);
members_company2(id, name, ...);
profiles(memberid, membertypeid, ...);
membertypes(id, name, ...)
[ 
       { id : 1, name : 'company1', ... }, 
       { id : 2, name : 'company2', ... }
];

因此,每个配置文件都属于某个成员,来自company1或company2,具体取决于membertypeid

members_company1     —————————      members_company2     
————————————————                    ————————————————
id      ——————————> memberid <———————————         id
name               membertypeid                 name
                       /|\
                        |  
                        |  
      profiles          |  
      ——————————        |  
      memberid  ————————+  
      membertypeid

我想知道是否可以在profiles表中创建基于memberidmembertypeid对的引用完整性的外键来引用members_company1或members_company2表记录?

5 个答案:

答案 0 :(得分:4)

外键只能引用一个表,如documentation(强调我的)中所述:

  

外键(FK)是使用的列或列组合   在两个表中的数据之间建立和实施链接。

但是如果你想开始清理,你可以创建一个members表,如@KevinCrowell建议的那样,从两个members_company表中填充它并用视图替换它们。您可以在视图上使用INSTEAD OF触发器将更新重定向到新表。这仍然是一些工作,但它将是一种修复数据模型而不破坏现有应用程序的方法(当然,如果它在你的情况下是可行的)

答案 1 :(得分:1)

在您无法更改表结构的情况下运行:

选项1

参考诚信对您有多重要?你只是在这些表之间进行内连接吗?如果您不必过于担心,那就不用担心了。

选项2

好的,你可能需要做某事。也许你只有内连接,但你必须处理与成员表中的任何内容无关的配置文件中的数据。你能创建一个每天或每周运行一次的工作来清理它吗?

选项3

是的,那个人可能也行不通。您可以在配置文件表上创建一个触发器,用于检查对成员表的引用。这远非理想,但确实可以保证即时检查。

我的意见

我会使用选项2.你显然正在处理一个不太理想的架构。为什么要让它变得更糟。让糟糕的数据持续一周;每个周末打扫桌子。

答案 2 :(得分:1)

来吧你可以创建一个表但是你不能修改members_company1或members_company2吗?

当将新记录插入members_company表时,您创建成员表的想法将需要更多操作 所以你可以在members_company1和members_company2上创建触发器 - 那不是修改?

你能做什么有什么限制?

如果您只需要选择与members_company1和members_company2的兼容性,那么创建一个真实的成员表并为members_company1和members_company2创建视图。
基本选择不知道它是另一端的视图或表。

CREATE VIEW dbo.members_company1
AS
SELECT id, name 
FROM members
where companyID = 1

您甚至可以使用而不是

来处理插入,更新和删除

INSTEAD OF INSERT Triggers

答案 3 :(得分:0)

外键不能引用两个表。假设您不想通过合并members_company1members_company2表来更正您的设计,最好的方法是:

将两个名为member_company1_idmember_company2_id的列添加到profiles表中,并为这两个表创建两个外键并允许nulls。然后你可以添加一个约束来确保其中一列是null而另一列不是。

答案 4 :(得分:0)

没有。外键可以引用一个且只有一个主键,并且无法在表之间传播主键。您希望实现的逻辑类型需要使用触发器或重构数据库,以便所有成员都基于单个表中的核心记录。