鉴于这些要求,最合适的数据结构是什么?

时间:2018-09-05 12:58:19

标签: algorithm search data-structures

我们正在为公司中的某些实体(活动同盟体育)在公司中构建Search API,每个实体都具有名称属性和我们很难满足业务需求。

TL; DR; 能比基本的红黑树更好地解决这些业务需求的数据结构吗?

我们的业务要求是什么?

  1. 需要对数据结构进行排序,因此易于实现以下要求,因此插入不应破坏该属性。
  2. 数据结构需要保存有关其实体的信息,因此将使用节点键(实体的name属性)进行搜索,但是节点需要保存所有具有name属性的实体(开头)值。
  3. 数据结构需要支持按ID删除。 ID也是所有实体的财产。
  4. 它需要支持索引搜索(最多3个字符),因此,如果有人用“ aaa a .. ”和“ aaa z”之间的键来搜索“ aaa”,则每个节点应显示“ strong>”。 (例如,query =“ aaa”,索引=“ aaa”,“ aaab”,“ aaaab”,“ aaaz”,结果应为“ aaa”,“ aaab”,“ aaaab”)。
  5. 我们需要按本地化的节点键进行搜索。

到目前为止我们做了什么?

我们使用内置的红黑树(在C#中为SortedSet)开始了第一个迭代,对于节点,我们拥有的结构包含实体的name属性以及该name属性的所有相关事件。并且使用一种辅助方法满足了业务需求(1),(2)和(4)。

在第二次迭代中,我们必须支持删除,因此我们创建了实体ID的map(Dictionary),以引用放置在SortedSet中的实体对象。之所以这样做,是因为我们的删除请求仅按ID进行,而我们无法根据ID重新创建实体,因此,我们还需要创建此类映射。 (也许通过预言会有所帮助吗?)以此,我们确定了要求(3)。

现在我们需要支持(5),但是,每次迭代(收到的业务需求)都变得越来越难实现,我几乎觉得我们需要更改数据结构以便更好地满足业务标准。

本地化有什么问题?

我们可以创建新的SortedSet并重新使用实现,但这需要付出巨大的代价。让我详细说明。

我们有100个客户,每个客户都支持7-8种语言,我们系统中的语言对每个客户来说都是唯一的,因此,一位客户的翻译不会干扰另一位客户(如果有人想将其称为“足球”而不是“足球”,顺其自然。),除了基本语言(每个客户端都是全局的)外,这些语言基本上是新创建语言的默认设置,因此我们可以放心地说,客户端特定语言的很大一部分(让我们说英语)是相同的作为基础。综上所述,如果我们想分别对每个客户端和区域进行准确的搜索,则需要为每个客户端和区域分别进行索引,这会带来大量的重复。 >

到目前为止我一直在想什么?

我自己不是数据结构方面的专家,但是我真的很想做到这一点。当然,只要有足够的编码和硬件,一切都是可能的,但这不是重点。

我考虑过要实现一些二叉树(可以是AVL,红黑,2-3-4等),并对其进行扩展以使其比SortedSet更好地满足要求。希望这将解决目前为止我们必须解决的许多问题和解决方法,正如我所说的那样,可以更好地解决将来的需求,从而实现更快,更准确的实施, 但是 说我自己不是数据结构方面的专家,可悲的是,我无法在我拥有的时间范围内将这些业务需求映射到某些数据结构,因此,如果没有进一步的建议,你们有什么建议吗?

1 个答案:

答案 0 :(得分:0)

在这里,我的建议是将您的主要数据结构作为一个字典,以产品ID为键,其值为产品数据。这样可以非常快速地插入产品,并按产品ID进行移除。

要进行搜索,请提供一个单独的数据结构,其中包含产品名称和相关的产品ID。

class IndexEntry
{
    string ProductName;
    string ProductId;  // or int, if ProductId is an integer
}

由于允许使用客户特定的名称,因此必须将所有这些客户名称添加到此索引中。没问题,但是当您通过ID删除某些内容时,还必须从其他数据结构中删除关联的项。这将需要顺序搜索名称索引数据结构,以确保获得与特定产品关联的所有名称。即使使用树形结构,这也可能很昂贵。

为了加快处理速度,您可以为那些索引条目设置一个“已删除”标志,然后定期重建该结构以删除已删除的项目。这样,删除仅需要顺序扫描。这不理想,但是如果不经常进行插入和删除,则可以接受。

但是,关键是使您的主要数据结构包含按产品ID索引的产品信息。然后,您可以根据需要构建二级索引。