【问题标题】:Cassandra data-modelling around email-system围绕电子邮件系统的 Cassandra 数据建模
【发布时间】:2015-04-27 18:29:36
【问题描述】:

我需要数据建模帮助,因为我还没有找到解决相同问题的资源。

用户案例类似于电子邮件系统。我想存储用户收到的所有电子邮件的时间线,然后用三种不同的方式取回它们:

  1. 曾经收到的所有电子邮件
  2. 用户已阅读的邮件
  3. 用户仍未阅读的邮件

我目前的模型如下:

CREATE TABLE TIMELINE (
    userID varchar,
    emailID varchar,
    timestamp bigint,
    read boolean,
    PRIMARY KEY (userID, timestamp)
) WITH CLUSTERING ORDER BY (timestamp desc);

CREATE INDEX ON TIMELINE (userID, read);

我需要支持的查询是:

SELECT * FROM TIMELINE where userID = 12;
SELECT * FROM TIMELINE where userID = 12 order by timestamp asc;
SELECT * FROM TIMELINE where userID = 12 and read = true;
SELECT * FROM TIMELINE where userID = 12 and read = false;
SELECT * FROM TIMELINE where userID = 12 and read = true order by timestamp asc;
SELECT * FROM TIMELINE where userID = 12 and read = false order by timestamp asc;

我的查询是:

  1. 我是否应该继续阅读作为我的二级索引,因为它会经常更新并且可以创建墓碑 - 每个 http://docs.datastax.com/en/cql/3.1/cql/ddl/ddl_when_use_index_c.html 这是一个问题。

  2. 我们可以对二级索引进行不等式检查吗,因为我发现二级索引上应该存在至少一个相等条件

  3. 如果这不是正确的建模方式,请就如何支持上述查询提出建议。维护三个不同的表格让我担心插入的数量(对于已读/未读),因为用户数量 * 每天查看的电子邮件将是巨大的。

【问题讨论】:

    标签: cassandra data-modeling cassandra-2.0


    【解决方案1】:

    您的索引 (userID) 具有高基数 - 您可能希望将其作为您手动与应用程序同步的第二个(或第三个)CF 进行管理。

    可能是这样的

    CREATE TABLE READ_TIMELINE (
        userID varchar,
        emailID varchar,
        timestamp bigint,
        PRIMARY KEY (userID, timestamp)
    ) WITH CLUSTERING ORDER BY (timestamp desc);
    
    CREATE TABLE UNREAD_TIMELINE (
        userID varchar,
        emailID varchar,
        timestamp bigint,
        PRIMARY KEY (userID, timestamp)
    ) WITH CLUSTERING ORDER BY (timestamp desc);
    

    这使您能够满足以下查询:

    SELECT * FROM READ_TIMELINE where userID = 12;
    SELECT * FROM UNREAD_TIMELINE where userID = 12;
    SELECT * FROM READ_TIMELINE where userID = 12 order by timestamp asc;
    SELECT * FROM UNREAD_TIMELINE where userID = 12 order by timestamp asc;
    

    也就是说,您使用 ORDER BY 的自然聚类顺序,并且您可以通过简单的批处理(一个 DELETE,一个 INSERT)将电子邮件从 UNREAD 移动到 READ

    现在,当您将电子邮件标记为已读时,您最终可能会在 UNREAD 表中出现大量墓碑。将 GCGS 设置得较低并使用频繁的压缩可以在一定程度上有所帮助,但是如果您有成千上万的电子邮件飞入并标记为已读,您可能还希望分解这些分区以避免墓碑压倒性问题。

    【讨论】:

    • 好答案杰夫。我也在想同样的事情。
    • 这里有一个非常现实的潜在墓碑问题,不容忽视,但我认为这可能是正确的方向。
    • @JeffJirsa 感谢您的回答和解释。我仍然有一个查询:渲染所有电子邮件时间线 - 我会在 cassandra 上触发两个查询,然后进行内存合并,对吗?
    • 否 - 您将针对 TIMELINE 表执行一次查询,并且仅在需要 WHERE 子句中的读取状态时才使用 READ_TIMELINE 和 UNREAD_TIMELINE。
    • @JeffJirsa 好的。因此,我们为单个用户维护三个不同的时间线。谢谢。实施后如有更多问题会回复。
    猜你喜欢
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-02
    相关资源
    最近更新 更多