如何在最终一致的数据库上实现列表?

时间:2010-05-04 11:41:05

标签: database-design list nosql

我想在Cassandra,Riak或任何其他最终一致的商店上实现列表和队列。这有可能吗?我怎么能这样做?

我正在寻找通用算法。

5 个答案:

答案 0 :(得分:2)

我不完全明白。什么列表/队列?您可以创建一个(一个/多个)文档,其中包含其中的每个队列/列表。你的意思是关于查询等(听起来有点像SQL思考)?

有关建模而非建模事物的非常好的文章可以在这里找到:

怎么不这样做 http://ayende.com/blog/4465/that-no-sql-thing-the-relational-modeling-anti-pattern-in-document-databases

怎么做 http://ayende.com/Blog/archive/2010/04/21/that-no-sql-thing-modeling-documents-in-a-document-database.aspx

如果我理解你错了请澄清:)

答案 1 :(得分:1)

你可以使用不同的路线并使用Lucene存储你的“列表”,只需在Lucene中添加一个列,用于“会话索引”或者你正在做什么。

有关详细信息,请参阅Lucandra项目。此外,Sematext blog有一个很好的写作。

答案 2 :(得分:1)

免责声明:我不熟悉Casandra或Riak。这适用于一般的“数据库”(不一定是关系型,分布式等)。

我假设您能够存储和访问“键值对”(即一对值(a,b),其中a是值b的关键。)

我还会用这种表示法来表示一些通用的“对象”(数据结构,对象,字典,......):人[姓名:“John Doe”年龄:49]。

实施链表

假设你有一个键值对(键,值)和一个对象Object [fields:values ...],可以通过

在数据库中实现一个链表。
  1. 通过定义Object [fields:values ... next] OR
  2. 向对象添加“next”字段
  3. 创建一个新的“持有者对象”,定义为(key,value)= Holder [Object [fields:values ...] next]
  4. 将链表的第一个值存储在一些特殊的键值对中也是一个可能的想法,如(第一,......)。

    在任何一种情况下,都可以在数据库中实现链接列表。

    从键值对中提取值时,要获取下一个值,只需找到Holder或Object的“next”字段,将列表遍历到下一个值,等等。

    示例链接列表算法

    搜索:

    def find(first, node):
        if node = first[next]:
            return first[next]
        else:
            find(first[next], node)
    

    搜索前任:

    def find_pred(first, node):
        if node = first[next]:
            return first
        else:
            find_pred(first[next], node)
    

    在特定节点之前插入:

    def insert_at_front(node, inserted_node):
        find_pred(node)[next] = inserted_node
        inserted_node[next] = node
    

    队列的实现

    在这种情况下,队列可以只是一个链接列表,其中自动知道两个特定值(可能存储在数据库中):

    1. 可以使用特殊键值对(head,...)存储的第一个元素(或头部)
    2. 可以使用特殊键值对(tail,...)存储的最后一个元素(或尾部)
    3. 注意:这些算法是故意简化的;它们不是任何特定的语言,不处理异常,列表末尾等,不应该用于等等,等等,等等......

答案 3 :(得分:1)

看看Cages项目。它可能对您的用例有所帮助。 http://ria101.wordpress.com/2010/05/12/locking-and-transactions-over-cassandra-using-cages/

它基本上使用ZooKeeper集群进行锁定,以便您可以在数据中保持逻辑一致性。当您的应用程序想要修改列表时,它可以保持锁定,以便其他用户不会同时修改它。

答案 4 :(得分:1)

不确定您想要支持哪些操作,也不熟悉Riak等。 al。,但这是CouchDB的一个可能的实现,另一个最终一致的DB。

我假设map / reduce操作返回一个或多个键/值对,结果按键排序顺序返回,查询键和键范围是基本操作。 (CouchDB这样做,不了解其他人。)

假设你想支持迭代,推送和弹出,你可以拥有一个带

的文档
  • 文档ID :可能是UUID或其他有意义的内容,因此每个条目都会获得唯一ID,并且在合并期间不会导致冲突。
  • 排名键:提供相对排序。可以是时间戳或全局计数器,关键是键的排序顺序与列表中的相对排序相同。当排名键与文档ID不同时,冲突无关紧要,您仍然可以通过对键进行排序来获得正确顺序的列表/队列。如果您需要唯一的订购,请在密钥上附加客户端ID或其他内容。示例键:[123, "client1"]将在[123, "client2"]之前排序。 (此处的细节可能因DB而异,但即使键只是字符串,也可以使用此技巧。)
  • value :此列表元素的内容

操作

  • list / iterate :返回按排名键排序的所有元素,在客户端上迭代。如果数据集很大,则迭代关键子范围。
  • head tail :返回具有最小或最大排名键的元素的查询。
  • push :插入一个排名密钥高于现有最高级别的新文档。
  • pop :检索并删除排名最低的文档