카산드라에는 여러 key 개념이 있다.



CQL을 이용할 때 일반 Database를 사용하 듯 table을 생성할 때 다음처럼 키를 생성할 수 있다. 


primary key(col1, col2, col3)


* primary key 

DB의 pk와 비슷하다. row를 유일무이하게 해주는 key를 의미한다. 1개 이상의 키가 필요하다. 


* composite(compound) key

primary key가 2개 이상이면 composite key라 부른다.


* partition key

partition key는 primary key의 1번째 key(예시에서는 col1)를 의미한다. 저장소 row key로 직접 변환하고 해시 알고리즘에 따라 클러스터에 저장(분배)된다. 대부분의 질의는 partition key를 제공해서 카산드라는 요청된 데이터가 어느 노드에 있는지 알게 된다. 


* clustering key

primary key의 1번째 key외 나머지 key를 clustering key(또는 clustering column)라 한다. 해당 key는 디스크에 데이터 순서를 안다. 하지만 어느 노드에 저장될지는 결정하지 않는다. 

순서 관련해서 오름차순, 내림차순으로 변경할 수 있다. 


with clustering order by (col2 desc) 




실제로는 '값:값'이 아닌 'col1의 값:col2의컬럼 이름'의 조합으로 되어 있다. 따라서 2.x까지는 중복이 발생할 수 있지만, 3.x부터는 문제가 없도록 되어 있다고 한다. 


실제 예시를 소개한다.


$cqlsh 

cqlsh:google> 

CREATE TABLE story.crizin (

    a int,

    b int,

    c int,

    d int,

    type int,

    PRIMARY KEY (a, b, c)


cqlsh:google> insert into google.crizin(a,b,c,d,type) values(1,1,1,1,1);

cqlsh:google> insert into google.crizin(a,b,c,d,type) values(2,2,2,2,2);



$ cassandra-cli -h IP -port 9160

[default@google] list crizin

... ;

Using default limit of 100

Using default cell limit of 100

-------------------

RowKey: 1

=> (name=1:1:, value=, timestamp=1484644014043867)

=> (name=1:1:d, value=00000001, timestamp=1484644014043867)

=> (name=1:1:type, value=00000001, timestamp=1484644014043867)

-------------------

RowKey: 2

=> (name=2:2:, value=, timestamp=1484644020194477)

=> (name=2:2:d, value=00000002, timestamp=1484644020194477)

=> (name=2:2:type, value=00000002, timestamp=1484644020194477)


2 Rows Returned.


cassandra data layer에서는 콜론 단위로 저장됨을 확인할 수 있다. 




지금까지 하나의 partition key에 여러 clustering 컬럼 조합을 살펴봤다. partition key를 multi로 둘 수 있다. 


primary key((col1, col2), col3)



* composite partition key

composite partition key는 다수의 컬럼을 partition key로 둔다. 


data layer에서는 row key를 'col1의 값:col2의 값'으로 변경한다. 


$cqlsh 

cqlsh:google> 


CREATE TABLE story.crizin1 (

    a int,

    b int,

    c int,

    d int,

    type int,

    PRIMARY KEY ((a, b), c)


cqlsh> insert into story.crizin1(a,b,c,d,type) values(2,2,2,2,2);

cqlsh> insert into story.crizin1(a,b,c,d,type) values(1,1,1,1,1);




$ cassandra-cli -h IP -port 9160

[default@story] use story;

Authenticated to keyspace: story

[default@story] list story.crizin1;

 list crizin1;

Using default limit of 100

Using default cell limit of 100

-------------------

RowKey: 2:2

=> (name=2:, value=, timestamp=1484645817202697)

=> (name=2:d, value=00000002, timestamp=1484645817202697)

=> (name=2:type, value=00000002, timestamp=1484645817202697)

-------------------

RowKey: 1:1

=> (name=1:, value=, timestamp=1484645825186628)

=> (name=1:d, value=00000001, timestamp=1484645825186628)

=> (name=1:type, value=00000001, timestamp=1484645825186628)


2 Rows Returned.

Elapsed time: 58 msec(s).



key 말고 secondary index가 존재한다. index를 구축할 수 있지만, 


CREATE INDEX d_index ON crizin(d);


성능 이슈가 존재한다는 커다란 단점이 있다. (자세한 내용은 다음 블로그에서 설명한다)







Posted by '김용환'
,