2016-09-21 50 views
0

我现在有一个基本的用户事件表中的下列表格布局:对比唯一性的更好选择?

CREATE TABLE IF NOT EXISTS events.events_by_user(
    user text, 
    added_week int, 
    added_timestamp timestamp, 
    event text, 
    uuid uuid, 
    PRIMARY KEY((user, added_week), added_timestamp, event, uuid)) 
WITH CLUSTERING ORDER BY(added_timestamp DESC) 

因此唯一性基本上由UUID作为主键的最后一列中必要的。同一个用户有几次相同的事件有可能发生在同一个毫秒(时间戳)中。

另一种方法可能是(如果我没有记错的话),下降的uuid列由相对柱取代它,而不是像这样:

CREATE TABLE IF NOT EXISTS events.events_by_user(
    user text, 
    added_week int, 
    added_timestamp timestamp, 
    event text, 
    frequency counter, 
    PRIMARY KEY((user, added_week), added_timestamp, event)) 
WITH CLUSTERING ORDER BY(added_timestamp DESC) 

我的想法是,我可以节省一些空间使用这个计数器,而且我的行不会变宽。我不确定,如果这可能会有其他性能影响维持这个柜台,或者如果有任何其他原因,为什么这可能不是一个好主意?

回答

1

为什么要使用一个计数器来节省空间? C *设计成语是使用空间来增益效率。

回到你的问题,专柜几乎都可以做什么限制,如必须在其自己的表被用在你想要的主键,你可以有许多列,然后只计列。它们只支持递增和递减操作,并且由于它们只支持这两个操作,所以每个查询都不是幂等的。如果您可以忍受“计数”值的不准确性...(即使C * 2.1+缓解了这一点,过度计数也是众所周知的问题)

这意味着您不能指定event列,因为是不是你主键的一部分,所以你的设计是无效的。

回到你的独特性要求,您可以使用timeuuid列类型。它们是基于时间的Type 1 UUID,并提供相当低的碰撞概率。从Cassandra wiki

类型1 UUID由以下部分组成:

  • 由100纳秒间隔的计数的时间戳因为 00:00:00.00,1582 10月15日(日格利高里改革的基督徒日历 )。

  • 甲版本(应该具有1的值)。

  • 的变体(其应具有2的值)。

  • 的序列号,它可以是一个计数器或一个伪随机数。

  • 一个“节点”,它将成为机器的MAC地址(它应该使UUID在整个机器上都是唯一的)。

与UUID的挑战是,使之成为 一台机器上运行多个进程和多线程 在一个进程中运行是唯一的。上面指定的类型1 UUID也不是 。在具有多个内核的快速机器上,很有可能 具有以相同时间值生成的UUID。只有当顺序号可以跨越线程和进程时,这个可以修复为 ,这对于高效地执行相当具有挑战性。

的时间参考的基于UUID通过补偿这些问题:

  • 使用()由 System.currentTimeMillis的恢复正常毫秒的粒度和调整它假装容纳100张 纳秒数只。

  • 每当遇到重复时间值时,将时间递增1(以非线程安全方式) 。使用与序列号的UUID类关联的伪随机 号码。 将时间增加1允许多个线程在同一个进程中在同一毫秒内唯一地创建多达10,000个UUID。使用 序列号的伪随机数在每个UUID类将具有唯一ID的情况下提供1个16344个机会。

这些机制提供了合理的概率,即所生成的UUID将是唯一的。但是,要注意的问题是:

  • 计算机能够每 微秒产生1点万多的UUID。

  • 在不同线程上创建UUID的应用程序可能会得到重复,因为时间不会以线程安全 的方式递增。类的

  • 多个实例是在虚拟机中在不同的 类加载器 - 这将通过具有其自身的 序列号的每个类而减轻。

  • 不能保证相同或不同VM的UUID在 中的两个实例将具有不同的序列号 - 只是 它们将具有合理的概率。

在实践中,C *就已经做你想做的事。但是,如果您真的担心自己最终会出现重复,那么您需要自己进行适当的计数,并且建议您在应用程序级别实现这一点。

+0

我看到了,我用我的初始设计timeuuid,但有点害怕[this](http://nickberardi.com/sometimes-a-nanosecond-makes-all-the-difference/)文章。 Thx的努力,提到的概率是足够好的,我会用timeuuid去。 – u6f6o