13

这更像是“内部运作”不解的问题:

不支持 * A *CID(意味着它们不能在单个事务中更新/插入然后回滚多个对象的数据)的 noSQL 数据库如何更新二级索引?

我的理解是——为了保持二级索引同步(否则它会变得陈旧读取)——这必须发生在同一个事务中。

此外,如果索引可以驻留在与数据不同的主机上,则需要存在分布式锁和/或两阶段提交,这样更新才能以原子方式工作。

但是如果这些数据库不支持多对象事务(这意味着它们不会对跨多个主机的数据进行两阶段提交),那么它们使用什么方法来保证驻留在 B 树结构中的二级索引与数据不陈旧?

4

3 回答 3

22

这是一个很好的问题。

RethinkDB 始终将二级索引与表的主索引/数据存储在同一主机上。即使在连接的情况下,RethinkDB 也会对数据进行查询,因此二级索引、主索引和数据始终位于同一节点上。因此,不需要分布式锁定协议,例如两阶段提交。

RethinkDB 确实支持一组有限的事务功能——单文档事务。对单个文档的更改以原子方式记录。相关的二级索引更改也被记录为该事务的一部分,因此要么记录整个更改,要么根本不记录任何内容。

扩展有限的事务功能以支持单个分片中的多个文档很容易,但跨分片很难做到(出于您提出的分布式锁定原因),因此我们决定不为多个文档实现事务然而。

希望这可以帮助。

于 2013-08-12T20:08:51.050 回答
3

RethinkDB 总是将二级索引数据存储在与其索引的数据相同的机器上。这允许它在同一事务中更新。Rethink 承诺在单个文档操作中是 ACIDy,并将文档的索引视为文档本身的一部分。

于 2013-08-12T19:30:20.323 回答
3

这是一个 MongoDB 答案。

我不太确定你的逻辑是什么。更新二级索引与能够回滚多语句事务(例如多次更新)无关。

MongoDB 每个文档都有事务,这对于更新索引很重要。如果需要,可以使用日志来撤销这些操作。

这必须发生在同一笔交易中。

是的,就像 RDBMS 一样。你应用的索引越多,你的写入速度就越慢,在我看来你知道为什么。

当写入发生时,MongoDB 将使用适用于特定索引的字段更新适用于该集合的所有索引。

此外,如果索引可以驻留在与数据不同的主机上

我不确定 MongoDB 是否允许这样做,我相信它有一个 JIRA;但是,我目前找不到那个 JIRA。

然后需要存在分布式锁和/或两阶段提交,这样更新才能以原子方式工作。

最有可能的。允许此功能将......好吧,我们只是说创建一个毛球。

即使在分片设置中,每个范围的索引也驻留在分片本身上,而不是在配置服务器上。

但是如果这些数据库不支持多对象事务(这意味着它们不会跨多个主机对数据进行两阶段提交)

这不是两阶段提交的意思。我相信您需要了解什么是两阶段提交:http ://docs.mongodb.org/manual/tutorial/perform-two-phase-commits/

我想如果您谈论的是涵盖多个分片的交易,那么,嗯,好的。

他们使用什么方法来保证驻留在与数据分开的 B 树结构中的二级索引不会过时?

Agan 我不确定为什么多文档事务会影响索引是否过时,您没有跨文档分组。唯一的例外是唯一索引,但也适用于单个文档更新;请注意,它的唯一性在分片设置中有点毛茸茸,无法保证。

在您正在创建的索引中,通常每个文档前缀键都有一个条目,除非它是文档上的多键索引,那么您可以创建多个索引,但是,无论哪种方式索引更新都是针对单个对象完成的,而不是通过多文档交易,我不确定你在这里的逻辑是什么,因此这是我给出的答案。

于 2013-08-10T20:36:02.777 回答