3

我有 Orm 框架的经验,我开始了解 NoSql 数据库解决方案的结构。我将继续使用一些基于对象模型的示例。

我有以下文档模型,我想考虑一些场景处理。

  1. 用几个标签保存帖子
  2. 显示带有帖子计数的标签列表
  3. 更新标签

public class Post
{
    public string Title { get; set; }
    public List<Tag> Tags { get; set; }
}

public class Tag
{
    public string Name { get; set; }
}

关于我的场景,我脑海中几乎没有出现任何问题。

帖子类是一个将使用标签保存的文档。在 RDBMS 中,Tag 和 Post 具有多对多关系,但我知道它在 NoSql 中没有任何关系,因此 post 对象与整个成员一起保存。因此显示带有 post 计数场景的标签列表将导致整个 post 项中的大量查询在每个查询中都付出了一些努力,所以在这种情况下我不会失去 NoSql 功能的所有好处吗?

更新一个标签名会不会造成一些复杂的工作?我必须查询整个帖子项目并发现它具有该标签名称并对其进行更新。顺便说一句,它需要多文档事务和长流程,因此失败会导致我的数据库不一致,因为 NoSql 中不支持多文档事务,所以我该如何处理?

我并不是要展示 NoSql 对 RDBMS(Sql) 系统的缺点。我只是想了解我对这个场景的想法是否正确,可能有些东西我错过了,或者看起来很糟糕的事情并不像我想象的那样糟糕。我需要可扩展性,这就是我对 NoSql 解决方案感兴趣的原因。

4

1 回答 1

0

起初,NoSQL 只是一个流行词,它涵盖了许多不同的数据库类型,如键值存储、文档存储、图形数据库……有关不同类型和实现的列表,请参见http://nosql-database.org/ . 其中一些系统还具有事务保证,例如,对于您的情况,将 Post 完全写入数据库。

我现在将专注于键值存储,因为它们似乎是一个非常突出的 NoSQL 实例。

关于您的第一个问题:您是对的,在 RDBMS 中不会使用像外键这样的严格关系,但您只需保留与 post 实例关联的标签列表:

| pid | title | tags
|  1  | foo   | sql, rdbms
|  2  | bar   | sql, acid
...

对于按标签查询,您有一个所谓的倒排索引( http://en.wikipedia.org/wiki/Inverted_index ),它为您提供一个标签的所有文档 ID:

| tag   | pids
| sql   | 1, 2
| rdbms | 1
| acid  | 2

这使得进行帖子计数变得非常容易。

更新标签名称实际上并不复杂,如果您对数据具有基于 map-reduce 的访问权限,那么您可以通过简单的工作(伪代码)将标签“Sql”更新为“SQL”:

map:    IF post.tag contains('Sql') THEN emit(post)

reduce: in post.tag: replace('Sql' by 'SQL')
        write(post)

但我不认为,重命名标签是一件常见的事情。Brewer 在 CAP 定理 ( http://en.wikipedia.org/wiki/CAP_theorem )中说明了处理时间长和不一致的问题,基本上说您不能同时具有一致性、可用性和分区容错性,你必须至少用一个换另外两个。在您的情况下:如果您想对标签进行一致的更新(这样就无法读取两个文档,其中一个具有标签“Sql”而另一个已经具有“SQL”),您必须锁定表以供其他读者,因此您将没有可用性。

最后的想法:如果你想构建一个高可用、良好的扩展平台,你不想以关系的方式思考太多。

于 2013-07-20T12:14:34.557 回答