针对多列的hstore用例

时间:2014-02-04 18:31:02

标签: postgresql database-design hstore

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

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

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

  1. 在ENTITIES表中为每个属性创建一个列,这意味着不共享该属性的实体类型将只有一个空值。
  2. 对每个实体类型的唯一属性使用单独的表,这有点难以管理。
  3. 使用hstore列,每个实体都会在此列中存储其唯一标志。
  4. ???
  5. 我倾向于使用3,但我想知道是否有更好的解决方案。

2 个答案:

答案 0 :(得分:9)

(4)Inheritance

从数据库设计的角度来看,最干净的风格可能是继承,就像@yieldsfalsehood在他的评论中所建议的那样。这是一个包含更多信息,代码和链接的示例:
Select (retrieve) all records from multiple schemas using Postgres

但Postgres中当前的继承实现有许多限制。其中,您无法为所有继承表定义公共外键约束。仔细阅读the last chapter about caveats

(3)hstorejson(第9.2+页)/ jsonb(第9.4 +)页

不同或更改属性集的批次的一个很好的替代方法,特别是因为您甚至可以在列中的属性上使用函数索引:

EAV类型的存储有其自身的优点和缺点。 This question on dba.SE提供了非常好的概述。

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

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

The maximum number of columns allowed is 1600。由于大多数列为NULL,因此适用此上限。只要你把它保持在100到200列,我就不用担心了。 Postgres中的NULL存储非常便宜basically 1 bit per column, but it's more complex than that.)。这只是每行10-20个字节。与人们可能认为(!)相反,磁盘上的小得多hstore解决方案相反。

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

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

答案 1 :(得分:0)

在我的工作中,我们的需求在迅速变化,并且很少因适当的架构升级而停机。在完成大记录时都包含大量的空值和高度归一化的(名称,值)后,我一直认为将所有常见属性都放在适当的列中,而将不同/不太常见的属性包含在“ hstore”存储桶。