3种存储家谱数据的方法
3种存储家谱数据的方法
家谱软件开发案例研究
在构建家谱应用程序时,基本问题之一是如何有效地存储数据。本博客比较了三种可能的方法:父 ID、嵌套集和祖先数组。
一些背景
在过去的一年里,我们一直在为一个阿拉伯家谱项目开发一个系统。从许多角度来看,该项目对我们来说都是新事物。你可能还记得我们的 关于从右到左 UI 实现的博客 .该博客专注于前端和阿拉伯语。这个将是关于后端和有效存储超过一百万个节点的家谱的方法。
该项目追溯了阿拉伯血统。一个庞大的研究团队正在研究来自世界各地的资源。他们正在寻找阿拉伯人之间的家谱联系,以便将他们放在阿拉伯家谱上。
他们需要一个可以让他们轻松输入数据的系统。我们需要以一种使它们之间的关系易于管理和编辑的方式保存这些数据。
要求
因此,我们必须问自己的第一个问题是我们希望应用程序执行哪些操作。这些曾经是:
- 搜索最多 5 代的所有孩子。 (它也可能多达 10 个,但超过 10 个会使树的绘制变得模糊和滞后)。
- 插入一个人或一个子树。
- 删除一个人(作为单个节点或递归)。
- 按类型选择——列出特别重要的人(标有“MF”)及其直接继任者。
现在是时候弄清楚如何以一种使这些操作易于编写和执行流畅的方式将每个人保存在数据库中。
三种经过测试的方法
1. 家长 ID
我们看到的第一种方法是使用父 ID。数据库中的每个人都有一个 ID 号。然后,您可以使用相同的编号为其所有子代定义父 ID。
具有父 ID 的树的开头看起来像这样:
这种简单的方法可以轻松地从树中插入和移除人员。列出最多 5 代的孩子也不成问题。
挫折?这种类型的结构需要对此类操作使用递归。问题不仅在于递归可能不是你最喜欢写的东西。这也意味着每次我们执行这个操作时,都需要遍历整棵树才能给我们结果。这可能需要很长时间。
这是一个“不可行”。
所以,现在是我们探索其他选择的时候了。
2. 嵌套集
在研究其他选项时,我们遇到了嵌套集系统并试了一下。
嵌套集基于将人们放入……,好吧,集。你用两个值来定义每个人——左和右。你把他们的孩子放在那个集合里。您还给孩子们单独的间隔,从而为每个孩子创建额外的子集。
这可能是一张图片值一千字的情况之一。所以:
该系统使 搜索超快 .然而,编辑很快就会成为一个问题,因为一个集合的变化也会导致所有更高级别的集合发生变化。这使得添加新人或改变他们在树上的位置成为 Chuck Norris 的工作。甚至诺里斯先生也可能会放弃按类型选择。
所以这种方法在我们的案例中肯定行不通。但, 如果您有最终数量的节点并且优先考虑快速搜索,则可能值得研究 .
3. 祖先数组
我们尝试的最后一种方法是使用祖先数组。树上的每个人都被分配了一组 ID 号。每个数字都定义了血统中的下一个人。序列中的最后一个数字是他们自己的个人 ID 号。
例如,Felix 由数组 [1, 3, 5] 定义。 1 号来自他的祖父 Victor,3 号来自他的父亲 Adeel,5 号是他自己的身份证号码。
使用这种方法,添加或删除子树相当顺利。选择具有血统的 MF 类型的人也只需要检查一次数据库。
将一个人移动到树上的另一个地方需要更多的关注。您还必须修改孩子的数组。这不仅仅是额外的工作。我们主要关心的是此类操作所需的时间,尤其是当数组变长时。因此,我们对其进行了测试。
这个想法是使用父 ID 或数组来比较每个操作所需的时间。我们还尝试增加数据库大小以查看那里的差异。这就是我们得到的:
*The operation is not possible with this method.
当我们尝试删除一个人并保留他们的孩子时,我们注意到了最显着的差异。这意味着您必须先将所有孩子移动到不同的父母(=调整他们的数组),然后才能删除一个人。数据库越大,花费的时间就越多。
另一个突出的操作是删除一个人和他们的孩子。在这里,Parent ID 方法花费的时间最长,因为您必须使用递归来一个一个地删除每个人。
虽然我们只是出于好奇,但我们还将带有数字的数组与使用 UUID 的数组进行了比较。虽然差异很明显,但结果保持在同一数量级内。
即使阵列有 50 个插槽长,我们仍然发现速度可以满足我们的需求。有了这个, 我们决定阵列的祖先是我们要走的路 .
结论 / TL;博士
- 我们比较了在族谱中保存数据的三种方法:父 ID、嵌套集和祖先数组。
- 在选择方法之前,我们建议列出所有必要的操作(=需求)。
- 使用父 ID 可以轻松添加和编辑节点。但是,高级搜索可能很困难并且可能需要很长时间。
- 使用嵌套集搜索非常快。但是,如果您从一开始就没有最终数量的节点,那么编辑可能会成为一场噩梦。
- 祖先阵列最大的问题是速度。但是,根据我们的需要,测试显示出可接受的结果。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明