我正在评估一些NoSQL实现(目前是RavenDB和MongoDB),作为解决涉及存储/检索无模式数据的特定需求集的一种方法。我想得到一些关于NoSQL是否应该是我应该查看的方向的反馈,或者是否还有其他(可能更简单的)选项。
基本上我们有一个软件产品(除其他外)定义了一个基本的域模型,该模型由几个相关的实体组成,每个实体都有许多属性(键/值)。当我们向客户发布时,我们与他们一起设置属性和值,这实际上是系统的配置。这是相当简单的,因为设计是预先知道的,我们不需要任何动态来实现这一点并使其执行(我们将使用RDBMS)。这些属性不是预先知道的,但这也不是问题,因为系统的这一部分几乎围绕属性模型。
问题在于,对于不同的客户,在我们发布并投入生产之后,我们发现需要查询特定的属性数据集,我们在编译和发布代码时(在配置之前)一无所知客户的属性)。我们基本上需要从我们可以存储的属性映射中生成数据(我们不会预先知道结构),然后以我们无法预料的方式查询存储的数据。现在的想法是我们可以创建在处理期间受到影响的钩子,并允许我们插入库(可能通过MEF)创建数据以便存储,然后在需要时查询它(不用于报告 - 通常用于创建其他数据/属性)。
(请注意,创建钩子和插件库是一个单独的问题,并不打算成为这个问题的一部分。)
常见的情况可能是:“我想知道过去10天内xxx发生了多少次”。所以我会创建一个能够识别xxx已经发生的插件,并将其写入带有日期/时间的数据存储。然后我将创建另一个执行查询的插件(可能在同一个DLL中),并向名为“CountOfxxxInLast10Days”的模型添加一个属性。 另一种情况可能是创建可配置的查找。所以我可能有一个在启动时运行的插件来创建/更新可以将一个属性值转换为另一个属性值的查找数据表,或者(更可能)将转换为查找值的一系列值。因此转换插件可能会添加一个包含列的表:bottom_value,top_value,multiplier,查询插件将使用属性值查询表,例如“SELECT multiplier FROM table WHERE [attribute_value] BETWEEN bottom_value AND top_value”。结果可能会将结果添加到名为“乘数”的属性中。
在某些情况下,旧数据可能会在指定的时间段后被清除。在上述第一种情况中,可能需要从超过十天的商店/缓存中删除数据。
在其他情况下,数据需要永久保留,就像上面的第二种情况一样。这种数据可能只是在启动时重新创建,而不是在永久存储中保存。
其他要求:
我们现在非常致力于.Net平台,因此任何选项都必须拥有可靠的.Net客户端/ API。
答案 0 :(得分:7)
有三种可能的选择,每种都有利有弊。
您已将实体存储在关系数据库中。您可以将未定义的属性存储在一个额外的表中,该表具有Key
和Value
列,以及一个引用属性所属实体的EntityId
列。基本上,您将使用数据库的一部分作为键值存储。
优点:
缺点:
键值存储(例如Redis和Riak或更高级Apache Cassandra)针对存储键值对进行了优化(毫无疑问......)。您可以使用RDBMS旁边的键值存储,专门用于存储属性,同时将实体保留在RDBMS中。
优点:
缺点:
您可以使用文档数据库来存储属性。但您也可以将所有内容存储在文档数据库中,包括您的实体。
优点:
缺点:
Apache CouchDB有quite a list of applications使用它,并从Stack Overflow社区接收positive feedback。它有一些drivers for .NET,但我不能告诉你这些驱动程序有多成熟。
MongoDB令人印象深刻list of production employments。有三个主要的drivers for .NET可用,它们似乎都是good quality。
RavenDB对.NET的支持非常出色,因为它是为.NET平台设计的。但是,我无法找到在RavenDB上运行的大型生产环境的示例。不过,我认为这绝对值得探索。
我在生产环境中没有太多实际操作经验,因此我不确切知道备份/恢复的准确程度。但鉴于这些NoSQL系统并不像RDBMS系统那么严格,我想它们应该比没有RDBMS更容易备份/恢复而不需要停机。