2015-01-06 3 views
3

안녕하세요 저는 카산드라를 처음 사용합니다. 아래 시나리오에서 DB 디자인에 약간의 혼동이 있습니다.카산드라 + MySQL

현재 저는 3 개의 테이블을 가지고 있습니다 : Post, User, PostLike.

포스트 : 저장 후 정보

사용자 : 저장소 사용자 정보

PostLIke :

CREATE TABLE PostLike (
    like_time timestamp 
    post_id bigint, 
    user_id bigint, 
    PRIMARY KEY (like_time,post_id,user_id) 
); 

like_time : 시간처럼 우편으로 포스트 순서를 저장하는 데 사용. 그들이 사용되었다 like_time에 의해 주어진 포스트 위해 추천하고

  1. 모든 사용자 ID : 카산드라는

    요구 사항은 OrderPreservingPartitioner이 제공 선택 * PostLike에서 어디 post_id를 =를?

  2. 모든 게시물 사용자가 좋아하는 모든 게시물 select * from PostLike where user_id =? :이 오류

을 준 [잘못된 쿼리] 메시지 = "PRIMARY KEY 열"post_id를 = user_id를 ColumnDefinition {이름 = org.apache.cassandra 유형 " 제한 (이전 열 수 없습니다." db.marshal.LongType, 종류 = CLUSTERING_COLUMN는 는 componentIndex = 0, INDEXNAME = NULL,는 indexType = NULL}

pls는 내가에 필요한 제안 "중 하나를하지 제한 또는 비 EQ 관계)입니다" 여기에서 :

또는

카산드라

CREATE TABLE PostLike (
    like_time timestamp 
    post_id bigint, 
    PRIMARY KEY (like_date,post_id) 
); 

CREATE TABLE UserLike (
    like_time timestamp 
    user_id bigint, 
    PRIMARY KEY (like_date,user_id) 
); 

또는 다른 어떤 솔루션이 별도의 테이블을 만들고 이러한 관계에 대한 카산드라와 MySQL을 사용하는

  1. 필요. 도와주세요.

+1

옵션 # 2로 이동하십시오. 비정규 화는 새로운 검정색입니다. 답장을 보내 주셔서 감사합니다. – ethrbunny

+0

또한 색인을 추가하면 위의 오류 해결 – navy

답변

2

먼저 "중 하나를하지 제한 또는 비 EQ 관계)입니다", 당신은 그 오류 때문에지고있다 첫 번째 부분을 지정하지 않고 기본 키의 두 번째 부분을 지정합니다. 복합 기본 키로 Cassandra에서 쿼리 할 때 키의 일부를 건너 뛸 수 없습니다. 키의 끝에서 파트를 제외하고 파티션 키 (아래 참조)를 쿼리하면 키의 일부를 건너 뛸 경우 작동하지 않습니다.

다음으로, 2 차 인덱스는 MySQL에서와 마찬가지로 Cassandra에서 동일하게 작동하지 않습니다 .Cassandra에서는 성능이 아닌 편의를 위해 제공되며, 카디널리티는 post_iduser_id 일 가능성이 높습니다. 특히 큰 클러스터에서는 수백만 행의 보조 색인 질의 성능이 상위 카디널리티 2 차 색인에서 상당히 떨어집니다.

이 문제를 해결하는 적절한 방법은 두 번째 옵션 (etherbunny 권장)을 사용하는 것입니다. 당신의 기본 키.

CREATE TABLE PostLike (
    like_time timestamp 
    post_id bigint, 
    PRIMARY KEY (post_id,like_date) 
); 

CREATE TABLE UserLike (
    like_time timestamp 
    user_id bigint, 
    PRIMARY KEY (user_id,like_date) 
); 

카산드라 기본 키의 첫 번째 키를 파티션 키라고합니다. 이 키는 행이 저장 될 토큰 범위를 결정합니다.

카산드라 기본 키의 나머지 키는 clustering columns입니다. 클러스터링 열은 파티션 키 내의 디스크상의 정렬 순서 을 결정하는 데 도움이됩니다.

마지막 부분은 (클러스터링 순서뿐만 아니라 ORDER BY 키워드와 마찬가지로) MySQL 또는 RDBMS와는 매우 다르게 동작하므로 중요합니다. 이렇게하면 SELECT * FROM user_like WHERE user_id=34574398 ORDER BY like_date에 like_date에 의해 정렬 된 user_id에 대한 좋아요가 표시됩니다. 실제로 ORDER BY 절이 없어도 like_date에 의해 정렬되어야합니다. 그러나 SELECT * FROM user_like ORDER BY like_date 인 경우 데이터는 이 아닌이 예상 순서로 정렬됩니다. 이는 순서 지정이 파티션 키가 지정된 경우에만 작동하기 때.입니다.

+1

덕분에 많이. 또한 OrderPreservingPartitioner를 사용하면 cassandra가 파티션 키의 ASC 순서로 행을 삽입합니다.
또한 파티션 키를 생성합니다 : Long.Max_VALUE - currentTime. 그래서 기본적으로 모든 행이 정렬되므로 선택 시간에 정렬 할 필요가 없습니다. 또한 다음과 같이 시간을 얻을 수 있습니다 : Long.Max_VALUE - partitionKey. 그러나 나는이 접근법이 약간 혼란 스럽다. 짧은 시간은 더 좋습니다 : 시간을 삽입하거나 시간을 선택하십시오. – navy

+0

Murmur3 파티션을 사용해야합니다. 주문한 파티션 도구는 더 이상 사용되지 않습니다. – Aaron

+0

감사합니다. 너 나를 구해줘. 또한 나는 파티션 키로 주문하고 싶습니다. 가능합니다. 키 순서를 분할하기 위해 하나 이상의 테이블을 추가해야합니까? – navy

2

이하 인덱스를 만들면 오류가 해결됩니다.

CREATE INDEX post_id_PostLike_indx ON post_like (post_id); 
CREATE INDEX user_id_PostLike_indx ON post_like (user_id); 

[잘못된 검색어] 메시지 = "PRIMARY KEY 칼럼"post_id를 USER_ID ColumnDefinition = {NAME = org.apache.cassandra.db.marshal 형 " 제한 (이전 열 수 없다".LongType, 종류 = CLUSTERING_COLUMN이 이 componentIndex = 0, INDEXNAME = NULL,는 indexType = NULL} 모든