围绕电子邮件系统的Cassandra数据建模

围绕电子邮件系统的Cassandra数据建模,cassandra,data-modeling,cassandra-2.0,Cassandra,Data Modeling,Cassandra 2.0,我需要数据建模的帮助,因为我还没有找到一个资源来解决同样的问题 该用户案例类似于电子邮件系统。我想存储用户收到的所有电子邮件的时间线,然后用三种不同的方式将其取回: 所有收到的电子邮件 用户已阅读的邮件 用户尚未阅读的邮件 我当前的模型如下所示: CREATE TABLE TIMELINE ( userID varchar, emailID varchar, timestamp bigint, read boolean, PRIMARY KEY (user

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

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

  • 所有收到的电子邮件
  • 用户已阅读的邮件
  • 用户尚未阅读的邮件
  • 我当前的模型如下所示:

    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;
    
    我的问题是:

  • 我是否应该继续阅读作为我的第二索引,因为它将经常更新,并可能创建墓碑-根据它的一个问题

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

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

  • 您的索引(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的自然聚类顺序,并且您可以通过一个简单的批处理(一次删除,一次插入)将电子邮件从未读移动到已读


    现在,当您标记电子邮件已读时,未读表中可能会有很多墓碑。将GCGS设置为较低并使用频繁压缩可能会有所帮助,但您也可能希望将这些分区拆分,以避免出现TombstoneOverlming问题。如果有数千封电子邮件飞来,请标记为read。

    回答得好,Jeff。我也在想同样的事情。这里有一个不应该忽视的潜在墓碑问题,但我认为这可能是正确的方向。@JeffJirsa谢谢你的回答和解释。我还有一个问题:要呈现一个所有电子邮件的时间线-我会在cassandra上触发两个查询,然后进行内存合并,对吗?不-你会对时间线表执行一个查询,如果你需要WHERE子句中的读取状态,只使用READ_时间线和UNREAD_时间线。@JeffJirsa Ok得到了。因此,我们为单个用户维护三个不同的时间表。谢谢如果实施后有更多问题,将返回。