我记得 - 很久以前 - 我正在搞乱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&l
,address
,city
或country
表。
答案 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
约束来确保给定行的此字段中只有有效值。
最后,听起来你可能会更好地使用混合方法。从我所看到的,您基本上代表了两种不同类型的位置:
鉴于此,一个简单的模型看起来像这样:
Location
现在唯一的问题是我们有可以为空的列。如果你想让你的查询变得简单但是从人们那里得到(证明!)剥离可以留下可以为空的列,那么你可以保持原样。如果你想了解大多数人会认为设计得更好的数据库,你可以为我们的两个可空列移到6NF。这样做也会产生很好的副作用,让我们可以更好地控制这些字段的填充方式,而无需做任何额外的事情。
我们的两个可空字段是CHECK
和Location
------------
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
列强制执行引用完整性,不会,因为它不会始终引用同一个表吗?