我有兴趣听听你用过非关系型"nosql"数据库的设计策略- 也就是说,不使用传统关系设计或SQL的(通常是新的)数据存储类(如Hypertable,CouchDB, SimpleDB,Google App Engine数据存储,Voldemort,Cassandra,SQL数据服务等).它们通常也被称为"键/值存储",而在基础上它们就像巨大的分布式持久哈希表.
具体来说,我想了解概念数据设计与这些新数据库的差异.什么更容易,更难,什么不能完成?
您是否想出了在非关系世界中工作得更好的替代设计?
你有没有碰到任何看似不可能的东西?
您是否与任何设计模式弥合了差距,例如从一个设计模式转换为另一个设计模式?
你现在甚至都在做明确的数据模型(例如在UML中),还是让你完全放弃它们以支持半结构化/面向文档的数据blob?
您是否错过了RDBMS提供的任何主要额外服务,例如关系完整性,任意复杂的事务支持,触发器等?
我来自SQL关系数据库背景,所以标准化在我的血液中.也就是说,我获得了非关系数据库的优点,简化和扩展,我的直觉告诉我必须有更丰富的设计功能重叠.你做了什么?
仅供参考,这里有类似主题的StackOverflow讨论:
下一代数据库
更改架构以使用Google App Engine
选择面向文档的数据库
j-g-faustus.. 79
我刚刚开始使用非关系数据库,我仍然试图绕过它并找出最佳模型.我只能代表CouchDB.
不过,我有一些初步结论:
设计焦点发生了变化:文档模型的设计(对应于DB表)变得几乎无关紧要,而一切都取决于设计视图(对应于查询).
文档DB交换了复杂性:SQL具有不灵活的数据和灵活的查询,文档DB是另一种方式.
CouchDB模型是"JSON文档"(基本上是嵌套的哈希表)的集合.每个文档都有一个唯一的ID,可以通过ID轻松检索.对于任何其他查询,您可以编写"视图",这些视图是命名的map/reduce函数集.视图将结果集作为键/值对列表返回.
技巧是在查询SQL数据库时不查询数据库:运行视图函数的结果存储在索引中,只能查询索引.(如"获取所有内容","获取密钥"或"获取密钥范围".)
SQL世界中最接近的类比是,如果您只能使用存储过程查询数据库 - 您要支持的每个查询都必须是预定义的.
文件的设计非常灵活.我发现只有两个约束:
将相关数据保存在同一文档中,因为没有与连接相对应的内容.
不要使文档过于频繁更新(例如将所有公司的销售额放在同一文档中),因为每个文档更新都会触发重新编制索引.
但一切都取决于设计观点.
我发现替代设计使用CouchDB比任何SQL数据库更好的工作量级是系统级而不是存储级.如果您有一些数据并希望将它们提供给网页,则整个系统的复杂性至少降低50%:
没有设计DB表(小问题)
没有ODBC/JDBC中间层,所有基于http的查询和事务(中等问题)
来自JSON的简单DB到对象映射,与SQL中的相同,这几乎是微不足道的(重要!)
您可以跳过整个应用程序服务器,因为您可以使用AJAX设计要由浏览器直接检索的文档,并在显示为HTML之前添加一些JavaScript抛光.(巨大!!)
对于普通的webapps,基于文档/ JSON的数据库是一个巨大的胜利,而不太灵活的查询和一些额外的数据验证代码的缺点似乎是一个很小的代价.
还没.Map/reduce作为查询数据库的一种手段是不熟悉的,并且需要比编写SQL更多的思考.存在相当少量的基元,因此获得所需的结果主要是关于如何指定键的创造性问题.
有一个限制,查询不能同时查看两个或多个文档 - 没有连接或其他类型的多文档关系,但到目前为止没有任何东西是不可克服的.
作为示例限制,计数和总和很容易,但是CouchDB视图/查询无法计算平均值.修复:分别返回总和和计数并计算客户端的平均值.
我不确定这是否可行.它更像是一个完整的重新设计,比如将功能样式程序转换为面向对象的样式.通常,文档类型比SQL表少得多,每个文档中的数据也多.
考虑它的一种方法是查看SQL以获取插入和常见查询:例如,当客户下订单时,哪些表和列会更新?哪些月度销售报告?该信息可能应该放在同一个文档中.
即:订单的一个文档,包含客户ID和产品ID,并根据需要复制字段以简化查询.可以轻松查询文档中的任何内容,任何需要在订单和客户之间进行交叉引用的内容都必须由客户端完成.因此,如果您想按区域报告销售情况,则应该将区域代码放入订单中.
对不起,在文档DB之前从未做过多少UML :)
但是你需要某种模型来说明哪些字段属于哪些文档以及它们包含哪些类型的值.两者都是供您自己参考,以确保使用DB的每个人都知道约定.例如,如果您在文本字段中存储日期时不再出现错误,并且任何人都可以添加或删除他们感觉到的任何字段,那么您需要验证代码和约定来获取冗余.特别是如果您使用外部资源.
不.但我的背景是Web应用程序开发人员,我们只处理数据库,我们必须:)
我曾经工作过的公司制作了一个产品(一个webapp),它设计用于跨多个供应商的SQL数据库运行,而"额外服务"在数据库与数据库之间是如此不同,以至于它们必须为每个数据库单独实现.因此,将功能移出RDBMS对我们来说就不那么重要了.这甚至扩展到全文搜索.
所以无论我放弃什么,都是我从未真正拥有过的东西.显然,您的经历可能会有所不同.
需要注意的是:我现在正在研究的是一个用于财务数据,股票报价等的webapp.这是一个非常好的文档数据库匹配,从我的角度来看,我得到了数据库的所有好处(持久性和查询)没有任何麻烦.
但是这些数据相互独立,没有复杂的关系查询.通过自动收报机获取最新报价,通过自动收报机和日期范围获取报价,获取公司元信息,这几乎就是全部.我看到的另一个例子是博客应用程序,博客也没有以大量复杂的数据库模式为特征.
我想说的是,我所知道的文档数据库的所有成功应用都是首先没有太多相互关系的数据:文档(如谷歌搜索),博客文章,新闻文章,财务数据.
我希望有一些数据集可以更好地映射到SQL而不是文档模型,所以我想SQL会存活下来.
但对于我们这些只想要一种简单的方法来存储和检索数据的人 - 我怀疑我们中有很多人 - 文档数据库(如在CouchDB中)是天赐之物.
我刚刚开始使用非关系数据库,我仍然试图绕过它并找出最佳模型.我只能代表CouchDB.
不过,我有一些初步结论:
设计焦点发生了变化:文档模型的设计(对应于DB表)变得几乎无关紧要,而一切都取决于设计视图(对应于查询).
文档DB交换了复杂性:SQL具有不灵活的数据和灵活的查询,文档DB是另一种方式.
CouchDB模型是"JSON文档"(基本上是嵌套的哈希表)的集合.每个文档都有一个唯一的ID,可以通过ID轻松检索.对于任何其他查询,您可以编写"视图",这些视图是命名的map/reduce函数集.视图将结果集作为键/值对列表返回.
技巧是在查询SQL数据库时不查询数据库:运行视图函数的结果存储在索引中,只能查询索引.(如"获取所有内容","获取密钥"或"获取密钥范围".)
SQL世界中最接近的类比是,如果您只能使用存储过程查询数据库 - 您要支持的每个查询都必须是预定义的.
文件的设计非常灵活.我发现只有两个约束:
将相关数据保存在同一文档中,因为没有与连接相对应的内容.
不要使文档过于频繁更新(例如将所有公司的销售额放在同一文档中),因为每个文档更新都会触发重新编制索引.
但一切都取决于设计观点.
我发现替代设计使用CouchDB比任何SQL数据库更好的工作量级是系统级而不是存储级.如果您有一些数据并希望将它们提供给网页,则整个系统的复杂性至少降低50%:
没有设计DB表(小问题)
没有ODBC/JDBC中间层,所有基于http的查询和事务(中等问题)
来自JSON的简单DB到对象映射,与SQL中的相同,这几乎是微不足道的(重要!)
您可以跳过整个应用程序服务器,因为您可以使用AJAX设计要由浏览器直接检索的文档,并在显示为HTML之前添加一些JavaScript抛光.(巨大!!)
对于普通的webapps,基于文档/ JSON的数据库是一个巨大的胜利,而不太灵活的查询和一些额外的数据验证代码的缺点似乎是一个很小的代价.
还没.Map/reduce作为查询数据库的一种手段是不熟悉的,并且需要比编写SQL更多的思考.存在相当少量的基元,因此获得所需的结果主要是关于如何指定键的创造性问题.
有一个限制,查询不能同时查看两个或多个文档 - 没有连接或其他类型的多文档关系,但到目前为止没有任何东西是不可克服的.
作为示例限制,计数和总和很容易,但是CouchDB视图/查询无法计算平均值.修复:分别返回总和和计数并计算客户端的平均值.
我不确定这是否可行.它更像是一个完整的重新设计,比如将功能样式程序转换为面向对象的样式.通常,文档类型比SQL表少得多,每个文档中的数据也多.
考虑它的一种方法是查看SQL以获取插入和常见查询:例如,当客户下订单时,哪些表和列会更新?哪些月度销售报告?该信息可能应该放在同一个文档中.
即:订单的一个文档,包含客户ID和产品ID,并根据需要复制字段以简化查询.可以轻松查询文档中的任何内容,任何需要在订单和客户之间进行交叉引用的内容都必须由客户端完成.因此,如果您想按区域报告销售情况,则应该将区域代码放入订单中.
对不起,在文档DB之前从未做过多少UML :)
但是你需要某种模型来说明哪些字段属于哪些文档以及它们包含哪些类型的值.两者都是供您自己参考,以确保使用DB的每个人都知道约定.例如,如果您在文本字段中存储日期时不再出现错误,并且任何人都可以添加或删除他们感觉到的任何字段,那么您需要验证代码和约定来获取冗余.特别是如果您使用外部资源.
不.但我的背景是Web应用程序开发人员,我们只处理数据库,我们必须:)
我曾经工作过的公司制作了一个产品(一个webapp),它设计用于跨多个供应商的SQL数据库运行,而"额外服务"在数据库与数据库之间是如此不同,以至于它们必须为每个数据库单独实现.因此,将功能移出RDBMS对我们来说就不那么重要了.这甚至扩展到全文搜索.
所以无论我放弃什么,都是我从未真正拥有过的东西.显然,您的经历可能会有所不同.
需要注意的是:我现在正在研究的是一个用于财务数据,股票报价等的webapp.这是一个非常好的文档数据库匹配,从我的角度来看,我得到了数据库的所有好处(持久性和查询)没有任何麻烦.
但是这些数据相互独立,没有复杂的关系查询.通过自动收报机获取最新报价,通过自动收报机和日期范围获取报价,获取公司元信息,这几乎就是全部.我看到的另一个例子是博客应用程序,博客也没有以大量复杂的数据库模式为特征.
我想说的是,我所知道的文档数据库的所有成功应用都是首先没有太多相互关系的数据:文档(如谷歌搜索),博客文章,新闻文章,财务数据.
我希望有一些数据集可以更好地映射到SQL而不是文档模型,所以我想SQL会存活下来.
但对于我们这些只想要一种简单的方法来存储和检索数据的人 - 我怀疑我们中有很多人 - 文档数据库(如在CouchDB中)是天赐之物.
我认为您必须考虑非关系型DBMS在数据模型方面存在很大差异,因此概念数据设计也会有很大差异.在NOSQL Google组的非关系数据库中的数据设计中,不同的范例分类如下:
类似Bigtable的系统(HBase,Hypertable等)
键值商店(东京,伏地魔等)
文档数据库(CouchDB,MongoDB等)
图数据库(AllegroGraph,Neo4j,Sesame等)
我主要是使用图形数据库,使用这种模式的数据设计的优雅是让我在那里的原因,厌倦了RDBMS的缺点.我在这个维基页面上使用图形数据库提供了一些数据设计示例,并且还有一个如何建模基本IMDB电影/演员/角色数据的示例.
演示幻灯片(SlideShare上)图形数据库和大规模的知识管理未来的马尔科·罗德里格斯包含使用图形数据库,以及一个非常好的介绍,数据设计.
从graphdb的角度回答具体问题:
替代设计:添加许多不同类型实体之间的关系,无需担心或需要预定义哪些实体可以连接.
缩小差距:我倾向于根据域本身对每种情况做不同的事情,因为我不想要"面向表格的图表"等.但是,这里有一些关于从RDBMS到graphdb的自动转换的信息.
显式数据模型:我一直这样做(白板风格),然后在数据库中使用模型.
来自RDBMS世界的小姐:创建报告的简便方法.更新:也许这不是说努力创造从图形数据库报告,请参阅创建一个Neo4j的SAMPLE数据库的报告.
我在脑海中回答了CouchDB这个问题,但我认为大多数人对其他数据库也是如此.我们考虑使用CouchDB,但最终决定反对它,因为我们的数据访问事先是未知的,可扩展性不是问题.
更难:
需要在概念层面进行重新思考,因为它更加"难",因为它只是不同.由于您必须事先了解数据访问模式,因此不能应用自动转换.您至少需要添加访问模式.
数据库不处理一致性,但必须在应用程序中处理.较少的保证意味着更容易的迁移,故障转移和更好的可扩展性,代价是更复杂的应用程序.应用程序必须处理冲突和不一致.
跨文档(或键/值)的链接也必须在应用程序级别处理.
SQL类型的数据库具有更成熟的IDE.您获得了许多支持库(尽管这些库的分层使得事情比SQL需要的要复杂得多).
更轻松:
如果您了解数据访问模式,则会更快.
迁移/故障转移对于数据库来说更容易,因为作为应用程序员不会对您做出承诺.虽然你获得了最终的一致性.大概.最后.一段时间.
一个键/值比表中的一行更容易理解.所有(树)关系已经存在,并且可以识别完整的对象.
建模应该大致相同,但你必须要小心你在一个文档中放置的东西:UML也可以用于OO建模和DB建模,它们已经是两种不同的动物.
我本来希望看到一个很好的开放式OO数据库与C#/ Silverlight很好地集成.只是为了让选择变得更加困难.:)