10

timeuuid でどのようにクエリとフィルタリングを行いますか。つまり、次のテーブルがあると仮定します。

create table mystuff(uuid timeuuid primary key, stuff text);

つまり、あなたはどうしますか:

select uuid, unixTimestampOf(uuid), stuff
from mystuff
order by uuid desc
limit 2000

また、次の古い 2000 などをフェッチできるようにしたいのですが、それは別の問題です。エラーは次のとおりです。

Bad Request: ORDER BY is only supported when the partition key is restricted by an EQ or an IN.

念のため、実際のテーブルは次のとおりです。

CREATE TABLE audit_event (
  uuid timeuuid PRIMARY KEY,
  event_time bigint,
  ip text,
  level text,
  message text,
  person_uuid timeuuid
) 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
  read_repair_chance=0.100000 AND
  replicate_on_write='true' AND
  populate_io_cache_on_flush='false' AND
  compaction={'class': 'SizeTieredCompactionStrategy'} AND
  compression={'sstable_compression': 'SnappyCompressor'};
4

1 に答える 1

20

テーブルのデザインを少し変えることをお勧めします。現在お持ちのデザインでご希望の内容を実現するのはかなり難しいでしょう。

現時点では、audit_eventテーブル内の各エントリが別の を受け取りuuid、内部で Cassandra が多くの短い行を作成します。このような行のクエリは非効率的であり、さらにランダムに並べ替えられます (正当な理由で避けるべき Byte Ordered Partitioner を使用しない限り)。

ただし、Cassandra は列の並べ替えが得意です。(例に戻って)次のようにテーブルを宣言した場合:

CREATE TABLE mystuff(
  yymmddhh varchar, 
  created timeuuid,  
  stuff text, 
  PRIMARY KEY(yymmddhh, created)
);

Cassandra は内部的に行を作成します。キーは 1 日の時間で、列名は実際に作成されたタイムスタンプであり、データはデータです。これにより、クエリが効率的になります。

次のデータがあるとします (簡単にするために、2k レコードには行きませんが、考え方は同じです)。

insert into mystuff(yymmddhh, created, stuff) VALUES ('13081615', now(), '90');
insert into mystuff(yymmddhh, created, stuff) VALUES ('13081615', now(), '91');
insert into mystuff(yymmddhh, created, stuff) VALUES ('13081615', now(), '92');
insert into mystuff(yymmddhh, created, stuff) VALUES ('13081615', now(), '93');
insert into mystuff(yymmddhh, created, stuff) VALUES ('13081615', now(), '94');
insert into mystuff(yymmddhh, created, stuff) VALUES ('13081616', now(), '95');
insert into mystuff(yymmddhh, created, stuff) VALUES ('13081616', now(), '96');
insert into mystuff(yymmddhh, created, stuff) VALUES ('13081616', now(), '97');
insert into mystuff(yymmddhh, created, stuff) VALUES ('13081616', now(), '98');

ここで、最後の 2 つのエントリを選択するとします (「最新」の行キーが '13081616' であることがわかっていると仮定しましょう)。次のようなクエリを実行することで実行できます。

SELECT * FROM mystuff WHERE yymmddhh = '13081616' ORDER BY created DESC LIMIT 2 ;

これはあなたに次のようなものを与えるはずです:

 yymmddhh | created                              | stuff
----------+--------------------------------------+-------
 13081616 | 547fe280-067e-11e3-8751-97db6b0653ce |    98
 13081616 | 547f4640-067e-11e3-8751-97db6b0653ce |    97

次の 2 行を取得するには、列から最後の値を取得しcreated、次のクエリに使用する必要があります。

SELECT * FROM mystuff WHERE  yymmddhh = '13081616' 
AND created < 547f4640-067e-11e3-8751-97db6b0653ce 
ORDER BY created DESC LIMIT 2 ;

受信した行が予想より少ない場合は、行キーを別の時間に変更する必要があります。

ロウキーの扱い・計算

ここでは、データのクエリに使用する行キーがわかっていると想定しています。多くの情報をログに記録する場合、それは問題ではないと思います。現在の時刻だけを取得して、現在の時刻に設定されたクエリを発行できます。行が不足した場合は、1 時間を差し引いて、別のクエリを発行できます。

ただし、データがどこにあるのかわからない場合、またはデータが均等に分散されていない場合は、行キーに関する情報を格納するメタデータ テーブルを作成できます。

CREATE TABLE mystuff_metadata(
  yyyy varchar, 
  yymmddhh varchar, 
  PRIMARY KEY(yyyy, yymmddhh)
) WITH COMPACT STORAGE;

行キーは年ごとに編成されるため、現在の年から最新の行キーを取得するには、クエリを発行する必要があります。

SELECT yymmddhh 
FROM  mystuff_metadata where yyyy = '2013' 
ORDER BY yymmddhh DESC LIMIT 1;

監査ソフトウェアは、開始時とその後の各時間の変更時にそのテーブルにエントリを作成する必要があります (たとえば、にデータを挿入する前mystuff)。

于 2013-08-16T15:27:42.590 に答える