如何为关系数据库中的不同类型对象建模公共数据?

Dav*_*ave 2 database-design

在当前的项目中,我们正在创建一个应用程序,其中包含一些实体,例如Customer、Project、Company、Ticket、Request 等。这些模型是直截了当的。我无法理解的复杂部分如下:

我们希望有一些可以“附加”到各种对象的公共实体。一些示例包括Documents、Tags 和 Notes。对于上面提到的每个域实体,每一个都应该是可管理的。

在服务器端代码 (Java) 中,我们希望将通用功能实现为组件,并将它们重用/嵌入到我们域对象的特定编辑页面上。我们正在使用 ORM,并且还想重用那些“元数据”类。

我认为这个用例很容易用文档数据库建模。 但是如何在关系模型中做到这一点呢?

Joe*_*own 5

您要求的是一种使您的关系数据模型适合任意代码约束的方法,即:所有“附加”项都使用单个 ORM 类。我不会告诉您如何做到这一点,而是尝试解释为什么这不是一个好主意以及您应该做什么。

代码重用是应用于代码的一个很好的原则。数据不是代码,关系数据库的设计不应主要是为了促进代码重用。您应该为数据完整性而不是代码重用设计数据库。设计数据完整性意味着您应该以不同的方式对待不同类型的事物,即使它们目前碰巧“看起来相似”。这就是关系数据库的设计和构建目的。它们不是为了优化代码重用而设计的。

此外,ORM 代码通常不可重用,因为它旨在反映特定表的结构并对其进行操作。即使您碰巧有多个在结构上看起来都相似的表,并且即使您定义了允许这些表通过一组通用代码工作的接口,您仍然需要将数据保存在不同的表中。还有 ORM 代码生成器的问题,它不是为了寻找代码重用机会而构建的,例如您想要实现的目标。

您可以想象开发自己的 ORM(我在 1990 年代自己构建了一个)。如果你这样做了,你可以用一种方式构建它,使其在运行时成为元数据驱动。这会给您一种在代码中使用文档数据库的感觉,同时将数据存储在关系数据库中。但是,您真正要做的是将方钉捣碎成圆孔。如果您的应用程序需要一个文档数据库,您最好使用一个而不是关系数据库。

您可以(并且可能应该)尝试实现的最好方法是制作中间层/模型代码(以及前端/视图,如果可能的话)的可重用代码组件,该组件在后端/数据层内部分支到按表使用 ORM 类。这使您能够获得使用关系数据库的好处、使用 ORM 进行持久性代码的好处以及业务层和用户界面代码中的组件的好处。