应该在数据库表的一列中存储一个长顺序的id列表吗



假设我有一个用户表,其中有一个id列和一个排名列。每个用户可以按某种顺序对其他用户进行排名。假设这个列表可能很长(某个常数的最大值,比如10000),但通常会短得多。只需要存储和检索用户的整个列表,也就是说,不需要在查询中搜索每个列表。

一个想法是以逗号分隔字符串的形式将其存储为id列表。唯一的缺点是外键无法将列表中的每个id连接到相应用户中的id列,这意味着如果用户的id发生更改,它不会在列表中自动更改。然而,用户的id永远不会改变,所以这是一个原则问题(不打破1NF?)。

另一个想法是创建一个表,其中每个条目都有一个from和to用户id列以及一个排名列。这样做的缺点是,与用户数量相比,该表可能包含大量记录(例如数十亿)。此外,当检索用户的列表时,它需要搜索许多记录。数据存在重复,例如,排名现在是显式存储的,而不是隐式存储的。这意味着对列表进行一次更改可能意味着属于该列表的所有记录都必须更新其排名列。

什么是更好的解决方案?有完全不同的解决方案吗?

编辑:我想大多数人都会说第二个是最好的,因为它是一个关系型数据库,然而,你能说负面方面可以减轻吗?或者为什么它们无关紧要?如果有序列表可能更长,例如每个列表有数百万个元素,那么列表更像是一个数据块,而一个等效的表可能包含数万亿个条目,该怎么办?

使用表时,用户可能需要将排名复制到前端语言的数组中进行编辑,因此必须在前端和后端进行每次更改,或者必须删除旧记录,并为新列表的每个元素插入一条新记录。

对于关系数据库来说,这通常不是一个好的设计。

存储逗号分隔的值列表是反规范化的一种类型。良好的关系数据库设计鼓励规范化。

所有类型的优化都会以牺牲其他查询为代价来改进一种类型的查询。在您的情况下,如果您只存储或检索整个id列表,那么这可能是一个很好的优化。但是,如果你想将一个id添加到列表中,或者搜索一个特定的id,或者确保它们被正确排序,或者进行许多其他类型的操作,那么这些任务就不会得到优化。

使用逗号分隔的列表实际上有很多缺点,而不仅仅是您提到的外键。我在这里写了一个老答案:在数据库列中存储分隔列表真的有那么糟糕吗?

使用规范化设计使数据库更加灵活。也就是说,您可以对数据运行多种类型的查询,但没有一种特别不利。

因此,像非规范化这样的优化需要你确保你提前知道哪些查询对你的项目很重要,并且你知道你不需要任何类型的查询,因为非规范化设计会使这些查询的成本更高。或者,如果您偶尔确实需要这些查询,则不需要它们来提高效率。

如果以规范化的方式存储,您表示担心会生成许多行,但大多数RDBMS产品可以处理数十亿行。

如果创建了正确的索引,则搜索不应该扫描很多行。哪些索引是正确的,取决于需要优化哪些查询。


如果有序列表可以更长,例如每个列表有数百万个元素,那么列表将更像一个数据块,而等效的表可能包含数万亿个条目,该怎么办?

恕我直言,如果你必须以这种规模解决数据管理问题,那么你就不会问如何在Stack Overflow上解决它了。你可以雇佣一些资深的软件架构专家来解决这个问题

他们会告诉你基本上相同的事情:在他们选择支持这些特定查询的最佳体系结构之前,你必须非常清楚你需要对这些数据执行什么类型的查询。因为在这种规模下,除了一种最佳的方法,你什么都做不起。

如果你不需要在";数万亿元素";规模,那么使用关系解决方案就足够了,并且提供了灵活性,正如我上面所描述的。

我看到很多SO问题在问脸书如何管理其规模的数据。答案几乎总是:;他们做什么并不重要,因为你永远不必按照他们的规模去做">

最新更新