代码之家  ›  专栏  ›  技术社区  ›  mohsenJsh MohammadTaha Sameni

Cassandra用户聊天桌设计

  •  1
  • mohsenJsh MohammadTaha Sameni  · 技术社区  · 7 年前

    我想在Cassandra中创建一个用于用户聊天的表,最后我做了这个

    CREATE TABLE sample.user_messages (
        user_id INT,
        second_user_id INT,
        id TIMEUUID,
        author_id INT,
        message TEXT,
        PRIMARY KEY ((user_id), second_user_id, id)
    ) WITH CLUSTERING ORDER BY (second_user_id ASC, id DESC);
    

    我有两种疑问

    1. 获取此表设计满足的两个用户之间的聊天 ... where user_id=100 and second_user_id=200

    2. 获取此表设计不适合的特定用户的所有聊天 我也不知道该怎么做,因为我应该使用两个查询,1- ... where user_id=100' 2… where second_user_id=100 哪一个查询不好,还有什么方法可以只使用一个查询吗?

    3 回复  |  直到 6 年前
        1
  •  3
  •   Mikhail Baksheev    7 年前

    您的表允许您按用户ID获取所有聊天记录,因此您可以将数据两次插入此表,但在第二次插入时更改用户ID。

    为第一个用户放置消息:

    UPDATE user_messages SET .... second_user_id = 200 WHERE user_id = 100;
    

    并为第二个用户输入相同的消息:

    UPDATE user_messages SET .... second_user_id = 100 WHERE user_id = 200;
    

    现在,您可以获取每个用户的所有聊天:

    Select * from user_messages where user_id = 100;
    Select * from user_messages where user_id = 200;
    

    在两个用户之间聊天:

    Select * from user_messages where user_id = 100 and second_user_id = 200;
    

    反之亦然:

    Select * from user_messages where user_id = 200 and second_user_id = 100;
    

    这种方法会复制数据,但对于Cassandra来说,这是一种支付读取速度的常见方法。

    [编辑] 大分区问题

    如果每个用户期望的消息太多,您应该选择另一个分区键,而不是用户ID。例如,您可以使用由用户ID和日期组成的复合分区键,在这种情况下,每个分区只包含一天的消息,但每天都有单独的分区。这种技术通常被称为“套桶法”, some example of bucketing

        2
  •  1
  •   Guillaume S    7 年前

    您可以为具有反向ID的两个用户创建两条记录:

    记录1:用户ID=1,第二个用户ID=2

    记录2:用户ID=2,第二个用户ID=1

    显然,两个记录必须相同 id , author_id message

    所以你的第二个查询有效

    SELECT * FROM sample.user_messages WHERE user_id = 1
    

    此外,您的第一个查询在所有情况下都可以工作,因为无论您在查询中提供的ID的顺序如何:

    SELECT * FROM sample.user_messages WHERE user_id = 1 AND second_user_id = 2
    SELECT * FROM sample.user_messages WHERE user_id = 1 AND second_user_id = 2
    

    两个查询将提供相同的结果。

        3
  •  0
  •   Mehul Gupta Arya    7 年前

    我建议对第二个用户使用辅助索引,如下所示:

    在sample.user_messages(second_user_id)上创建索引索引_second_user_id;

    所以现在您的第一个查询将保持不变。

    第二个查询将分为两个单独的查询,分别查询用户ID和第二个用户ID,如下所示

    1) select * from "user_messages" where user_id=100;
    2) select * from "user_messages" where second_user_id=100;
    

    这应该会有所帮助。