Sql 数据库设计,表模拟多个表的外键
我正在努力解决一个问题,但很难想出最好的解决方案。我有一个数据库,其中包含(除其他外)一个用于以下内容的表:Sql 数据库设计,表模拟多个表的外键,sql,sql-server,database-design,foreign-keys,ddl,Sql,Sql Server,Database Design,Foreign Keys,Ddl,我正在努力解决一个问题,但很难想出最好的解决方案。我有一个数据库,其中包含(除其他外)一个用于以下内容的表: 目的地请求 支持请求 交换请求 存款请求 每个表都有一列注释(从最终用户到管理员),但是我被要求添加向所有这些请求添加注释的功能。我希望每组注释都是独立的,这样我就可以跟踪添加注释的日期/时间,以及谁编辑了它。这向我建议,我需要将注释存储在一个表中,并通过外键链接回请求。问题在于,每个请求表都有一个自动递增的id列,该列在该表中是唯一的,但并非所有其他表都是唯一的(这意味着每个表可能
- 目的地请求
- 支持请求
- 交换请求
- 存款请求
我真正想知道的是,是否有一种有效的方法可以使用id和请求类型(基本上是表名)来创建外键。这是可能的吗? < P>作为创可贴,你可以做这样的事情… …在
上具有以下约束注意
:
CHECK (
(
“Destination Request Id” IS NOT NULL
AND “Support Request Id” IS NULL
AND “Exchange Request Id” IS NULL
AND “Deposit Request Id” IS NULL
)
OR (
“Destination Request Id” IS NULL
AND “Support Request Id” IS NOT NULL
AND “Exchange Request Id” IS NULL
AND “Deposit Request Id” IS NULL
)
OR (
“Destination Request Id” IS NULL
AND “Support Request Id” IS NULL
AND “Exchange Request Id” IS NOT NULL
AND “Deposit Request Id” IS NULL
)
OR (
“Destination Request Id” IS NULL
AND “Support Request Id” IS NULL
AND “Exchange Request Id” IS NULL
AND “Deposit Request Id” IS NOT NULL
)
)
这样,您不必改变现有表的PKS(它可以对您的模型和客户端应用程序的其余部分产生级联效应),但是您可以有适当的引用完整性而无需“重复”<代码> Notes < /Cord>表。
< P>作为一个创可贴,您可以这样做……/P> …在上具有以下约束注意
:
CHECK (
(
“Destination Request Id” IS NOT NULL
AND “Support Request Id” IS NULL
AND “Exchange Request Id” IS NULL
AND “Deposit Request Id” IS NULL
)
OR (
“Destination Request Id” IS NULL
AND “Support Request Id” IS NOT NULL
AND “Exchange Request Id” IS NULL
AND “Deposit Request Id” IS NULL
)
OR (
“Destination Request Id” IS NULL
AND “Support Request Id” IS NULL
AND “Exchange Request Id” IS NOT NULL
AND “Deposit Request Id” IS NULL
)
OR (
“Destination Request Id” IS NULL
AND “Support Request Id” IS NULL
AND “Exchange Request Id” IS NULL
AND “Deposit Request Id” IS NOT NULL
)
)
通过这种方式,您不必更改现有表的PKs(这可能会对模型的其余部分和客户端应用程序产生级联效应),但是您可以拥有适当的引用完整性,而无需“重复”注释表。您可以拥有表注释(object\u id,Note)其中,object_id引用任何请求表。您实际上不必在数据库中有外键约束,或者如果您确实想要维护约束,您可以使用约束子句(可能是特定于供应商的?)
要确定注释与哪个请求表关联,可以在注释中设置枚举类型值。一些数据库供应商有一个枚举类型,其他的您可能只使用一个Int。它只是一些类似于request_类型枚举(DESTINATION,SUPPORT,等等)的列
如果您的数据库很小或者可以脱机一段时间,您可以只重新创建表,这样它们就可以使用一个序列来生成所有四个对象id。。。这样,ID在不同的请求表中是唯一的。对于这种情况,我喜欢有一个普遍唯一的object_id序列
对于某些供应商(Postgre),您可以使用表继承。使用表继承,您可以执行类似于创建表目的地_请求(..)继承的操作(注意);这将使note表中的任何字段都可用于对destination_request表的查询。从某种意义上说,这是可行的,而且在幕后为你做了工作。从概念上讲,请求不是注释的子类型,因此这在OO设计方面并不理想,并且表继承可能无法移植到其他数据库供应商。这取决于你有多关心这里的纯洁
正如上面所建议的,您可以有四个不同的外键指向每个表,但这会留下一个大部分为空值的表。。。我可能更喜欢有四个不同的note表,而不是有那么多空值的表。您可以有一个表note(object\u id,note),其中object\u id引用任何请求表。您实际上不必在数据库中有外键约束,或者如果您确实想要维护约束,您可以使用约束子句(可能是特定于供应商的?)
要确定注释与哪个请求表关联,可以在注释中设置枚举类型值。一些数据库供应商有一个枚举类型,其他的您可能只使用一个Int。它只是一些类似于request_类型枚举(DESTINATION,SUPPORT,等等)的列
如果您的数据库很小或者可以脱机一段时间,您可以只重新创建表,这样它们就可以使用一个序列来生成所有四个对象id。。。这样,ID在不同的请求表中是唯一的。对于这种情况,我喜欢有一个普遍唯一的object_id序列
对于某些供应商(Postgre),您可以使用表继承。使用表继承,您可以执行类似于创建表目的地_请求(..)继承的操作(注意);这将使note表中的任何字段都可用于对destination_request表的查询。从某种意义上说,这是可行的,而且在幕后为你做了工作。从概念上讲,请求不是注释的子类型,因此这在OO设计方面并不理想,并且表继承可能无法移植到其他数据库供应商。这取决于你有多关心这里的纯洁
正如上面所建议的,您可以有四个不同的外键指向每个表,但这会留下一个大部分为空值的表。。。我可能更喜欢有四个不同的note表,而不是有那么多空值的表。除了ID和注释之外,这些表还有什么共同的属性吗?一般来说,用真实数据存储元数据是个坏主意。将引用表与引用ID一起存储几乎不会像有多个表那样有效。@Keyser:它们都有一个外键指向用户表,并且都有一个RequestDate和RequestStatus(我支持