Cassandra 使用日期和时间戳作为分区键和集群键

Cassandra 使用日期和时间戳作为分区键和集群键,cassandra,datastax,Cassandra,Datastax,我有一个存储系统活动的表。数据模型具有以下结构 CREATE TABLE activities { id UUID, json text, activity_date Date, activity_time Timestamp, activity_type Text, Primary Key(activity_date, activity_type, activity_time) } 上表提供的潜在用例包括 查找为给定日期生成的事件 查找为给定日期和活动类型生成的事件

我有一个存储系统活动的表。数据模型具有以下结构

CREATE TABLE activities {
  id UUID,
  json text,
  activity_date Date,
  activity_time Timestamp,
  activity_type Text,
  Primary Key(activity_date, activity_type, activity_time)
}
上表提供的潜在用例包括

  • 查找为给定日期生成的事件
  • 查找为给定日期和活动类型生成的事件
  • 查找在给定时间范围内为给定日期和活动类型生成的事件
  • 上述数据模型容易受到bug的攻击,如果在同一毫秒内插入两个具有相同活动类型的活动,其中一个可能会覆盖另一个。这是因为casssandra保证时间戳的唯一性高达一毫秒

    数据库中的另一个表具有类似的结构,我们看到记录彼此覆盖了两次。这在两年内发生了两次。虽然概率很低,但仍有可能破坏数据完整性

    为了克服这个问题,我们可能会在insert查询中添加一个
    IF NOT EXISTS
    子句,这将导致一个insert失败,而如果出现这种情况,另一个insert将成功

    不过,我想了解一下,这里还有什么可以做的吗

    卡桑德拉还能提供我们所缺少的任何东西吗


    这是一个设计糟糕的数据模型吗?但是考虑到这些查询,我们没有更多的列添加到键中。

    一般来说,如果您的时间戳可能有冲突,您可以使用timeuuids而不是timestamp。它们应该是唯一的,您可以随时从它们那里获取时间戳

    其他一些注意事项:

    • 您是否使用您定义的UUID

    • 您应该将熵添加到分区键中,可能((activity\u date,activity\u type),activity\u time),因为只有activity\u date作为分区键才会导致热点


    通常,如果您的时间戳可能存在冲突,您可以使用TimeUUID而不是时间戳。它们应该是唯一的,您可以随时从它们那里获取时间戳

    其他一些注意事项:

    • 您是否使用您定义的UUID

    • 您应该将熵添加到分区键中,可能((activity\u date,activity\u type),activity\u time),因为只有activity\u date作为分区键才会导致热点


    您的问题非常有效,我认为根据我的说法,在集群列中添加eventId(在您的案例中是id)将提供唯一性。这应该是唯一的解决方案。你的问题非常有效,我认为根据我的说法,在集群列中添加eventId(在你的例子中是id)将提供唯一性。这应该是唯一的解决方案。我认为TimeUUID将是我们的选择,因为它可以确保无冲突的时间戳生成。谢谢你的建议。我们正在考虑删除UUID列,因为它没有被使用。我认为TimeUUID将是我们的选择,因为它可以确保无冲突的时间戳生成。谢谢你的建议。我们正在考虑删除UUID列,因为它没有被使用。