非关系数据库设计


114

我对您使用非关系型“ nosql”数据库所使用的设计策略感兴趣,即不使用传统关系设计或SQL(例如Hypertable,CouchDB, SimpleDB,Google App Engine数据存储区,Voldemort,Cassandra,SQL数据服务等)。它们通常也被称为“键/值存储”,从根本上说,它们的作用就像巨型分布式持久哈希表。

具体来说,我想了解这些新数据库在概念数据设计方面的差异。更容易,更困难,什么都做不到?

  • 您是否提出了在非关系世界中工作得更好的替代设计?

  • 您是否遇到任何似乎不可能的事情?

  • 您是否在任何设计模式之间架起了桥梁,例如从一种设计模式转换到另一种设计模式?

  • 您是否甚至现在都在做显式数据模型(例如,在UML中),还是完全放弃了它们以支持半结构化/面向文档的数据块?

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

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

仅供参考,这里有关于类似主题的StackOverflow讨论:


2
键/值数据库是旧事物。
Christopher

1
对于任何尤伯杯兴趣,有一个长形的讨论正在进行对NoSQL的谷歌组,在这里:groups.google.com/group/nosql-discussion/browse_thread/thread/...
伊恩·瓦利

4
仅供参考,我在此主题上写过一篇长篇报告,网址 为:google.com/url?sa=D&q= http: //ianvarley.com/UT/MR/……感谢大家的宝贵意见!
伊恩·瓦利

Answers:


55

我认为您必须考虑到非关系型DBMS的数据模型差异很大,因此概念性数据设计也将差异很大。在NOSQL Google组非关系数据库中的线程数据设计中,不同的范例如下分类:

  1. 类似于Bigtable的系统(HBase,Hypertable等)
  2. 键值存储(东京,Voldemort等)
  3. 文档数据库(CouchDB,MongoDB等)
  4. 图形数据库(AllegroGraph,Neo4j,芝麻等)

我主要研究图形数据库,而使用这种范例进行数据设计的优雅之处使我厌倦了RDBMS的缺点。我已经在此Wiki页面上放置了一些使用图形数据库进行数据设计的示例,并且还提供了一个如何对基本IMDB电影/演员/角色数据进行建模示例

演示幻灯片(SlideShare上)图形数据库和大规模的知识管理未来马尔科·罗德里格斯包含使用图形数据库,以及一个非常好的介绍,数据设计。

从graphdb的角度回答特定问题:

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

缩小差距:我倾向于根据域本身在每种情况下都做不同的事情,因为我不需要“面向表的图”之类的东西。但是,这里有一些有关从RDBMS自动转换为graphdb的信息。

显式数据模型:我一直在做这些事情(白板样式),然后在数据库中也使用它。

RDBMS世界小姐:创建报告的简便方法。更新:也许它不是从图形数据库中努力创造报告,看到了Neo4j的示例数据库创建报表


79

我只是刚开始使用非关系型数据库,但我仍在努力寻找解决方案,以找出最佳模型。我只能代表CouchDB。

不过,我有一些初步结论:

您是否提出了在非关系世界中工作得更好的替代设计?

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

文档数据库的种类交换了复杂性:SQL具有固定的数据和灵活的查询,而文档数据库则相反。

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

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

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

文件的设计非常灵活。我发现只有两个约束:

  • 由于没有与联接相对应的内容,因此将相关数据放在同一文档中。
  • 不要将文档做得太大,以免它们过于频繁地更新(例如将当年的所有公司销售额都放在同一文档中),因为每次文档更新都会触发重新索引。

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

我发现这些替代设计表明,在系统级而不是存储级,与任何SQL数据库相比,CouchDB的工作量级更好。如果您有一些数据并希望将其提供给网页,则整个系统的复杂度至少降低了50%:

  • 没有设计数据库表(次要问题)
  • 没有ODBC / JDBC中间层,所有查询和基于HTTP的事务(中等问题)
  • 从JSON进行简单的DB到对象映射,与SQL中的相同相比,这几乎是微不足道的 (重要!)
  • 您可以跳过整个应用程序服务器,因为您可以设计要由浏览器使用AJAX直接检索的文档,并添加一些JavaScript修饰,然后将它们显示为HTML。(巨大!!)

对于普通的Web应用程序而言,基于文档/ JSON的数据库是一个巨大的胜利,灵活度较低的查询和一些用于数据验证的额外代码的缺点似乎要付出很小的代价。

您是否遇到任何似乎不可能的事情?

还没。映射/归约作为查询数据库的一种方式并不熟悉,并且比编写SQL需要更多的思考。基元的数量很少,因此获得所需的结果主要是在如何指定键方面具有创造力的问题。

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

作为示例限制,计数和总和很容易,但是CouchDB视图/查询无法计算平均值。修正:分别返回总和并计数,然后在客户端上计算平均值。

