【发布时间】:2018-09-05 12:58:19
【问题描述】:
我们正在公司中为我们的一些实体构建搜索 API - events、leagues 和 sports,每个实体都有 name 属性和我们在实现业务要求方面遇到了困难。
TL;DR;什么数据结构能比基本的红黑树更好地满足这些业务需求?
我们的业务需求是什么?
- 需要对数据结构进行排序,以便更容易实现以下要求,因此插入不应破坏此属性。
- 数据结构需要保存其实体的信息,因此将使用节点键(实体的名称属性)进行搜索,但节点需要保存所有具有名称属性的实体以节点键开头价值。
- 数据结构需要支持按id删除。 Id 也是所有实体的属性。
- 它需要支持索引搜索(最多 3 个字符),因此如果有人搜索“aaa”,则每个节点的键在“aaaa..”和“aaaz强>”应该出现。 (例如,查询 = “aaa”、索引 = “aaa”、“aaab”、“aaaab”、“aaaz”,结果应为“aaa”、“aaab”、“aaaab”)。
- 我们需要按本地化节点键搜索。
到目前为止我们做了什么?
我们使用内置的红黑树(C# 中的 SortedSet)开始了我们的第一次迭代,对于节点,我们拥有保存实体的名称属性以及与该名称属性相关的所有事件的结构。通过一种辅助方法,我们满足了业务需求 (1)、(2) 和 (4)。
作为我们的第二次迭代,我们必须支持删除,因此我们创建了一个实体 id 的映射(字典)到对放入 SortedSet 的实体对象的引用。我们这样做是因为我们的删除请求仅通过 id 进行,我们无法从 id 重新创建实体,所以在添加时我们需要创建这样的映射。 (也许增强功能可以提供帮助?)这样我们就获得了要求 (3)。
现在我们需要支持 (5),但是,随着每次迭代(我们收到的业务需求),它变得越来越难以实现,我几乎觉得我们需要更改数据结构以更好地满足业务标准。
本地化有什么问题?
我们可以创建新的 SortedSet 并重新使用该实现,但这需要付出巨大的代价。让我详细说明。
我们有 100 个客户,每个客户支持大约 7-8 种语言,我们系统中的语言对每个客户都是独一无二的,因此一个客户的翻译不会干扰另一个客户(如果有人想称之为足球而不是足球,没关系。),除了我们有基本语言(每个客户端都是全局的),它们基本上是新创建语言的默认设置,所以我们可以有把握地说,很大一部分客户端特定语言(比如说英语)是相同的作为基础。说了这么多,如果我们想分别准确地搜索每个客户端和语言环境,我们需要为每个客户端和语言环境分别建立索引,另一方面,这会引入大量重复。 p>
到目前为止我的想法是什么?
我自己不是数据结构方面的专家,但我真的很想把这件事做好。当然,只要有足够的编码和硬件,一切皆有可能,但这不是重点。
我考虑过实现一些二叉树(可以是 AVL、Red-Black、2-3-4 等)并对其进行扩充以比内置 SortedSet 更好地满足要求。这有望解决我们迄今为止必须解决的许多问题和解决方法,正如我所说,更好地解决未来的需求,因此实施更快,更准确,但是就像我一样说我自己不是数据结构方面的专家,遗憾的是我无法在我拥有的时间范围内将这些业务需求映射到某些数据结构,所以没有进一步的到期,你们有什么建议吗?
【问题讨论】:
-
我可能错过了一个重要的部分,但以上所有内容都由关系数据库方便地支持。通过标准化实现插入、删除、索引、非冗余等等。最重要的是,您拥有很好的灵活查询语言、可扩展性、容错性……
-
从商业角度来看,从头开始构建复杂的东西而不是使用现有的成熟技术对我来说听起来很奇怪。 “建立我们自己”是什么意思?除了标准库没有外部库吗?
-
抱歉,如果这不是您想要的,但存在非专有(公共领域)内存数据库,例如 SQLite。
-
您的第一个“业务”要求,即对数据结构进行排序,是不合适的。有可能,甚至很可能,排序的数据结构不是最有效或最有效的方式来做到这一点。您将可能无效的实施决策变成了业务需求,从而任意排除了大量可能的解决方案。
-
正如@SaiBot 指出的那样,您已经描述了数据库做得好的要求。如果出于某种原因管理层需要内存解决方案,则可以使用内存数据库,例如 SQLite。也就是说,如果管理层正在制定实施决策,您可能应该寻找另一份工作。这只能以糟糕的方式结束。
标签: algorithm search data-structures