2013-07-30 103 views

回答

51

UUID and TIMEUUID在Cassandra中的存储方式相同,它们只代表两种不同的排序实现。

TIMEUUID列可以通过时间的成分的第一排序,然后被其原始字节,而UUID列通过其版本第一排序,然后如果两者都可以通过时间成分版本1,最后可以通过原始字节。奇怪的是,时间组件排序实现在Cassandra代码中的UUIDTypeTimeUUIDType之间重复,除了不同的格式。

我想到UUIDTIMEUUID主要作为文档的问题:如果您选择TIMEUUID,则表示您按时间顺序存储事物,并且这些事件可能会同时发生,所以仅使用简单的时间戳是不够的。使用UUID表示您不关心订单(即使在实践中,如果您将版本1的UUID放入列中,列将按时间排序),您只需确保事物具有唯一的ID。

即使使用NOW()生成UUID值很方便,其他人阅读您的代码也很令人惊讶。

在事物的宏观方案中,这可能并不重要,但排序非版本1 UUID比版本1快一点,所以如果你有一个UUID列并自己生成UUID,请转到另一个版本。

+1

如何排序非版本1UUID更快?例如,版本4的UUID是完全随机的,我预计会提供最差的排序性能。我同意这个问题应该不重要。如果您使用的是UUID,那么您可以这样做是因为几个很好的理由,但性能不在其中。幸运的是,今天的计算机可以处理由UUID提出的空间和分类要求。 –

+3

UUID的内容与排序算法的性能无关。非版本1在Cassandra_中排序更快,因为没有将字节解包到时间戳中。这是一个非常非常小的差异,我只是觉得它很有趣。 – Theo

+0

是now()函数产生timeuuid的唯一方法吗?有可能生成自定义的?它仅用于测试我需要定制的测试。 – Pinocchio

19

​​一个是一个普通的旧UUID根据documentation

A UUID只是一个128-bit value认为它是一个难以想象的大数目。

特定位可以通过几种方法中的任何一种来确定。 original method涉及到计算机网络硬件的MAC address,结合当前的日期和时间,再加上一个任意数字和一个随机数。把所有这些都挤在一起得到一个几乎独一无二的号码。后来,出于各种原因(安全性,隐私),在生成UUID值时发明了其他方法来组装比特。这些其他方法省略了日期时间和/或MAC地址作为成分。问题是:并非所有的UUID值都有嵌入的日期时间值。

Cassandra文档错误地将其TimeUUID引用为“类型1 UUID”。正确的术语是版本1 UUID。这个版本有时被称为“基于时间的版本”。


一些建议

卡桑德拉似乎识别UUID的该特定版本用于提取128比特的日期和时间部分的目的。从UUID中提取日期时间是不好主意

首先,UUID从未打算用于这种历史跟踪。的确,UUID的规范特别认识到(a)计算机时钟可以被重置,因此(b)稍后生成的UUID实际上可以记录比先前的UUID更早的日期时间。不从UUID中提取日期时间的另一个原因是因为您可能拥有不是由时间方法生成的UUID,因此您将根据实际上不代表日期时间的位构建数据时间值的创作。第三个原因是,当编程代码稍后重构时,UUID可能会在与数据库记录不同的时间生成,因此使用UUID的日期时间会产生误导。

如果您需要跟踪日期时间历史记录,请明确执行。在您的数据中创建一个日期时间字段。顺便说一句,在UTC追踪日期时间,但这是另一个话题。

+2

为了记录,Cassandra文档明确建议使用ntp来跨所有节点同步系统时间。 http://www.datastax.com/documentation/cassandra/1.2/webhelp/cassandra/install/installRecommendSettings.html – omnibear

+10

同意使用UTC。但是为了解决您的其他问题:1)时间戳也会受到时钟漂移的影响,所以在时间序列数据方面它们不如TimeUUID好。 2)在CQL3和使用TimeUUID数据类型的Cassandra模式的上下文中,期望这些列中的所有UUID都是时间编码的类型1 UUID是合理的。 3)在CQL3中,您可以使用NOW()或特定的日期时间在插入时创建TimeUUID。因此,处理旧数据仍然会导致Cassandra表中历史上正确的TimeUUID。 – platforms

+0

@平台将两个不同的目的合并成一个单一的值是一个坏主意,这是一个不好的做法。在这种情况下,1.日期 - 时间历史跟踪和2.主键标识符。当您想要将数据导出或导入其他系统/资源/接收器时,您会感到遗憾。作为进一步证明无谓地造成的混乱,虽然**没有获得任何回报**,请重新阅读本页面的问题! –