在工作中,我们最近开始了一个使用 CouchDB(面向文档的数据库)的项目。我一直很难忘记我所有的关系数据库知识。
我想知道你们中的一些人是如何克服这个障碍的?你是如何停止相关性思考并开始记录性思考的(我为编造这个词道歉)。
有什么建议么?有帮助的提示?
编辑:如果有什么不同,我们使用 Ruby 和 CouchPotato 连接到数据库。
编辑 2:SO 让我接受答案。我认为,我选择了最能帮助我学习的那个。但是,我想没有真正的“正确”答案。
在工作中,我们最近开始了一个使用 CouchDB(面向文档的数据库)的项目。我一直很难忘记我所有的关系数据库知识。
我想知道你们中的一些人是如何克服这个障碍的?你是如何停止相关性思考并开始记录性思考的(我为编造这个词道歉)。
有什么建议么?有帮助的提示?
编辑:如果有什么不同,我们使用 Ruby 和 CouchPotato 连接到数据库。
编辑 2:SO 让我接受答案。我认为,我选择了最能帮助我学习的那个。但是,我想没有真正的“正确”答案。
我认为,在仔细阅读有关此主题的几页之后,这完全取决于您正在处理的数据类型。
RDBMS 代表一种自上而下的方法,在这种方法中,作为数据库设计者,您可以断言数据库中将存在的所有数据的结构。您定义一个人有一个名字、姓氏、中间名和家庭地址等。您可以使用 RDBMS 强制执行此操作。如果您没有关于个人的 HomePlanet 的列,那么不幸的想要成为与地球不同的 HomePlanet 的人;您必须在以后添加一列,否则数据无法存储在 RDBMS 中。无论如何,大多数程序员都会在他们的应用程序中做出这样的假设,因此假设和执行这并不是一件愚蠢的事情。定义事物可能是好的。但是,如果您将来需要记录其他属性,则必须将它们添加进去。关系模型假定您的数据属性不会发生太大变化。
使用 MapReduce 之类的“云”类型数据库,在您的情况下是 CouchDB,不要做出上述假设,而是从下往上查看数据。数据在文档中输入,文档可以具有任意数量的不同属性。它假设您的数据,根据其定义,它可能具有的属性类型是多种多样的。它说:“我只知道我在数据库 Person 中有这个文档,它的 HomePlanet 属性为“Eternium”,FirstName 为“Lord Nibbler”,但没有 LastName。该模型适合网页:所有网页都是一个文档,但文档的实际内容/标签/键差异很大,以至于您无法将它们放入 DBMS 高高在上的僵化结构中。这就是为什么 Google 认为 MapReduce 模型 roxors soxors,因为 Google' s 数据集非常多样化,需要从一开始就构建模糊性,并且由于海量数据集能够利用并行处理(MapReduce 使这变得微不足道)。文档数据库模型假设您的数据属性可能/将会发生很大变化或非常多样化,如果数据存储在关系数据库中,则可能会发现“间隙”和大量稀疏填充的列。虽然您可以使用 RDBMS 来存储这样的数据,但它会很快变得丑陋。如果数据存储在关系数据库中,则可能会发现许多填充稀疏的列。虽然您可以使用 RDBMS 来存储这样的数据,但它会很快变得丑陋。如果数据存储在关系数据库中,则可能会发现许多填充稀疏的列。虽然您可以使用 RDBMS 来存储这样的数据,但它会很快变得丑陋。
然后回答您的问题:在查看使用 MapReduce 范式的数据库时,您根本无法“关联地”思考。因为,它实际上并没有强制关系。这是一个概念上的障碍,你只需要克服。
我遇到的一篇很好地比较和对比了这两个数据库的文章是MapReduce: A Major Step Back,它认为 MapReduce 范式数据库是技术上的倒退,不如 RDBMS。我不得不不同意作者的论点,并认为数据库设计者只需为他/她的情况选择合适的。
一切都与数据有关。如果您拥有对关系最有意义的数据,则文档存储可能没有用处。一个典型的基于文档的系统是一个搜索服务器,你有一个庞大的数据集并且想要找到一个特定的项目/文档,该文档是静态的,或者是版本化的。
在存档类型的情况下,文档可能实际上是文档,不会更改并且具有非常灵活的结构。将它们的元数据存储在关系数据库中是没有意义的,因为它们都非常不同,因此很少有文档可以共享这些标签。基于文档的系统不存储空值。
当非规范化时,非关系/类似文档的数据是有意义的。它没有太大变化,或者您不太关心一致性。
如果您的用例非常适合关系模型,那么可能不值得将其压缩到文档模型中。
这是一篇关于非关系数据库的好文章。
另一种思考方式是,文档是一行。有关文档的所有内容都在该行中,并且特定于该文档。行很容易拆分,因此缩放更容易。
在 CouchDB 中,就像 Lotus Notes 一样,您真的不应该将 Document 视为类似于一行。
相反,文档是一个关系(表)。
每个文档都有许多行——字段值:
ValueID(PK) Document ID(FK) Field Name Field Value
========================================================
92834756293 MyDocument First Name Richard
92834756294 MyDocument States Lived In TX
92834756295 MyDocument States Lived In KY
每个视图都是一个交叉表查询,它在每个文档的大量 UNION ALL 中进行选择。
因此,它仍然是关系型的,但不是最直观的意义上,也不是最重要的意义上:良好的数据管理实践。
面向文档的数据库不拒绝关系的概念,它们只是有时让应用程序取消引用链接(CouchDB),甚至直接支持文档之间的关系(MongoDB)。更重要的是 DODB 是无模式的。在基于表的存储中,可以通过大量开销来实现此属性(请参阅richardtallent 的回答),但在这里它的效率更高。当从 RDBMS 切换到 DODB 时,我们真正应该学习的是忘记表并开始考虑数据。这就是sheepsimulator 所说的“自下而上”的方法。这是一个不断发展的模式,而不是预定义的 Procrustean 床。当然,这并不意味着应该以任何形式完全放弃图式。您的应用程序必须解释数据,
也许你应该阅读这个 http://books.couchdb.org/relax/getting-started
我自己刚刚听到它,它很有趣,但不知道如何在现实世界的应用程序中实现它;)
您可以尝试的一件事是获取 firefox 和 firebug 的副本,并在 javascript 中使用map和reduce函数。它们实际上很酷很有趣,并且似乎是如何在 CouchDB 中完成工作的基础
这是乔尔关于这个主题的小文章:http: //www.joelonsoftware.com/items/2006/08/01.html