我有兴趣了解您使用过的设计策略 非关系型“nosql”数据库 - 也就是说,不使用传统关系设计或 SQL 的(大多数是新的)数据存储类(例如 Hypertable、CouchDB、SimpleDB、Google App Engine 数据存储、Voldemort、Cassandra、SQL 数据服务等)。它们通常也被称为“键/值存储”,本质上它们就像巨大的分布式持久哈希表。

具体来说,我想了解以下方面的差异 概念数据设计 有了这些新的数据库。什么更容易,什么更难,什么根本不能做?

  • 您是否想出了在非关系世界中效果更好的替代设计?

  • 你是否曾遇到过看似不可能的事情?

  • 您是否用任何设计模式弥补了差距,例如从一种翻译到另一种?

  • 您现在是否正在做显式数据模型(例如UML 中)或者您是否完全抛弃了它们而转而使用半结构化/面向文档的数据 blob?

  • 您是否错过了 RDBMS 提供的任何主要额外服务,例如关系完整性、任意复杂的事务支持、触发器等?

我有 SQL 关系数据库背景,所以规范化是我的血液。也就是说,我获得了非关系数据库在简单性和可扩展性方面的优势,而且我的直觉告诉我,设计功能必须有更丰富的重叠。你做了什么?

仅供参考,StackOverflow 上已经有关于类似主题的讨论:

有帮助吗?

解决方案

我认为您必须考虑到非关系型 DBMS 在数据模型方面有很大差异,因此概念数据设计也会有很大差异。在线程中 非关系数据库中的数据设计NOSQL 谷歌小组 不同的范式分类如下:

  1. 类大表系统(HBase、 超表等)
  2. 钥匙值商店(东京,伏地魔等)
  3. 文档数据库(CouchDB、 MongoDB等)
  4. 图形数据库(AllegroGraph、 Neo4j、芝麻等)

我主要喜欢 图数据库, ,正是使用这种范式的数据设计的优雅让我厌倦了 关系型数据库管理系统. 。我在此提供了一些使用图形数据库进行数据设计的示例 维基页面 还有一个 如何建模的示例 基础的 互联网数据库 电影/演员/角色数据也是如此。

演示幻灯片(幻灯片共享) 图数据库和大规模知识管理的未来 经过 马尔科·罗德里格斯 还包含关于使用图形数据库进行数据设计的非常好的介绍。

从graphdb的角度回答具体问题:

替代设计:在许多不同类型的实体之间添加关系,无需担心或需要预定义哪些实体可以连接。

缩小差距:我倾向于根据域本身对每种情况采取不同的做法,因为我不想要“面向表格的图表”等。然而, 这是 有关从 RDBMS 到 graphdb 自动转换的一些信息。

显式数据模型:我一直这样做(白板风格),然后也使用数据库中的模型。

RDBMS世界小姐:创建报告的简单方法。更新:也许不是 很难从图形数据库创建报告,请参阅 为 Neo4J 示例数据库创建报告.

其他提示

我才刚刚开始使用非关系数据库,而且我仍在努力思考它并找出最好的模型是什么。我只能代表 CouchDB。

尽管如此,我还是有一些初步的结论:

您是否想出了在非关系世界中效果更好的替代设计?

设计重点转移:文档模型(对应于数据库表)的设计几乎变得无关紧要,而一切都取决于设计视图(对应于查询)。

文档数据库交换了复杂性:SQL 具有不灵活的数据和灵活的查询,文档 DB 则相反。

CouchDB 模型是“JSON 文档”(基本上是嵌套哈希表)的集合。每个文档都有一个唯一的ID,并且可以通过ID轻松检索。对于任何其他查询,您可以编写“视图”,它们是命名的映射/归约函数集。视图以键/值对列表的形式返回结果集。

诀窍在于,您不像查询 SQL 数据库那样查询数据库:视图函数的运行结果存储在索引中,并且只能查询索引。(如“获取所有内容”、“获取密钥”或“获取密钥范围”。)

SQL 世界中最接近的类比是,如果您只能使用存储过程查询数据库 - 您想要支持的每个查询都必须预先定义。

文档的设计非常灵活。我发现只有两个限制:

  • 将相关数据保存在同一个文档中,因为没有任何内容与连接相对应。
  • 不要使文档太大以至于更新过于频繁(例如将公司当年的所有销售额放在同一个文档中),因为每次文档更新都会触发重新索引。

但一切都取决于设计视图。

我发现 CouchDB 的替代设计比任何 SQL 数据库都在系统级别而不是存储级别上工作好几个数量级。如果您有一些数据并希望将它们提供给网页,则整个系统的复杂性至少会降低 50%:

  • 无需设计数据库表 (小问题)
  • 无 ODBC/JDBC 中间层,所有查询和事务均通过 http (中等问题)
  • 从 JSON 到对象的简单映射,这与 SQL 中的映射相比几乎微不足道 (重要的!)
  • 您可以跳过整个应用程序服务器,因为您可以将文档设计为使用 AJAX 直接由浏览器检索,并在将文档显示为 HTML 之前添加一点 JavaScript 修饰。 (巨大的!!)

对于普通的 Web 应用程序来说,基于文档/JSON 的数据库是一个巨大的胜利,而不太灵活的查询和一些额外的数据验证代码的缺点似乎只是一个很小的代价。

你是否曾遇到过看似不可能的事情?

还没有。Map/Reduce 作为一种查询数据库的方法是陌生的,并且比编写 SQL 需要更多的思考。原语的数量相当少,因此获得所需的结果主要是如何指定键的创造性问题。

