Sql 在Cosmos DB中是否可以创建一个单独链接的文档列表?

Sql 在Cosmos DB中是否可以创建一个单独链接的文档列表?,sql,json,database,azure-cosmosdb,document-database,Sql,Json,Database,Azure Cosmosdb,Document Database,我通常解决的一个问题是保持文档的不变版本,而不是编辑文档。当询问文档时,检索最新版本 一种方法是使用时间戳: 文件0: { id: "e69e0bea-77ea-4d97-bedf-d3cca27ae4b6", correlationId: "d00be916-10e3-415c-aaf6-9acb7c70cf4f", created: "11/17/2018 2:20:25 AM", value: "foo" } 文件1: { id: "37ef6f99-bc8

我通常解决的一个问题是保持文档的不变版本,而不是编辑文档。当询问文档时,检索最新版本

一种方法是使用时间戳:

文件0:

{
   id: "e69e0bea-77ea-4d97-bedf-d3cca27ae4b6",
   correlationId: "d00be916-10e3-415c-aaf6-9acb7c70cf4f",
   created: "11/17/2018 2:20:25 AM",
   value: "foo"
}
文件1:

{
   id: "37ef6f99-bc87-45bb-87ae-a1b81070cc91",
   correlationId: "d00be916-10e3-415c-aaf6-9acb7c70cf4f",
   created: "11/17/2018 2:20:44 AM",
   value: "bar"
}
{
   id: "37ef6f99-bc87-45bb-87ae-a1b81070cc91",
   previousId: "e69e0bea-77ea-4d97-bedf-d3cca27ae4b6",
   correlationId: "d00be916-10e3-415c-aaf6-9acb7c70cf4f",
   created: "11/17/2018 2:20:44 AM",
   value: "bar"
}
文件2:

{
   id: "93fc913e-5ecc-4c59-a130-0e577ed4f2fb",
   correlationId: "d00be916-10e3-415c-aaf6-9acb7c70cf4f",
   created: "11/17/2018 2:21:51 AM",
   value: "baz"
}
{
   id: "93fc913e-5ecc-4c59-a130-0e577ed4f2fb",
   previousId: "37ef6f99-bc87-45bb-87ae-a1b81070cc91",
   correlationId: "d00be916-10e3-415c-aaf6-9acb7c70cf4f",
   created: "11/17/2018 2:21:51 AM",
   value: "baz"
}
使用时间戳的缺点是您必须按时间戳(
O(n*log(n))
)排序才能获得第n个最新版本

我希望通过存储指向上一版本的指针来实现这个
O(n)
,如

{
   id: "e69e0bea-77ea-4d97-bedf-d3cca27ae4b6",
   previousId: null,
   correlationId: "d00be916-10e3-415c-aaf6-9acb7c70cf4f",
   created: "11/17/2018 2:20:25 AM",
   value: "foo"
}
文件1:

{
   id: "37ef6f99-bc87-45bb-87ae-a1b81070cc91",
   correlationId: "d00be916-10e3-415c-aaf6-9acb7c70cf4f",
   created: "11/17/2018 2:20:44 AM",
   value: "bar"
}
{
   id: "37ef6f99-bc87-45bb-87ae-a1b81070cc91",
   previousId: "e69e0bea-77ea-4d97-bedf-d3cca27ae4b6",
   correlationId: "d00be916-10e3-415c-aaf6-9acb7c70cf4f",
   created: "11/17/2018 2:20:44 AM",
   value: "bar"
}
文件2:

{
   id: "93fc913e-5ecc-4c59-a130-0e577ed4f2fb",
   correlationId: "d00be916-10e3-415c-aaf6-9acb7c70cf4f",
   created: "11/17/2018 2:21:51 AM",
   value: "baz"
}
{
   id: "93fc913e-5ecc-4c59-a130-0e577ed4f2fb",
   previousId: "37ef6f99-bc87-45bb-87ae-a1b81070cc91",
   correlationId: "d00be916-10e3-415c-aaf6-9acb7c70cf4f",
   created: "11/17/2018 2:21:51 AM",
   value: "baz"
}
所以它是一个链表,就像

NULL <- doc0 <- doc1 <- doc2

<>但是我不确定数据库级别是否有可能。

你考虑了COSMOS DB图形API吗?链表实际上是一种非常基本的图形形式

您正在做的看起来不错,但是更新相关id可能会很混乱。有了graph API,问题就不存在了

在第一条评论之后更新答案:

这就是我们使用SQLAPI可以做的。 链可以建模为:

NULL <- Doc1 <- Doc2 <- Doc3 <- Head.
这整片都是原子的。如果另一个并发线程已成功更新H,则当前存储的进程将失败,并出现“Premission”failed错误(由于_etag不匹配),整个存储的进程将回滚

没有锁定的概念,但在您的情况下,您可以利用唯一的键约束:

  • 使用
    correlationId
    作为逻辑分区键创建分区集合
  • 添加唯一的密钥约束,密钥基于
    previousId
此时,对于给定的
correlationId
,如果您试图在列表中创建一个新链接,而之前又创建了另一个链接,则会在
previousId
上遇到冲突,然后您就可以使用刚刚创建的
previousId
文档id重新执行操作


注意:每个文档都有一个ETag,它有助于在更新文档时提高并发性,以防您决定在某个时候使用更新。

使用图形如何解决问题?无论是使用core(SQL)API还是Gremlin(graph)API,都存在同样的问题
CorrelationID
不是问题所在(我不明白为什么会这样)。如果两个编写器尝试将一个顶点添加到图中,并通过edge连接到已知的最新版本的顶点,则会出现与核心API相同的并发问题。David,我已更新了响应。我建议使用graph API主要是为了便于创建链。我误解了这个问题,认为链的创建是主要问题,并发性问题只是使用SQLAPI创建链的产物。