2016-09-08 5 views
1

誰も私がINとI selectコレクション列でクラスタリング列を制限するクエリを使用できない理由を知っていますか?なぜCassandraはIN制限でクラスタリングキーをクエリできないのですか?

私はそれについて詳しく説明します。私はselect文次を使用しようとすると、

create table inventory (
       sku text, 
       class text, 
       unit text, 
       node text, 
       supply map<text, frozen<delta_and_time>>, 
       supply_compacted int, 
       primary key ((sku, class, unit), node)); 

::のは、私は次のようなデータモデルを持っているとしましょう

select sku, class, unit, node, supply_compacted where sku = '0' 
      and class = 'good' and unit = 'each' and node in ('1', '2', '3') 

すべてが正常です。

Cannot restrict clustering columns by IN relations when a collection is selected by the query 

私はC *のような制限がある理由を見つけることを試みたが、私は何かを見つけることができませんでした:私は同じ制限がselect *しようとすると、しかし、私は INGエラーに従ってもらいます。また、コードを調べましたが、そのようなチェックが行われる理由についての情報はありません。

誰でもこのような制限の理由を知っていますか?

答えて

1

これは、コレクションデータタイプが既存のストレージエンジンに「ハッキング」された方法に基づく制限です。マップコレクションは、各キーをクラスタリング列と同じ領域に一意の列名として格納することによって実装されます。したがって、カサンドラは特に、「行」ごとに大規模なコレクションサイズの場合に効率的に「IN」操作を実行することを困難にします。

しかし、この制限を回避し、コレクションタイプを使用しないようにするためにデータモデルを再作成できると思います(慎重でない場合、多くの問題が関連付けられているため)。 「supply_compacted」は、サプライマップ内の総在庫のロールアップになる可能性がありますか?もしそうなら、あなたは以下のことができます:

create table inventory (
    sku text, 
    class text, 
    unit text, 
    node text, 
    supply_compacted int static, -- stored once, total amount of inventory across all nodes 
    supply frozen<delta_and_time>, 
    primary key ((sku, class, unit), node) 
); 
+0

「クラスタリング列と同じ領域」でもっと詳しく説明できますか? – k0ner

0

私の独創的な考えは、複数のコレクションは、上の制約で一度に返すことができるので、制約が、メモリへの影響やコレクションを取得するためのネットワークによるものであるということです。ただし、パーティションキーを指定するだけで制限が緩和されていれば、クエリが機能していることがわかりました。 (カサンドラ3.7上)

私のテストデータ:

cqlsh:test> create table mytable(X text, Y text, Z text, mylist list<int>, primary key (X,Y)); 
cqlsh:test> insert into mytable (X,Y,Z,mylist) values('x','y1','z1',[1,2,3]); 
cqlsh:test> insert into mytable (X,Y,Z,mylist) values('x','y2','z2',[4,5,6]); 
cqlsh:test> select x,y,z from mytable where x = 'x' and y in ('y1'); 

x | y | z 
---+----+---- 
x | y1 | z1 

(1 rows) 
cqlsh:test> select * from mytable where x = 'x' and y in ('y1'); 
InvalidRequest: Error from server: code=2200 [Invalid query] message="Cannot restrict clustering columns by IN relations when a collection is selected by the query" 
cqlsh:test> select * from mytable where x = 'x'; 

x | y | mylist | z 
---+----+-----------+---- 
x | y1 | [1, 2, 3] | z1 
x | y2 | [4, 5, 6] | z2 

(2 rows) 

根本sstableダンプ:

$ sstabledump mb-1-big-Data.db 
[ 
    { 
    "partition" : { 
     "key" : [ "x" ], 
     "position" : 0 
    }, 
    "rows" : [ 
     { 
     "type" : "row", 
     "position" : 15, 
     "clustering" : [ "y1" ], 
     "liveness_info" : { "tstamp" : "2016-09-13T08:14:33.172799Z" }, 
     "cells" : [ 
      { "name" : "z", "value" : "z1" }, 
      { "name" : "mylist", "deletion_info" : { "marked_deleted" : "2016-09-13T08:14:33.172798Z", "local_delete_time" : "2016-09-13T08:14:33Z" } }, 
      { "name" : "mylist", "path" : [ "1a1a0760-798a-11e6-851a-e3954ecad15b" ], "value" : "1" }, 
      { "name" : "mylist", "path" : [ "1a1a0761-798a-11e6-851a-e3954ecad15b" ], "value" : "2" }, 
      { "name" : "mylist", "path" : [ "1a1a0762-798a-11e6-851a-e3954ecad15b" ], "value" : "3" } 
     ] 
     }, 
     { 
     "type" : "row", 
     "position" : 99, 
     "clustering" : [ "y2" ], 
     "liveness_info" : { "tstamp" : "2016-09-13T08:14:49.772718Z" }, 
     "cells" : [ 
      { "name" : "z", "value" : "z2" }, 
      { "name" : "mylist", "deletion_info" : { "marked_deleted" : "2016-09-13T08:14:49.772717Z", "local_delete_time" : "2016-09-13T08:14:49Z" } }, 
      { "name" : "mylist", "path" : [ "23fefce0-798a-11e6-851a-e3954ecad15b" ], "value" : "4" }, 
      { "name" : "mylist", "path" : [ "23fefce1-798a-11e6-851a-e3954ecad15b" ], "value" : "5" }, 
      { "name" : "mylist", "path" : [ "23fefce2-798a-11e6-851a-e3954ecad15b" ], "value" : "6" } 
     ] 
     } 
    ] 
    } 
] 

コレクションを見ることができるように除いて、非主キー列から実際に違いはありませんそれをクライアントに返す前に必要な集約のために。私はこれが古い倹約の実装の制約であるかどうか疑問に思って、これができない理由が明白でないにもかかわらず、持ち越されました。

関連する問題