多态ORM数据库模式

时间:2011-03-21 16:48:41

标签: database design-patterns database-design orm relational-database

我记得 - 很久以前 - 我正在搞乱Java ActiveObjects ORM,我遇到了它声称支持的数据库模式。

然而,通过搜索一般的想法很难找到模式的名称,因此如果有人能给我这个模式的名称,并且对使用它的“清洁度”有一些想法,我将非常感激。


模式定义如下:

Table:
  reference_type <enum>
  reference      <integer>
  ...

...其中字段reference_type的值将决定被引用的类型(以及表格)。因此:

User:
  location_type <l&l, address, city, country>
  location      <integer>
  ...

...根据location_type字段的值,外键location会引用l&laddresscitycountry表。

2 个答案:

答案 0 :(得分:2)

你很难找到它,因为它不是真正的(在广泛采用和鼓励的意义上)数据库设计模式。

远离这样的模式。虽然ORM使数据库表更容易映射到类型,但表不是类型,反之亦然。虽然目前尚不清楚你所描述的模型应该做什么,但你不应该将列作为多个表的假外键(当我说“假”时,我的意思是你要存储一个简单的标识符值,对应于另一个表的主键,但您实际上无法将该列定义为外键)。

为数据库建模以表示数据,为对象建模以表示过程,并使用ORM和中间层进行转换;不要试图将数据库推送到您的代码中,也不要将您的代码推送到数据库中。

编辑回复评论

您正在混合使用数据库和OO术语;虽然我不熟悉您用于定义该函数的语法,但我假设它是名为User的{​​{1}}类型的实例函数,它不带参数并返回{{1对象。数据库不支持实例(或任何基于类型的)函数的概念;关系数据库可以具有用户定义的函数,但这些是简单的过程函数,它们接受参数并返回值或结果集。它们不以任何方式对应于特定的表或字段,除了您可以在函数体内使用它们。

话虽如此,这里有两个问题要回答:如何做你所问的问题,以及什么可能是更好的解决方案。

对于你所问的内容,听起来你有一个超类型 - 子类型关系, 是一个标准的数据库设计模式。在这种情况下,您有一个表示父级的超类型表:

getLocation

(请注意,为简单起见,我使用Location;如果可能,您应该有更多特定和逻辑属性来定义主键)

然后你有一个或多个定义子类型的表:

Location
---------------
LocationID (PK)
...other common attributes

如果LocationID的特定实例只能是其中一个子类型,那么您应该将一个鉴别器值添加到父表(Address ----------- LocationID (PK, FK to Location) ...address-specific attributes Country ----------- LocationID (PK, FK to Location) ...country-specific attributes ),以指示它对应的子类型。您可以使用Location约束来确保给定行的此字段中只有有效值。

最后,听起来你可能会更好地使用混合方法。从我所看到的,您基本上代表了两种不同类型的位置:

  • 基于坐标的位置(L&amp; L)
  • 基于市政/邮政/等等的地点(国家,城市,地址),以及其中每一个都是上一个更具体的版本

鉴于此,一个简单的模型看起来像这样:

Location

现在唯一的问题是我们有可以为空的列。如果你想让你的查询变得简单但是从人们那里得到(证明!)剥离可以留下可以为空的列,那么你可以保持原样。如果你想了解大多数人会认为设计得更好的数据库,你可以为我们的两个可空列移到6NF。这样做也会产生很好的副作用,让我们可以更好地控制这些字段的填充方式,而无需做任何额外的事情。

我们的两个可空字段是CHECKLocation ------------ LocationID (PK) LocationType (non-nullable) ('C' for coordinate, 'P' for postal) LocationCoordinate ------------------ LocationID (PK; FK to Location) Latitude (non-nullable) Longitude (non-nullable) LocationPostal ------------------ LocationID (PK, FK to Location) Country (non-nullable) City (nullable) Address (nullable) 。我将假设City没有Address将是无意义的。在这种情况下,我们从Address表中删除这两个属性,并再创建两个表:

City

答案 1 :(得分:0)

在我看来,城市和国家将成为address表的一部分,并且L&amp; L不会与地址相互排斥(您可能同时拥有......),所以,为什么限制自己喜欢这样或那样?

此外,这会阻止location列强制执行引用完整性,不会,因为它不会始终引用同一个表吗?