存在一个限制,即查询不能同时查看两个或多个文档 - 没有联接或其他类型的多文档关系,但到目前为止还没有什么是不可克服的。

作为一个示例限制,计数和求和很容易,但平均值无法通过 CouchDB 视图/查询计算。使固定:分别返回总和和计数并在客户端计算平均值。

您是否用任何设计模式弥补了差距,例如从一种翻译到另一种?

我不确定这是否可行。它更像是一次彻底的重新设计,就像将函数式风格的程序转换为面向对象的风格一样。一般来说,文档类型的数量远少于 SQL 表的数量,而每个文档中的数据却较多。

一种思考方法是查看 SQL 中的插入和常见查询:例如,当客户下订单时哪些表和列会更新?哪些是月度销售报告?该信息可能应该放在同一个文档中。

那是:一份订单文档,包含客户 ID 和产品 ID,并根据需要提供复制字段以简化查询。文档中的任何内容都可以轻松查询,任何需要订单和客户之间交叉引用的内容都必须由客户完成。因此,如果您想要按地区划分的销售报告,您可能应该在订单中输入地区代码。

您现在是否正在做显式数据模型(例如在 UML 中)?

抱歉,在文档数据库之前也没有做过太多 UML :)

但是您需要某种模型来说明哪些字段属于哪些文档以及它们包含哪些类型的值。既供您自己稍后参考,也确保每个使用数据库的人都知道这些约定。例如,如果您将日期存储在文本字段中,您将不再收到错误,并且任何人都可以添加或删除他们想要的任何字段,因此您需要验证代码和约定来弥补这一不足。尤其是当您使用外部资源时。

您是否错过了 RDBMS 提供的任何主要额外服务?

没有。但我的背景是网络应用程序开发人员,我们只在必须的范围内处理数据库:)

我曾经工作过的一家公司开发了一款产品(Web 应用程序),该产品旨在跨多个供应商的 SQL 数据库运行,而“额外服务”因数据库而异,因此必须为每个数据库单独实现。因此,我们将功能移出 RDBMS 的工作量减少了。这甚至扩展到全文搜索。

所以无论我放弃什么,都是我一开始就没有真正拥有过的东西。显然,您的体验可能会有所不同。


警告:我现在正在开发一个用于财务数据、股票报价等的网络应用程序。这与文档数据库非常匹配,从我的角度来看,我获得了数据库的所有好处(持久性和查询),而没有任何麻烦。

但这些数据彼此相当独立,不存在复杂的关系查询。通过股票代码获取最新报价,通过股票代码和日期范围获取报价,获取公司元信息,这几乎就是全部。我看到的另一个例子是博客应用程序,博客也不具有非常复杂的数据库模式的特点。

我想说的是,据我所知,文档数据库的所有成功应用都是使用原本没有太多相互关系的数据:文档(如 Google 搜索)、博客文章、新闻文章、财务数据。

我希望有一些数据集能够更好地映射到 SQL,而不是映射到文档模型,因此我认为 SQL 将会继续存在。

但对于我们这些只想要一种简单的方法来存储和检索数据的人来说——我怀疑我们中有很多人——文档数据库(如 CouchDB 中的)是天赐之物。

我在脑海中用 CouchDB 来回答这个问题,但我认为其他数据库也是如此。我们考虑过使用 CouchDB,但最终决定不使用它,因为我们的数据访问事先未知,并且可扩展性不是问题。

更难:

  • 在概念层面上重新思考,所以它“更难”,因为它只是不同的。由于您必须提前了解数据访问模式,因此无法应用自动翻译。您至少需要添加访问模式。
  • 一致性不是由数据库处理的,而是必须在应用程序中处理。更少的保证意味着更容易的迁移、故障转移和更好的可扩展性,但代价是应用程序更加复杂。应用程序必须处理冲突和不一致。
  • 跨文档(或键/值)的链接也必须在应用程序级别进行处理。
  • SQL类型的数据库有更成熟的IDE。您可以获得大量支持库(尽管这些库的分层使事情比 SQL 所需的复杂得多)。

更轻松:

  • 如果您了解数据访问模式,速度会更快。
  • 对于数据库来说,迁移/故障转移更容易,因为作为应用程序程序员,我们不会向您做出任何承诺。尽管你得到了最终的一致性。大概。最后。一些时间。
  • 一个键/值比表中的一行更容易理解。所有(树)关系都已经存在,并且可以识别完整的对象。

建模应该大致相同,但您必须小心在一份文档中放置的内容:UML 还可以用于 OO 建模和 DB 建模,这已经是两种不同的东西了。

我希望看到一个良好的开放式 OO 数据库与 C#/Silverlight 很好地集成。只是让选择变得更加困难。:)

长期以来,平面文件一直被认为对于任何大小的数据集来说都是神秘且不切实际的。然而,速度更快、内存更多的计算机可以将文件加载到内存中并实时排序,至少对于相当小的 n 和本地单用户应用程序来说是这样。

例如,您通常可以在不到半秒的时间内读取包含 10,000 条记录的文件并在字段上对其进行排序,这是可接受的响应时间。

当然,使用数据库而不是平面文件是有原因的——关系操作、数据完整性、多用户能力、远程访问、更大容量、标准化等,但是计算机速度和内存容量的增加使得内存中操作成为可能。在某些情况下更实用的数据。

我在现实生活中看到的关系数据库往往根本没有很好地规范化,这与您的说法相反。当被问及时,设计师告诉我这主要是因为性能。RDBM 不擅长连接,因此从规范化的角度来看,表往往太宽。面向对象的数据库往往在这方面做得更好。

RDBM 存在问题的另一点是处理历史/时间相关的键。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top