Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 如何通过对象的层次结构(?)快速获取标记?_Postgresql_Database Design_Tags_Hierarchy - Fatal编程技术网

Postgresql 如何通过对象的层次结构(?)快速获取标记?

Postgresql 如何通过对象的层次结构(?)快速获取标记?,postgresql,database-design,tags,hierarchy,Postgresql,Database Design,Tags,Hierarchy,几个月以来,这个问题一直困扰着我: 首先,我将标记链接到对象。使用带有gin索引的数组对标记进行非规范化,以便快速检索 其次,这些对象有类,一个标记只能应用于一种类型的类 第三,我在我的对象上面有第二层,我称之为超级对象,它列出了一组对象,其中一个是根。典型的子类超类 我将使用可定制的机器人玩具作为类比。不要太认真。 对象是所有的片段和片段集。他们的职业可以是手臂、腿、胸围、头、武器等,也可以是身体,或者是成套的机器人。 超级对象将连接这些对象以创建可购买的物品。可以是将身体对象列为根加上

几个月以来,这个问题一直困扰着我:

  • 首先,我将标记链接到对象。使用带有gin索引的数组对标记进行非规范化,以便快速检索
  • 其次,这些对象有类,一个标记只能应用于一种类型的类
  • 第三,我在我的对象上面有第二层,我称之为超级对象,它列出了一组对象,其中一个是根。典型的子类超类

我将使用可定制的机器人玩具作为类比。不要太认真。
对象是所有的片段和片段集。他们的职业可以是手臂、腿、胸围、头、武器等,也可以是身体,或者是成套的机器人。
超级对象将连接这些对象以创建可购买的物品。可以是将身体对象列为根加上其所有部分(手臂、腿、胸围等)的身体,也可以是将整个机器人对象列为根、身体及其部分(因为身体和整个机器人可能有差异)和头部的完整机器人

如果这些对象被列为相等对象,则搜索标记将只需将链接到这些对象的标记数组相加即可。但是,superobject可以列出同一类的多个对象,这些对象在您购买时成为选项。一个完整的机器人可以列出3种不同的武器和2条不同的腿。当你买了它,你最终只有一件武器和一条腿

我的问题是,当你想用黄色斧头搜索机器人时,你不想找到一个黄色枪选项和一个蓝色斧头选项的机器人

更糟糕的是,这些选项可以有子选项,即你可以有两种腿和两种武器,一种武器可以在两种导弹之间进行选择。你不会想找到一把装有黄色导弹的斧子。在这种情况下,它一直是层次结构。但请注意,我对显示这些层次结构不感兴趣,这只是为了在对象中搜索标记

问题是,我不知道如何使用额外的层高效地搜索标签。我知道,简单地搜索对象上的多个标记可能会降低性能,因为如果不进行反规范化,就会有太多的连接与每个新标记相乘,从而无法找到(),这意味着如果在其上有一个层次结构,则必须递归地遍历所有这些组合,这将注定是一场灾难我们谈论的是Web服务器,所以性能才是最重要的。
我估计1百万个对象和1百万个超对象的标签数为3k

如果没有子选项,组合的数量会呈指数增长,因为3个半身像选项+2个腿选项提供了6条路径,然后使用6个武器选项,您有36条路径,同一头部有3个不同的身体,您有108条路径。具有许多选项的超级对象不是标准的,但我担心很少有例外会以难以置信的高路径数结束,因为我知道只有六个选项,您至少有64条路径(2^6)

我找到的唯一解决方案是通过记录所有路径(即数组中所有标记的组合)来反规范化。它有点像物化路径或ltree,但您可以直接记录标记数组。
它可以使用或不使用子选项

complete_robot_tags + head_tags + body_A_tags + track_tags + weapon_A_tags  
complete_robot_tags + head_tags + body_A_tags + track_tags + weapon_B_tags  
complete_robot_tags + head_tags + body_A_tags + legs_tags + weapon_A_tags  
complete_robot_tags + head_tags + body_A_tags + legs_tags + weapon_B_tags  
complete_robot_tags + head_tags + body_B_tags + track_tags + weapon_A_tags  
complete_robot_tags + head_tags + body_B_tags + track_tags + weapon_B_tags  
complete_robot_tags + head_tags + body_B_tags + legs_tags + weapon_A_tags  
complete_robot_tags + head_tags + body_B_tags + legs_tags + weapon_B_tags  

complete_robot_tags + head_tags + body_A_tags + track_tags  
complete_robot_tags + head_tags + body_A_tags + legs_tags  
complete_robot_tags + head_tags + body_B_tags + weapon_A_tags  
complete_robot_tags + head_tags + body_B_tags + weapon_B_tags  
但正如我所说的,它可以成倍增长,即使没有子选项,这看起来像是
base\u标记和(option\u 1\u标记或option 2\u标记)和(option 3\u标记或option\u 4\u标记或option\u 5\u标记)
。我正在考虑对您可以拥有的组合数量设定一个硬限制,但这有点违背了我数据库的用途…
子选项是例外,但它们的简单存在似乎让我朝着这个方向发展(尽管我想知道是否有一个简单的解决方案,在这种情况下,我可以从数据模型中删除子选项并“展平”所有内容)

谢谢你阅读这一大堆复杂的文字


注意:这个问题是关于postgresql的。告诉我使用图形数据库或任何其他DBMS不会被接受为答案。

对于复杂的标记筛选,我认为您需要一个标记引擎(请参阅)