Postgres为行存储一堆任意布尔值的最佳方法是什么?

时间:2011-12-05 04:08:02

标签: sql database postgresql postgresql-9.1

我有一个装满食谱的数据库,每行一个食谱。我需要为每个配方存储一堆任意“标志”,以标记各种属性,如无Gluton,没有肉,没有红肉,没有猪肉,没有动物,快速,简单,低脂肪,低糖,低卡路里,低钠和低碳水化合物。用户需要通过选中UI中的复选框来搜索包含一个或多个这些标记的食谱。

我正在寻找在食谱表中存储这些属性的最佳方法。到目前为止我的想法:

  1. 为每个属性创建一个单独的列,并在每个列上创建索引。我可能有超过20个这些属性,所以我想知道在一个表上创建一大堆BOOL列是否有任何缺点。
  2. 对所有属性使用位掩码,并将整个内容存储在包含适当位数的一个数字列中。为每个位创建一个单独的索引,以便快速搜索。
  3. 使用每个标记的值创建一个ENUM,然后创建一个具有该ENUM类型的ARRAY的列。我相信数组列上的ANY子句可以使用INDEX,但从未这样做过。
  4. 创建一个单独的表,其中包含配方与标签的一对多映射。每个标记都是此表中的一行。该表将包含配方的链接,以及该配方的标签为“on”的ENUM值。在查询时,我必须执行嵌套的SELECT来过滤掉不包含至少一个这些标记的配方。我认为这是更“正常”的方式,但它确实使某些查询更复杂 - 如果我想查询100个食谱并显示所有标签,我必须使用INNER JOIN并合并行,或动态使用嵌套的SELECT和聚合。
  5. 写入性能不是一个大问题,因为后端进程添加了配方,搜索速度至关重要(最终可能有几十万个配方)。我怀疑我会经常添加新标签,但我希望它至少可以做到没有重大问题。

    谢谢!

1 个答案:

答案 0 :(得分:4)

我建议你使用标准化设置。从一开始就将其设置为非规范化结构并不是我所建议的。

在不知道他发生了什么的所有细节的情况下,我认为最好的设置是让您的配方表和新属性表以及新的recipe_property表。这允许配方具有0或多个属性并规范化您的数据,使其快速且易于维护和查询数据。

高级别结构将是:

CREATE TABLE recipe(recipe_id);
CREATE TABLE property(property_id);
CREATE TABLE recipe_property(recipe_property_id,recipe_id,property_id);