简体   繁体   English

SQL:一个外键引用多个表之一中的主键

[英]SQL : one foreign key references primary key in one of several tables

I am working on an application that will be used as an extensible framework for other applications. 我正在开发一个将用作其他应用程序的可扩展框架的应用程序。

One of the fundamental classes is called Node, and Nodes have Content. 基本类之一称为节点,节点具有内容。 The SQL tables look like this: SQL表如下所示:

TABLE Node ( NodeId int, .... etc ) TABLE节点(NodeId int,....等)

TABLE NodeContentRelationship ( NodeId int, ContentType string, ContentId int) 表格NodeContentRelationship(NodeId int,ContentType字符串,ContentId int)

It will be up to the developers extending the application to create their own content types. 开发人员可以扩展应用程序以创建自己的内容类型。

Clearly this is bad from a relationship-database point of view as it is not possible to add a foreign key relationship to NodeContentRelationship.ContentId, even though it is a foreign key column. 显然,从关系数据库的角度来看,这很不好,因为即使它外键列,也无法向NodeContentRelationship.ContentId添加外键关系。

However, the solution is quite simple and powerful so I am reluctant to change it. 但是,该解决方案非常简单且功能强大,因此我不愿意对其进行更改。

What do you think - am I in for a world of pain down the track? 您如何看待-我是否在痛苦的世界中前进?

Beware the Inner Platform Effect . 当心内部平台效应

If you're trying to build an 'extensible framework' which allows developers to store data of different 'content types' and relate them to each other in a generic fashion, you may find that others have already solved this problem . 如果您试图构建一个“可扩展框架”,使开发人员可以存储不同“内容类型”的数据并以通用方式将它们相互关联,那么您可能会发现其他人已经解决了 这个 问题

Why is it impossible to set NoteContentRelationship.ContentId as a foreign key? 为什么不可能将NoteContentRelationship.ContentId设置为外键? You can easily use a relational inheritance model with a table Content representing an abstract base class, and various tables AnimalContent , CarContent , etc. representing derived classes. 您可以轻松地使用关系继承模型,其中表Content表示抽象基类,而各种表AnimalContentCarContent等表示派生类。

This looks to me like a variation on EAV (Entity, Attribute, Value) design. 在我看来,这就像是EAV(实体,属性,值)设计的一种变体。

The benefits and drawbacks of EAV design have been extensively documented. EAV设计的优缺点已被广泛记录。

Here is a description of EAV from a sympathetic point of view: 这是从同情的角度对EAV的描述:

http://ycmi.med.yale.edu/nadkarni/Introduction%20to%20EAV%20systems.htm http://ycmi.med.yale.edu/nadkarni/Introduction%20to%20EAV%20systems.htm

And here is one from a hostile point of view: 从敌对的角度来看,这是一个:

http://tonyandrews.blogspot.com/2004/10/otlt-and-eav-two-big-design-mistakes.html http://tonyandrews.blogspot.com/2004/10/otlt-and-eav-two-big-design-mistakes.html

Be aware of the downside of EAV before you commit thousands of man-hours into pouring data into it. 在投入数以千计的工时将数据倒入EAV之前,请注意EAV的不利之处。 It's enormously seductive to programmers, but it can become a data manager's nightmare. 它对程序员非常诱人,但它可能成为数据管理器的噩梦。

You're in for a world of hurt down the road if you ever want to actually report on this data. 如果您想实际报告这些数据,那么您将面临很多麻烦。 You just made it much much harder to write joins and such. 您刚刚变得很难编写联接等。 The lack of constraints is bad, but the extra work needed on queries is (IMHO) worse. 缺少约束是不好的,但是查询所需的额外工作却更糟。

However, if you want other developers to be able to extend the system and store data in the database but not be able to change the database schema, there might not be a choice. 但是,如果您希望其他开发人员能够扩展系统并在数据库中存储数据,但又不能更改数据库架构,则可能别无选择。 In that case, the answer is to minimize how much gets stored this way. 在这种情况下,答案是最小化以这种方式存储多少存储空间。 You might also speed it up slightly by replacing ContentType with a ContentTypeId defined in another table. 您还可以通过用另一个表中定义的ContentTypeId替换ContentType来稍微加快速度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM