2015-02-17 18 views
13

Tôi đang sử dụng Cassandra lần đầu tiên trong một ứng dụng web và tôi gặp vấn đề truy vấn. Đây là tab của tôi:cassandra cột khóa chính không thể bị hạn chế

CREATE TABLE vote (
    doodle_id uuid, 
    user_id uuid, 
    schedule_id uuid, 
    vote int, 
    PRIMARY KEY ((doodle_id), user_id, schedule_id) 
); 

Theo yêu cầu, tôi chỉ định khóa phân vùng, doodle_id. Ví dụ tôi có thể làm mà không cần bất kỳ vấn đề:

select * from vote where doodle_id = c4778a27-f2ca-4c96-8669-15dcbd5d34a7 and user_id = 97a7378a-e1bb-4586-ada1-177016405142; 

Nhưng theo yêu cầu cuối cùng tôi thực hiện:

select * from vote where doodle_id = c4778a27-f2ca-4c96-8669-15dcbd5d34a7 and schedule_id = c37df0ad-f61d-463e-bdcc-a97586bea633; 

Tôi đã nhận lỗi sau:

Bad Request: PRIMARY KEY column "schedule_id" cannot be restricted (preceding column "user_id" is either not restricted or by a non-EQ relation) 

Tôi mới với Cassandra, nhưng sửa tôi nếu tôi sai, trong một khóa chính hỗn hợp, phần đầu tiên là chìa khóa PARTITION đó là bắt buộc để cho phép Cassandra biết nơi để tìm kiếm dữ liệu. Sau đó, các bộ phận khác là CLUSTERING KEY để sắp xếp dữ liệu.

Nhưng tôi vẫn không hiểu tại sao yêu cầu đầu tiên của tôi hoạt động chứ không phải yêu cầu thứ hai?

Nếu có ai đó có thể giúp nó sẽ là một niềm vui lớn.

Trả lời

9

Trong Cassandra, bạn nên thiết kế mô hình dữ liệu cho phù hợp với truy vấn của mình. Do đó, cách thích hợp để hỗ trợ truy vấn thứ hai của bạn (truy vấn bởi doodle_idschedule_id, nhưng không cần thiết với user_id), là tạo một bảng mới để xử lý truy vấn cụ thể đó. Bảng này sẽ được khá nhiều giống nhau, ngoại trừ PRIMARY KEY sẽ hơi khác nhau:

CREATE TABLE votebydoodleandschedule (
    doodle_id uuid, 
    user_id uuid, 
    schedule_id uuid, 
    vote int, 
    PRIMARY KEY ((doodle_id), schedule_id, user_id) 
); 

Bây giờ truy vấn này sẽ làm việc:

SELECT * FROM votebydoodleandschedule 
WHERE doodle_id = c4778a27-f2ca-4c96-8669-15dcbd5d34a7 
AND schedule_id = c37df0ad-f61d-463e-bdcc-a97586bea633; 

này giúp bạn xung quanh phải chỉ định ALLOW FILTERING.Dựa trên ALLOW FILTERING không bao giờ là một ý tưởng tốt, và chắc chắn không phải là một cái gì đó mà bạn nên làm trong một cụm sản xuất.

+0

Cảm ơn rất nhiều vì hai câu trả lời! Bây giờ tôi hiểu rõ hơn về cách Cassandra hoạt động. Vì vậy, tôi đã tạo một bảng mới như bạn đã đề cập để xử lý truy vấn của tôi và nó hoạt động tốt ngay bây giờ. – Orodan

+0

và nếu tôi muốn thực hiện> và

+0

@ParthTrivedi Để thực hiện truy vấn phạm vi trên 'doodle_id', bạn sẽ cần phải tạo một bảng mới có khóa phân vùng khác (tìm hiểu ý nghĩa của dữ liệu của bạn). Sau đó, bạn có thể truy vấn một phạm vi 'doodle_id' cho một khóa phân vùng cụ thể. – Aaron

3

Phím phân cụm cũng được sử dụng để tìm các cột trong một phân vùng nhất định. Với mô hình của bạn, bạn sẽ có thể truy vấn bởi:

  • doodle_id
  • doodle_id/user_id
  • doodle_id/user_id/schedule_id
  • user_id sử dụng ALLOW FILTERING
  • user_id/schedule_id sử dụng ALLOW FILTERING

Bạn có thể thấy khóa chính của mình dưới dạng đường dẫn tệp doodle_id # 123/user_id # 456/schedule_id # 789 nơi tất cả dữ liệu được lưu trữ trong thư mục sâu nhất (tức là schedule_id # 789). Khi bạn đang truy vấn, bạn phải chỉ ra thư mục con/cây con từ nơi bạn bắt đầu tìm kiếm.

Truy vấn thứ hai của bạn không hoạt động do cách sắp xếp các cột trong phân vùng. Cassandra không thể nhận được slice liên tục của các cột trong phân vùng vì chúng được xen kẽ.

Bạn nên đảo ngược thứ tự khóa chính (doodle_id, schedule_id, user_id) để có thể chạy truy vấn của mình.

Các vấn đề liên quan