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

Mik*_*sen 5 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和聚合.

由于后端进程添加了配方,因此写入性能不是一个大问题,搜索速度至关重要(最终可能会有几十万个配方).我怀疑我会经常添加新标签,但我希望它至少可以做到没有重大问题.

谢谢!

Kub*_*aun 5

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

在不知道他正在发生的事情的所有细节的情况下,我认为最好的设置是拥有您的配方表和新属性表以及新的 recipe_property 表。这允许配方具有 0 个或多个属性并规范化您的数据,从而使维护和查询数据变得快速而轻松。

高级结构将是:

CREATE TABLE recipe(recipe_id);
CREATE TABLE property(property_id);
CREATE TABLE recipe_property(recipe_property_id,recipe_id,property_id);
Run Code Online (Sandbox Code Playgroud)

  • 我发现一般来说,解决方案越直接越好,而且我不是在谈论使用胶带方法。在我的生活中,我无数次因为代码过于聪明而陷入混乱。作为回报,您必须过度思考才能了解正在发生的事情。当你必须保持那种类型的东西时,它会让你想换职业。 (2认同)