【问题标题】:String sorting in Cassandra CQLCassandra CQL 中的字符串排序
【发布时间】:2014-11-25 03:45:18
【问题描述】:

在 Cassandra CQL 中查询文本主键时,字符串比较的工作方式与预期相反,即

cqlsh:test> 从 sl 中选择 *; 姓名 |数据 --------------+------ 000000020000000000000003 |空值 000000010000000000000005 |空值 000000010000000000000003 |空值 000000010000000000000002 |空值 000000010000000000000001 |空值 cqlsh:test> select name from sl where token(name) &lt token('000000010000000000000005'); 姓名 -------------------------- 000000020000000000000003 (1 行) cqlsh:test> select name from sl where token(name) &gt token('000000010000000000000005'); 姓名 -------------------------- 000000010000000000000003 000000010000000000000002 000000010000000000000001 (3 行)

相比之下,这是我从 Python 中的字符串比较中得到的(我认为在大多数其他语言中):

>>>'000000020000000000000003' < '000000010000000000000005'
False

如果我不使用令牌函数进行查询,则会收到以下错误:

cqlsh:test> 从 sl 中选择名称,其中名称 &lt '000000010000000000000005'; 错误请求:分区键仅支持 EQ 和 IN 关系(除非您使用 token() 函数)

表格说明为:

CREATE TABLE sl (
  name text,
  data blob,
  PRIMARY KEY (name)
) WITH
  bloom_filter_fp_chance=0.010000 AND
  caching='KEYS_ONLY' AND
  comment='' AND
  dclocal_read_repair_chance=0.000000 AND
  gc_grace_seconds=864000 AND
  index_interval=128 AND
  read_repair_chance=0.100000 AND
  replicate_on_write='true' AND
  populate_io_cache_on_flush='false' AND
  default_time_to_live=0 AND
  speculative_retry='99.0PERCENTILE' AND
  memtable_flush_period_in_ms=0 AND
  compaction={'class': 'SizeTieredCompactionStrategy'} AND
  compression={'sstable_compression': 'LZ4Compressor'};

在我错过的文档或其他地方是否有解释为什么选择了这样一个奇怪的字符串比较顺序,或者字符串比较运算符是否不符合我的期望(即返回一些不相关的顺序,即写入数据库时​​的行顺序)。我正在使用 Murmur3Partitioner 分区器以防万一。

【问题讨论】:

    标签: cassandra cql nosql


    【解决方案1】:

    这里有一些关于令牌功能和相关分页的文档链接。为广泛的主题道歉。我不确切知道哪些可能会有所帮助:

    【讨论】:

      【解决方案2】:

      在 Cassandra 中,行按其键值的哈希值排序。对于 Random 和 Murmur3 分区器,哈希值有一个随机元素,因此顺序是 A) 没有意义,并且 B) 设计为均匀分布在整个环中。

      因此,查询小于token('000000010000000000000005') 的令牌不会根据字符串值“000000010000000000000005”进行比较。它将对散列的令牌值进行比较。根据您看到的结果,字符串“000000020000000000000003”的令牌值小于“000000010000000000000005”的令牌值。

      有关更多信息,请查看 DataStax 中的此文档:Paging Through Unordered Partitioner Results

      假设您希望能够通过“名称”的值查询数据,您可以构建一个类似这样的表:

      CREATE TABLE sl (
        type text,
        name text,
        data blob,
        PRIMARY KEY (type, name)
      )
      

      我创建了type 作为分区键。我不确定您的数据是否有意义按“类型”(或其他任何东西)划分,所以它更多的是为了示例而不是其他任何东西。无论如何,使用name 作为聚类键(确定磁盘排序顺序),此查询将起作用:

      select * from sl where type='sometype' AND name < '000000010000000000000005';
      

      这只是一个示例,但我希望这有助于为您指明正确的方向。

      【讨论】:

      • 谢谢,我很困惑这些行似乎是按 DESC 顺序排列的,但看起来纯属巧合。项目进行的方式我不需要太多分区,所以我可能要么使用有序分区器,要么完全使用应用程序级别的排序和比较。
      • @alexk 只是一个警告,Byte-Ordered Partitioner 已被弃用,应该被使用。 datastax.com/documentation/cassandra/2.1/cassandra/architecture/…
      猜你喜欢
      • 2014-03-23
      • 2017-01-14
      • 2017-03-13
      • 1970-01-01
      • 2015-12-13
      • 2014-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多