您是否在任何设计模式之间架起了桥梁,例如从一种设计模式转换到另一种设计模式?

我不确定这是否可行。它完全是重新设计,例如将功能样式程序转换为面向对象的样式。通常,文档类型比SQL表少得多,每个文档中的数据更多。

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

即:一个用于订购的文档,其中包含客户ID和产品ID,并具有必要的复制字段以简化查询。文档中的任何内容都可以轻松查询,任何需要在“订单”和“客户”之间进行交叉引用的内容都必须由客户来完成。因此,如果要按地区销售报告,则可能应在订单中输入地区代码。

您现在是否还在做任何显式数据模型(例如,在UML中)?

抱歉,在文档数据库之前也从未做过很多UML :)

但是您需要某种模型来说明哪些字段属于哪些文档以及它们包含哪些类型的值。稍后供您自己参考,并确保使用DB的每个人都知道约定。例如,由于将日期存储在文本字段中时不会再出现错误,并且任何人都可以添加或删除他们喜欢的任何字段,因此,您既需要验证代码又需要使用约定来获取余裕。特别是如果您使用外部资源。

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

不。但是我的背景是Web应用程序开发人员,我们仅在必须满足以下条件的情况下处理数据库:)

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

因此,无论我要放弃什么,我一开始都从未真正拥有过。显然,您的经验可能会有所不同。


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

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

我要说的是,我所知道的所有成功的文档数据库应用程序都与数据之间的相互关系不大:文档(如Google搜索),博客文章,新闻文章,财务数据。

我希望有一些数据集可以更好地映射到SQL,而不是映射到文档模型,因此我认为SQL可以生存。

但是对于我们中那些只希望使用一种简单的方法来存储和检索数据的人-我怀疑我们中的很多人-文档数据库(如CouchDB中那样)真是天赐之物。


9
很有用。尤其是“ SQL具有不灵活的数据和灵活的查询,而文档DB则相反”并且没有联接。
j_random_hacker 2010年

2
+1,这很有见地。
马斯

2
没错,如果可能,我会多次投票。
Octavian A. Damiean

这在2014年仍然非常有用,如果您可以添加自2010年以来学到的知识或链接到其他地方可能拥有的信息,那将是很棒的。
玛姬

11

我在脑海中回想着用CouchDB回答这个问题,但我想大多数其他数据库也是如此。我们研究了使用CouchDB的方法,但最终决定不使用它,因为我们的数据访问权限事先未知,并且可伸缩性不是问题。

更难:

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

更轻松:

  • 如果您知道自己的数据访问方式,则速度更快。
  • 由于没有以应用程序程序员的身份向您作出承诺,因此数据库的迁移/故障转移更加容易。尽管您最终获得了一致性。大概。最后。待会儿
  • 一个键/值比表中的一行更容易理解。所有(树)关系都已存在,并且可以识别完整的对象。

建模应该大致相同,但是您必须注意放入一个文档中的内容:UML也可以用于OO建模和DB建模,这已经是两种不同的野兽。

我希望看到一个很好的与C#/ Silverlight完美集成的开放OO数据库。只是使选择更加困难。:)


1

平面文件长期以来一直被认为是不可思议的,对于任何大小的数据集都不切实际。但是,具有更多内存的更快计算机可以将文件加载到内存中并进行实时排序,至少对于n个较小的本地本地单用户应用程序而言。

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

当然,有理由使用数据库而不是平面文件—关系操作,数据完整性,多用户功能,远程访问,更大的容量,标准化等,但是提高的计算机速度和内存容量已经在内存中进行了操作在某些情况下更实用的数据。


1

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

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


3
史蒂芬(Stephan)-没错,现实世界的系统通常缺少标准化部门。但是,不能说RDBMses“不擅长加入”,这是不正确的。大多数商业产品(如Oracle,MS SQL Server等)都具有极其先进的查询优化器,并且可以执行各种不同的物理联接算法,其速度远远快于在应用程序代码中执行相同操作的速度。(据我了解,MySQL是对此的例外)。根据我的经验,像其他过早的优化一样,过早的非规范化通常是开发人员不佳的迹象。
伊恩·瓦利

2
继续这样的想法:不良的联接是不良索引和统计信息的结果。如果优化器没有任何可用的东西,或者有关其优化工具的信息已过期,则将做出错误的选择。许多人将其误认为是“糟糕的加入”。现代的RDBM系统具有自我调整功能,可在设置索引和统计信息时掩盖了使用大脑的需求。另外,人们还会混淆逻辑架构(第五范式)和物理架构(经常被规范化为第三范式)。仅仅因为您看到的数据库是“宽”的,并不意味着它在逻辑上设计不佳。
Godeke 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.