sqlite 数据库是否应该包含可传递属性以避免为空?

monwx1rj  于 2022-11-14  发布在  SQLite
关注(0)|答案(1)|浏览(187)

考虑一下这个简单的设置。

在此模型中,适用以下限制:

  • 一个人要么是父母,要么是孩子。
  • 每个孩子只有一位家长
  • 父级与公用事业示例有关系

由于父项的原因,子项与实用程序具有传递关系。
现在,问题是:是否应该在数据库中设置每个孩子的“City Utity id”属性?
优点:您可以避免为空。据说,如果该字段可为空,则数据库将构建效率较低的索引,因为作为孩子的每个人都将在该属性上具有相同的值(空)。
缺点:不那么干净,CUD业务需要更多的簿记。该字段不传递数据库中尚未表示的数据。

798qvoo8

798qvoo81#

EF同时支持每个层次结构的表(TPH)和每个具体类型的表(TPT),因此只要使用模式,您就可以选择。虽然父母和孩子都是一个人,但他们都有各自的特点。其中之一是,只有父母才能分配城市公用事业,其他的是孩子只能与父母相关联。(父级不能引用另一个父级作为子级,或者说子级不能引用另一个子级作为父级。)在单个表中处理所有这些场景的是一个TPH结构,它依赖于应用程序代码要强制执行的隐式规则,并为应用于其中一个或另一个的数据产生大量可为空的引用和字段。
只要有可能,我建议使用TPT结构,并使关系更加明确。这样做的好处是不需要完全依赖应用程序代码来确保关系和“可选性与必需性”在数据库级别强制执行。
这将包含类似以下内容:

[Person]
PersonId [PK]
// other common fields that apply to ALL types of Person.

[Parent]
PersonId [PK, FK]
CityUtilityId [FK]
// other parent-specific fields.

[Child]
PersonId [PK, FK]
ParentPersonId [FK] (To Parent, not Person)
// other child-specific fields.

这样,如果父项或子项具有必填或可选字段,则可以将它们放入各自的表中,并具有相应的空能力。另一种方法是,该字段始终为空,并由应用程序来确保强制执行其中之一的所需性质。DB将可以在任何时候错误地进入完全无效状态,而不会有任何抱怨。
在开发社区中,最小化表数仍然很有吸引力,这在很大程度上源于驱动器空间昂贵和模式成本$$的时代,因此将类似的数据合并到一个表中可能是有意义的。然而,在关系方面,它仍然存在重大缺陷。对于现代数据库,我认为只组合有效相同的内容并使用TPT进行继承或使用组合总是更好。
合成的一个例子就是具有状态的订单。该状态可能已交付,并且可能存在我们希望在交付订单时记录的详细信息。(签署等)这些字段可以是Order表上的Null字段,但它们仅适用于已交付的订单,在所有其他情况下将为Null。相反,拥有一个像OrderDeliveryDetails/w这样的表,它与Order是一对一的关系,这是在交付订单时创建的。(如果订单因任何原因从已交付状态更改为另一状态,则会删除/使其处于非活动状态。)

相关问题