针对CRUD场景的NoSql更新机制

本文关键字:NoSql 更新 新机制 CRUD 针对 | 更新日期: 2023-09-27 18:11:59

我有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; }
}

我的脑海中很少出现关于我的场景的问题。

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

更新标签名称会不会造成一些复杂的作业?我必须查询整个帖子项目,发现它有那个标签名称和更新它。顺便说一下,它需要多文档事务和漫长的过程,所以失败会导致我的数据库不一致,因为NoSql中不支持多文档事务,所以我怎么处理这个?

我并不是要展示NoSql相对于RDBMS(Sql)系统的缺点。我只是想知道我对这个场景的想法是否正确,可能是我错过了什么,或者事情看起来不像我想象的那么糟糕。我需要可扩展性,所以这就是为什么我对NoSql解决方案感兴趣。

针对CRUD场景的NoSql更新机制

起初,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'标记),您必须为其他读取器锁定表,因此您将没有可用性。

最后的想法:如果你想建立一个高可用性,良好的可扩展性平台,你不想在关系方式上考虑太多。