你如何跟踪NoSQL中的logging关系?

我试图找出在NoSQL KVP或文档数据库中的外键和索引的等价物。 由于没有关键表(要添加标记两个对象之间的关系的键),所以我非常难以确定如何以一种对普通网页有用的方式检索数据。

假设我有一个用户,并且这个用户在整个网站上留下了很多评论。 我能想到跟踪用户评论的唯一方法是

  1. 将它们embedded到用户对象中(这似乎很无用)
  2. 创build并维护一个user_id:comments值,其中包含每个评论的关键字列表[评论:34,评论:197等],以便我可以根据需要获取它们。

然而,拿第二个例子来说,当你用它来跟踪其他东西,比如一个叫做“active_comments”的键时,你可能很快就会碰到一堵砖墙,这个键可能包含了三千万个ID,使得查询每个页面只是为了了解一些最近的东西积极的评论。 它也会很容易出现竞争状况,因为许多页面可能会尝试同时更新它。

如何在NoSQL数据库中跟踪以下关系?

  • 所有用户的评论
  • 所有活跃的评论
  • 所有标有[关键字]
  • 所有在俱乐部的学生 – 或者所有学生所在的俱乐部都在

还是我错误地想这个?

关于如何以“NoSQL方式”存储多对多关联的所有答案都减less了同样的事情: 冗余存储数据。

在NoSQL中,您不根据数据实体之间的关系来devise数据库。 你根据你将运行的查询devise你的数据库。 使用与标准化关系数据库相同的标准:如果数据具有凝聚力更重要(用逗号分隔的列表而不是标准化表格来表示值),那么就这样做。

但是,这会不可避免地优化一种types的查询(例如,任何用户针对给定文章的评论),而牺牲其他types的查询(给定用户对任何文章的评论)。 如果您的应用程序需要对两种types的查询进行同等优化,则不应该进行非规范化。 同样,如果您需要以关系方式使用数据,则不应使用NoSQL解决scheme。

非规范化和冗余存在风险,冗余数据集将彼此不同步。 这被称为exception 。 当您使用规范化的关系数据库时,RDBMS可以防止exception。 在非规范化数据库或NoSQL中,编写应用程序代码以防止exception成为您的责任。

有人可能会认为对于NoSQL数据库来说,做好预防exception的努力是非常好的。 有一个范式可以做到这一点 – 关系范式。

  1. user:userid:comments是一种合理的方法 – 把它看作SQL中列索引的等价物,并增加了你不能在未索引列上查询的要求。

  2. 这是你需要考虑你的需求的地方。 一个拥有3000万件物品的清单是不合理的,因为它是缓慢的,但是因为用它做任何事情都是不切实际的。 如果你真正的要求是显示一些最新的评论,你最好保留一个非常短的列表,每当添加评论时都会更新 – 请记住,NoSQL没有规范化的要求。 竞争条件是基本键值存储中的列表问题,但通常您的平台可以正确支持列表,您可以使用locking来做某些事情,或者实际上并不关心失败的更新。

  3. 与用户评论相同 – 创build索引关键字:post

  4. 更多相同的 – 可能是作为学生的财产俱乐部列表和该领域的索引,以获得俱乐部的所有成员

couchDB的方法build议在地图阶段发布适当类别的东西,并在reduce中进行总结。因此,您可以映射所有评论,并为给定的用户发射1 ,并稍后打印出唯一的评论。 这将需要大量的磁盘存储,以构buildcouchDB中所有可跟踪数据的持久视图。 顺便说一句,他们也有这个维基页面的关系: http : //wiki.apache.org/couchdb/EntityRelationship 。

Riak另一方面有build立关系的工具。 这是链接。 您可以input链接(这里是注释)文件的地址到“根”文件(这里是用户文件)。 它有一个窍门。 如果它是分布式的,它可能在许多地方一次被修改。 它会导致冲突,结果是巨大的vector时钟树:/ ..不好,不太好。

里亚克还有另外一个“机制”。 它有两层密钥名字空间,所谓的存储桶和密钥。 因此,对于学生来说,如果我们有A,B和C俱乐部以及StudentX学生,您可以保持以下惯例:

 { Key = {ClubA, StudentX}, Value = true }, { Key = {ClubB, StudentX}, Value = true }, { Key = {ClubA, StudentY}, Value = true } 

并在给定的桶中读取关系只是列表键。 那有什么不对? 这是该死的缓慢。 上市桶从来没有优先riak。 这是越来越好,寿。 顺便说一句。 你不会浪费内存,因为这个例子{true}可以链接到StudentX或Y的单个完整configuration文件(这里不可能有冲突)。

就像你看到的那样NoSQL!= NoSQL。 您需要查看具体的实现并自行testing。

Column之前提到的商店看起来很适合关系..但这一切都取决于你的A和C和P的需求;)如果你不需要A,并且你有小于Peta字节只是离开它,继续与MySql或Postgres。

祝你好运

你有

 "user": { "userid": "unique value", "category": "student", "metainfo": "yada yada yada", "clubs": ["archery", "kendo"] } "comments": { "commentid": "unique value", "pageid": "unique value", "post-time": "ISO Date", "userid": "OP id -> THIS IS IMPORTANT" } "page": { "pageid": "unique value", "post-time": "ISO Date", "op-id": "user id", "tag": ["abc", "zxcv", "qwer"] } 

那么在一个关系数据库中,正常的事情是在一对多关系中规范化数据。 在NoSQL数据库中,您也会这样做。 只需索引您将要获取信息的字段。

例如,你的重要指标是

  • Comment.UserID
  • Comment.PageID
  • Comment.PostTime
  • Page.Tag []

如果你正在使用NosDB(一个基于.NET的NoSQL数据库和SQL支持),你的查询将会是这样的

  SELECT * FROM Comments WHERE userid = 'That user'; SELECT * FROM Comments WHERE pageid = 'That user'; SELECT * FROM Comments WHERE post-time > DateTime('2016, 1, 1'); SELECT * FROM Page WHERE tag = 'kendo' 

从SQL备忘单或文档中检查所有支持的查询types。

我认为RavenDB提供索引的这个问题的一个很好的解决scheme。 主页面http://ravendb.net/上的信息可以很好地解释这个概念,您可以为您的技术创build类似的东西。;