SQL - 两个相互依赖的外键

发布于 2024-09-03 21:52:09 字数 564 浏览 5 评论 0原文

当前的结构如下:

Table RowType:    RowTypeID

Table RowSubType: RowSubTypeID
                  FK_RowTypeID

Table ColumnDef:  FK_RowTypeID
                  FK_RowSubTypeID (nullable)

简而言之,我将列定义映射到行。在某些情况下,这些行具有子类型,子类型将具有特定于它们的列定义。或者,我可以将那些特定于子类型的列定义挂出它们自己的表,或者我可以将 RowType 和 RowSubType 中的数据组合到一个表中并使用单个 ID,但我不确定这是否是更好的解决方案(如果有的话,我倾向于后者,因为我们最终大多会为给定的 RowType/RowSubType 拉取 ColumnDefs。

现在的设计是对SQL的亵渎吗?

如果保留当前结构,如果在 ColumnDef 中指定了 RowSubTypeID,如何保持它必须与 RowTypeID 指定的 RowType 相对应?我应该尝试用触发器强制执行此操作,还是我错过了可以解决问题的简单重新设计?

The current structure is as follows:

Table RowType:    RowTypeID

Table RowSubType: RowSubTypeID
                  FK_RowTypeID

Table ColumnDef:  FK_RowTypeID
                  FK_RowSubTypeID (nullable)

In short, I'm mapping column definitions to rows. In some cases, those rows have subtype(s), which will have column definitions specific to them. Alternatively, I could hang those column definitions that are specific to subtypes off their own table, or I could combine the data in RowType and RowSubType into one table and work with a single ID, but I'm not sure either is a better solution (if anything, I'd lean towards the latter, as we mostly end up pulling ColumnDefs for a given RowType/RowSubType).

Is the current design SQL blasphemy?

If I keep the current structure, how do I maintain that if RowSubTypeID is specified in ColumnDef, that it must correspond to the RowType specified by RowTypeID? Should I try to enforce this with a trigger or am I missing a simple redesign that would solve the problem?

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

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

发布评论

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

评论(1

悲念泪 2024-09-10 21:52:09

您遇到的问题是第四范式

解决方案如下:

Table RowSubType:       RowSubTypeID
                        FK_RowTypeID
                        UNIQUE(FK_RowTypeID, RowSubTypeID) 

Table ColumnDef:        ColumnDefID
                        FK_RowTypeID
                        UNIQUE(ColumnDefID, FK_RowTypeID) 

Table ColumnDefSubType: FK_ColumnDefID   } compound foreign key to ColumnDef
                        FK_RowTypeID     }   } 
                        FK_RowSubTypeID      } compound foreign key to RowSubType

您只需在 ColumnDefSubType 表中为具有行子类型的列创建一行。但所有引用都受到限制,因此您无法创建异常。

但就其价值而言,我同意@Seth 关于可能存在过度设计的评论。我不确定我是否理解您如何使用这些列定义和行类型,但它闻起来像 内部平台效应反模式。在SQL中,只需使用元数据来定义元数据。不要尝试使用数据来创建动态模式。

另请参阅这个精彩的故事:


回复您的评论:在您的情况下,我建议使用类表继承或具体表继承。这意味着为每个子类型定义一个单独的表。但是原始文本记录的每一列都将进入子类型表的相应列。这样,您就不需要拥有 rowtype 或 rowsubtype 表,它是通过为每个子类型定义表来隐式实现的。而且您不需要您的columndefs 表,这是表中定义的列所隐含的。

另请参阅我对 产品的回答表,多种产品,每种产品有很多参数或我的演示幻灯片SQL 中实用的面向对象模型

What you're having trouble with is Fourth Normal Form.

Here's the solution:

Table RowSubType:       RowSubTypeID
                        FK_RowTypeID
                        UNIQUE(FK_RowTypeID, RowSubTypeID) 

Table ColumnDef:        ColumnDefID
                        FK_RowTypeID
                        UNIQUE(ColumnDefID, FK_RowTypeID) 

Table ColumnDefSubType: FK_ColumnDefID   } compound foreign key to ColumnDef
                        FK_RowTypeID     }   } 
                        FK_RowSubTypeID      } compound foreign key to RowSubType

You only need to create a row in the ColumnDefSubType table for columns that have a row subtype. But all references are constrained so you can't create an anomaly.

But for what it's worth, I agree with @Seth's comment about possible over-engineering. I'm not sure I understand how you're using these column defs and row types, but it smells like the Inner-Platform Effect anti-pattern. In SQL, just use metadata to define metadata. Don't try to use data to create a dynamic schema.

See also this excellent story: Bad CaRMa.


Re your comment: In your case I'd recommend using Class Table Inheritance or Concrete Table Inheritance. This means defining a separate table per subtype. But each column of your original text record would go into the respective column of the subtype table. That way you don't need to have your rowtype or rowsubtype tables, it's implicit by defining tables for each subtype. And you don't need your columndefs table, that's implicit by the columns defined in your tables.

See also my answer to Product table, many kinds of product, each product has many parameters or my presentation slides Practical Object-Oriented Models in SQL.

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