【问题标题】:Strange behavior of timeuuid comparisontimeuuid 比较的奇怪行为
【发布时间】:2014-08-14 12:03:04
【问题描述】:

我有 3 个节点的 Cassandra 2.x 集群和这样的数据库方案:

cqlsh> CREATE KEYSPACE test_ks WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 3} AND durable_writes = true;
cqlsh> CREATE TABLE IF NOT EXISTS test_ks.test_cf (
   ...   time timeuuid,
   ...   user_id varchar,
   ...   info varchar,
   ...   PRIMARY KEY (time, user_id)
   ... ) WITH compression = {'sstable_compression': 'LZ4Compressor'} AND compaction = {'class': 'LeveledCompactionStrategy'};

让我们添加一些数据(在插入之间等待一段时间):

cqlsh> INSERT INTO test_ks.test_cf (time, user_id, info) VALUES (now(), 'user1', 'pythonista');
cqlsh> INSERT INTO test_ks.test_cf (time, user_id, info) VALUES (now(), 'user1', 'mr. Haskell');

让我们看看我们的数据:

cqlsh> SELECT dateOf(time), user_id, info FROM test_ks.test_cf;

 dateOf(time)             | user_id | info
--------------------------+---------+-------------
 2014-06-24 16:00:31+0700 |   user1 | mr. Haskell
 2014-06-24 15:59:32+0700 |   user1 |  pythonista

(2 rows)

我在查询 test_cf CF 时得到了一些奇怪的结果:

cqlsh> SELECT dateOf(time) FROM test_ks.test_cf WHERE user_id='user1' AND token(time) >= token(maxTimeuuid('2014-06-24 16:00:31+0700')) ALLOW FILTERING;

 dateOf(time)
--------------------------
 2014-06-24 15:59:32+0700

(1 rows)

cqlsh> SELECT dateOf(time) FROM test_ks.test_cf WHERE user_id='user1' AND token(time) >= token(maxTimeuuid('2014-06-24 16:00:32+0700')) ALLOW FILTERING;

 dateOf(time)
--------------------------
 2014-06-24 15:59:32+0700

(1 rows)

cqlsh> SELECT dateOf(time) FROM test_ks.test_cf WHERE user_id='user1' AND token(time) >= token(maxTimeuuid('2014-06-24 16:00:33+0700')) ALLOW FILTERING;

 dateOf(time)
--------------------------
 2014-06-24 16:00:31+0700
 2014-06-24 15:59:32+0700

(2 rows)

如您所见,比较给出了错误的结果,但 timeuuid 不得大于 maxTimeuuid 并且必须大于 'minTimeuuid'(对于相同的日期时间,当然 =))。有人可以向我解释一下这种奇怪的行为吗?

TIA!

【问题讨论】:

    标签: cassandra cql3 cassandra-2.0 cqlsh


    【解决方案1】:

    首先,你的主键是向后的——如果你想执行这样的查询,你的CREATE TABLE 语句应该是这样的:

    CREATE TABLE IF NOT EXISTS test_ks.test_cf (
      time timeuuid,
      user_id varchar,
      info varchar,
      PRIMARY KEY (user_id, time)
    ) WITH compression = {'sstable_compression': 'LZ4Compressor'}
      AND compaction = {'class': 'LeveledCompactionStrategy'};
    

    这使得user_id 成为分区键,time 成为集群列,这符合您的查询模式。

    通过此更改,您不再需要使用 TOKEN 函数,该函数是对分区键进行范围查询所需的,但对于集群列没有意义(并且通常不对应于列值的语义排序)。由于time现在是一个聚类列,你只需要做一个普通的比较:

    SELECT dateOf(time)
    FROM test_ks.test_cf
    WHERE user_id='user1'
      AND time >= maxTimeuuid('2014-06-24 16:00:31+0700');
    

    您也可以删除ALLOW FILTERING,因为您现在正在执行标准范围切片而不是令牌比较,这需要扫描所有行并进行比较。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-25
      • 2017-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-04
      相关资源
      最近更新 更多