1
259
你所描述的是多态关联。也就是说,“外键”列包含在一组目标表中必须存在的ID值。通常,目标表以某种方式相关,例如作为某些公共超类数据的实例。您还需要外键列旁边的另一列,以便在每一行上指定引用哪个目标表。
无法使用SQL约束对多态关联建模。外键约束总是引用 一 目标表。 Rails和Hibernate等框架支持多态关联。但他们明确表示,必须禁用SQL约束才能使用此功能。相反,应用程序或框架必须执行等效的工作以确保满足引用。也就是说,外键中的值存在于一个可能的目标表中。 多态关联在增强数据库一致性方面很弱。数据完整性取决于使用相同的引用完整性逻辑访问数据库的所有客户机,而且执行必须是无错误的。 以下是一些利用数据库强制引用完整性的替代解决方案:
为每个目标创建一个额外的表。
例如
这意味着要获得用户最喜欢的所有位置,您需要查询这两个表。但这意味着您可以依赖数据库来增强一致性。
创建
使用两列。
不要使用一列引用两个目标表中的任何一个,而是使用两列。这两列可能是
根据关系理论,多态关联违反了
First Normal Form
,因为
多态关联也违反了 Third Normal Form ,因为列的含义取决于为外键所引用的表命名的额外列。在第三种标准形式中,表中的属性只能依赖于该表的主键。 @SavasVedova回复:
我不确定在没有看到表定义或示例查询的情况下是否遵循您的描述,但听起来您只是有多个
如果您知道要连接到哪种类型的筛选器,则将产品连接到特定类型的筛选器很容易:
如果希望筛选器类型是动态的,则必须编写应用程序代码来构造SQL查询。SQL要求在编写查询时指定并修复表。不能根据在
唯一的另一个选择是加入 全部的 使用外部联接筛选表。那些没有匹配的产品id的将作为一行空值返回。但你还是得硬编码 全部的 联接的表,如果添加新的筛选表,则必须更新代码。
连接到所有筛选表的另一种方法是按顺序执行:
但是这种格式仍然要求您编写对所有表的引用。这是绕不过去的。 |
2
10
这不是世界上最优雅的解决方案,但是您可以使用 concrete table inheritance 让这一切顺利。
从概念上讲,你提出了一个“可以成为流行区域的事物”的概念,你的三种类型的地方从中继承。您可以将其表示为一个表,例如,
您在第二篇专栏文章中提出的描述关联类型的解决方案碰巧是Rails如何处理多态关联,但我一般不喜欢这样。比尔非常详细地解释了为什么多态关联不是你的朋友。 |
3
5
下面是对Bill Karwin的“supertable”方法的修正,使用了一个复合键
这种设计不能保证
|
4
0
我意识到这根线是旧的,但我看到这个,我想到了一个解决办法,我想我会把它扔在那里。 区域、国家和州是生活在等级制度中的地理位置。 通过创建一个名为geographic_location_type的域表,您可以完全避免问题,该表将填充三行(Region、Country、State)。 接下来,不要创建三个位置表,而是创建一个具有geographic_location_type_id外键的geographic_location表(这样您就知道实例是地区、国家还是州)。 通过使此表自引用来建模层次结构,以便状态实例将fKey保存到其父国家/地区实例,其父国家/地区实例又将fKey保存到其父区域实例。区域实例在该fKey中将保留空值。这和你用三张表做的没有什么不同(你会有一个-很多地区和国家之间的关系,国家和州之间的关系),除非现在它都在一张表中。 流行的用户位置表是用户和地理位置之间的范围分辨率表(因此许多用户可能喜欢许多地方)。 苏乌
不确定目标数据库是什么;上面是MS SQL Server。 |
Davtho1983 · 在Django中查看ForiegnKey数据 6 年前 |
N_M · 主键和外键约束在配置单元中如何工作? 6 年前 |
Melolailo · 将约束与外键一起使用 6 年前 |
Alfred Balle · Postgresql,对唯一约束的引用 6 年前 |
yodabar Arkana · 更新|删除外键时的PgSQL默认操作 6 年前 |
Seba · 如何检查外键以限制软删除? 6 年前 |
dryhay · MySQL“多对多”关系错误 6 年前 |