【问题标题】:Generating a Random Type 1 UUID from a Unix Timestamp for use with Cassandra从 Unix 时间戳生成随机类型 1 UUID 以用于 Cassandra
【发布时间】:2014-10-28 13:21:25
【问题描述】:

是否可以从特定的 Unix 时间戳生成 Scala/Java 中的 Type 1 UUID(用于 Cassandra),这样它就可以用于获取记录的范围切片和表中的单个记录。以下结果似乎表明这是可能的。

import com.datastax.driver.core.utils._

var td = new DateTime(2003,1,1,0,0)
val time_millis = td.getMillis()
val lower =  UUIDs.startOf(time_millis)
val upper =  UUIDs.endOf(time_millis)

println(lower.getLeastSignificantBits())  #  9187201950435737472
println(lower.getMostSignificantBits())   # -545498504376938025
println(upper.getLeastSignificantBits())  # -9187201950435737471
println(upper.getMostSignificantBits())   # -545455558998945321

背景(以防有更好的方法解决问题)。

我想将几千条车辆记录批量导入到 Cassandra 数据库中。包含日期列包含将车辆添加到原始数据库 (VCA) 的日期,并且通常在特定日期添加不超过几百个,这似乎表明 timeuuid 中可用的熵可能足以解决此问题;即mac地址,小时,秒,...,100纳秒和随机部分。

我需要执行的示例查询

SELECT * FROM vehicles WHERE manufacturer = 'BMW';
SELECT * FROM vehicles WHERE manufacturer = 'BMW' AND id = a8bb5800-694c-11d7-8080-808080808080;
SELECT * FROM vehicles WHERE manufacturer = 'BMW' AND id < a8bb5800-694c-11d7-8080-808080808080 AND id >= cb59c000-1c26-11d6-8080-808080808080;

CQL 中的表架构。

CREATE TABLE vehicles (
  id                 timeuuid,
  manufacturer       text,
  model              text,
  transmission       text,
  description        text,
  engine_capacity    double,
  fuel_type          text,
  metric_urban       double,
  metric_extra_urban double,
  metric_combined    double,
  co2_g_per_km       double,
  euro_standard      int,
  noise              double,
  co                 double,
  hc_nox             double,
  hc                 double,
  nox                double,
  particulates       double,
  date_included      timestamp,
  PRIMARY KEY (manufacturer, id)
) WITH CLUSTERING ORDER BY (id ASC);

配套制造商表

SELECT * from manufacturers;

CREATE TABLE manufacturers (
  id                 uuid,
  manufacturer       text,
  years              set<int>
  PRIMARY KEY (manufacturer, id)
);

【问题讨论】:

  • 您的标题与单词 random 混淆。 Version 1 UUID 基于日期时间和 MAC 地址,128 位中只有少数是随机的。 Version 4 是几乎完全随机的类型。

标签: java scala cassandra uuid


【解决方案1】:

我想理论上是可以做到的。但是,没有标准的 Java API 允许您在生成 UUID 时指定“当前时间”。

这不是 1 类 UUID 的用途。 (无法承受 Cassandra 根据时间选择“timeuuid”值的能力!)嵌入的时间戳是保证唯一性方案的一部分......仅此而已。如果您在与当前时间不同的时间开始人为生成类型 1 UUID,那么您会遇到(理论上的)问题,即您的“新”UUID 实际上可能与当时在该机器上真正创建的 UUID 相同;即您的 UUID 不再是唯一的。

如果我这样做,我会以正常方式生成 UUID,并将时间戳存储在单独的字段中。


更新

您也许可以调整“https://github.com/cowtowncoder/java-uuid-generator”来做您想做的事。 (提示:编写一个棘手的“时间戳同步器”)。但我仍然认为这是一个坏主意。

【讨论】:

  • 谢谢@stephen。我最终按照您的建议使用时间戳和 Type 4 UUID,并创建了一个由 id 索引的新查找表,以查找参数(制造商、包含的日期等)以从 id 查询主表。鉴于导入将是批量操作重复/多个事实来源不应该成为太大的问题,而且我相信这是惯用的,因为在 Cassandra 中建模关系时使用了类似的策略。
  • 我绝对同意从 UUID 中提取日期时间是对 UUID 用途的滥用。这种“聪明”往往会带来麻烦。但是,如果您坚持这样做,至少检查the few bits of the UUID that identify its version 以验证它确实是包含日期时间的Version 1。所有版本都有 128 位并且可以相互替换,所以不要假设 UUID 是版本 1。
猜你喜欢
  • 1970-01-01
  • 2012-10-15
  • 2012-12-21
  • 2013-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-15
  • 1970-01-01
相关资源
最近更新 更多