针对多列的hstore用例

Tra*_*lio 6 postgresql database-design hstore

我在决定使用哪种方法时遇到了一些麻烦.

我有几个实体"类型",让我们称它们为A,B和C,它们共享一定数量的属性(大约10-15).我创建了一个名为ENTITIES的表,以及每个常用属性的列.

A,B,C也有一些(大部分)唯一属性(所有布尔值,可以是10到30左右).我不确定在对表建模时遵循的最佳方法是什么:

  1. 在ENTITIES表中为每个属性创建一个列,这意味着不共享该属性的实体类型将只具有空值.
  2. 对每个实体类型的唯一属性使用单独的表,这有点难以管理.
  3. 使用hstore列,每个实体都将在此列中存储其唯一标志.
  4. ???

我倾向于使用3,但我想知道是否有更好的解决方案.

Erw*_*ter 9

(4)继承

从数据库设计的角度来看,最干净的风格可能是继承,就像@yieldsfalsehood在他的评论中所建议的那样.以下是包含更多信息,代码和链接的示例:
使用Postgres从多个模式中选择(检索)所有记录

然而,Postgres中当前的继承实现有许多局限性.其中,您无法为所有继承表定义公共外键约束.仔细阅读关于警告的最后一章.

(3)hstore,json(第9.2+)/ jsonb(第9.4+页)

许多不同或不断变化的属性集的一个很好的替代方案,特别是因为你甚至可以在列中的属性上有功能索引:

EAV类型的存储有其自身的优点和缺点.关于dba.SE的这个问题提供了非常好的概述.

(1)一个包含大量列的表

这是一种简单的蛮力替代品.从您的描述来看,您最终会得到大约100列,其中大多数是布尔值,大部分NULL时间都是大多数列.添加列entity_id以标记类型.每种类型实施约束对于许多列来说有点尴尬.我不会为太多可能不需要的约束而烦恼.

允许的最大列数为1600.由于大多数列为NULL,因此适用此上限.只要你把它保持在100到200列,我就不用担心了.Postgres中的NULL存储非常便宜(每列基本上1位,但它比这更复杂.).这只是每行10-20个字节.与人们可能假设的相反(!),在磁盘上最可能比解决方案小得多hstore.

虽然这样的桌子看起来对人眼来说是怪异的,但Postgres处理它并不是问题.RDBMSes专注于暴力.您可以在基表的顶部定义一组视图(对于每种类型的实体),只包含感兴趣的列,并与适用的列一起使用.这就像继承的逆向方法.但是这样你就可以拥有通用索引和外键等等.我可能会这样做.

所有这一切,决定仍然是你的.这一切都取决于您的要求的细节.

  • 就个人而言,我反对使用继承,因为*你不能在父及其所有子代*之间强制实施主键或唯一约束的唯一性.有关Pg特定建模替代方案的详细信息,请参阅http://dba.stackexchange.com/questions/27057/model-with-variable-number-of-properties-of-different-types和http://stackoverflow.com/q /三十九万八千六百七十零分之二千一百四十一万四千○九十二 (2认同)