2016-02-29 19 views
7

Tôi mới sử dụng cơ sở dữ liệu NoSQL và mới bắt đầu sử dụng apache Cassandra. Tôi tạo ra một bảng "emp" đơn giản với khóa chính trên cột "empno". Đây là một bảng đơn giản như chúng ta luôn nhận được trong lược đồ scott mặc định của Oracle.Địa điểm và thứ tự theo các khoản trong Cassandra CQL

Bây giờ tôi đã tải dữ liệu bằng cách sử dụng lệnh COPY và truy vấn được phát hành Select * from emp order by empno nhưng tôi đã ngạc nhiên khi CQL không cho phép Đặt hàng theo cột empno (là PK). Ngoài ra khi tôi sử dụng điều kiện Where, nó không cho phép bất kỳ hoạt động bất bình đẳng nào trên cột empno (nó chỉ cho phép điều kiện EQ hoặc IN được cho phép). Nó cũng không cho phép Vị trí và Đặt hàng bằng bất kỳ cột nào khác, vì chúng không được sử dụng trong PK và không có chỉ mục.

Ai đó có thể vui lòng giúp tôi tôi nên làm gì nếu tôi muốn giữ empno duy nhất trong bảng và muốn có kết quả truy vấn theo thứ tự Sắp xếp là empno?

(phiên bản của tôi là:

cqlsh:demodb> show version [cqlsh 5.0.1 | Cassandra 2.2.0 | CQL spec 3.3.0 | Native protocol v4] )

Trả lời

10

Có hai phần cho một PRIMARY KEY Cassandra:

  • chìa khóa phân vùng (s)
  • chính clustering (s)

PRIMARY KEY (partitionKey1,clusteringKey1,clusteringKey2)

hoặc

PRIMARY KEY ((partitionKey1,partitionKey2),clusteringKey1,clusteringKey2)

Chìa khóa phân vùng xác định nút (s) dữ liệu của bạn được lưu trữ trên. Phím phân cụm xác định thứ tự của dữ liệu trong khóa phân vùng của bạn.

Trong CQL, mệnh đề ORDER BY thực sự chỉ được sử dụng để đảo ngược hướng sắp xếp được xác định cho thứ tự nhóm của bạn. Đối với các cột tự, bạn chỉ có thể chỉ định các cột được xác định (và theo thứ tự chính xác đó ... không bỏ qua) trong mệnh đề CLUSTERING ORDER BY của bạn tại thời điểm tạo bảng. Vì vậy, bạn không thể chọn các cột tùy ý để đặt hàng kết quả của bạn được đặt tại thời điểm truy vấn.

Cassandra đạt hiệu suất bằng cách sử dụng các phím phân cụm để sắp xếp dữ liệu của bạn trên đĩa, do đó chỉ trả về các hàng đã đặt trong một lần đọc duy nhất (không đọc ngẫu nhiên). Đây là lý do tại sao bạn phải thực hiện một phương pháp tiếp cận mô hình dựa trên truy vấn (thường nhân đôi dữ liệu của bạn thành nhiều bảng truy vấn) với Cassandra. Biết trước các truy vấn của bạn và xây dựng các bảng của bạn để phục vụ chúng.

Select * from emp order by empno; 

Trước hết, bạn cần mệnh đề WHERE. Bạn có thể truy vấn nếu không có nó, nếu bạn đang làm việc với một cơ sở dữ liệu quan hệ. Với Cassandra, bạn nên cố gắng hết sức để tránh các truy vấn không giới hạn SELECT. Bên cạnh đó, Cassandra chỉ có thể thực thi một thứ tự sắp xếp trong một phân vùng, do đó truy vấn không có mệnh đề WHERE sẽ không trả lại dữ liệu theo thứ tự bạn muốn.

Thứ hai, như tôi đã đề cập ở trên, bạn cần xác định các khóa phân cụm. Nếu bạn muốn đặt kết quả của mình theo empno, thì bạn phải tìm một cột khác để xác định là khóa phân vùng của mình.Hãy thử một cái gì đó như thế này:

CREATE TABLE emp_by_dept (
    empno text, 
    dept text, 
    name text, 
    PRIMARY KEY (dept,empno) 
) WITH CLUSTERING ORDER BY (empno ASC); 

Bây giờ, tôi có thể truy vấn các nhân viên của bộ phận, và họ sẽ được trả lại cho tôi ra lệnh bởi empno:

SELECT * FROM emp_by_dept WHERE dept='IT'; 

Tuy nhiên, để được rõ ràng, bạn sẽ không được có thể truy vấn mọi hàng trong bảng của bạn và đặt hàng theo một cột. Cách duy nhất để có được thứ tự có ý nghĩa trong bộ kết quả của bạn, trước tiên là phân vùng dữ liệu của bạn theo cách có ý nghĩa đối với trường hợp kinh doanh của bạn. Chạy một không ràng buộc SELECT sẽ trả về tất cả các hàng của bạn (giả sử truy vấn không hết thời gian trong khi cố gắng truy vấn mọi nút trong cụm của bạn), nhưng đặt kết quả chỉ có thể được thực thi trong một phân vùng. Vì vậy, bạn phải hạn chế bởi khóa phân vùng để cho rằng để làm cho bất kỳ ý nghĩa.

Xin lỗi vì đã tự quảng cáo, nhưng năm ngoái tôi đã viết một bài báo cho DataStax có tên là We Shall Have Order!, trong đó tôi đã giải quyết cách giải quyết các loại vấn đề này. Cung cấp cho nó một đọc và xem nếu nó giúp.

Chỉnh sửa cho câu hỏi thêm:

Từ câu trả lời của bạn tôi kết luận 2 điều về Cassandra:

(1) Không có cách để nhận được một tập kết quả mà chỉ là trật tự của một cột có được định nghĩa là Duy nhất.

(2) Khi chúng ta định nghĩa một PK (partition-key + cluster-key), sau đó kết quả sẽ luôn luôn được tự bởi Clustering cột trong một phím bất kỳ phân vùng cố định (chúng ta phải hạn chế đến một giá trị phân vùng-key), điều đó có nghĩa là không cần mệnh đề ORDER BY vì nó không bao giờ có thể thay đổi thứ tự các hàng (thứ tự trong những hàng nào được lưu trữ thực sự), tức là Order By là vô dụng.

1) Tất cả các khóa PRIMARY trong Cassandra là duy nhất. Không có cách nào để đặt kết quả của bạn bằng khóa phân vùng. Trong ví dụ của tôi, tôi đặt hàng theo số empno (sau khi phân vùng theo nợ). - Aaron 1 giờ trước

2) Ngừng nói rằng ORDER BY là vô ích, tôi sẽ nói rằng việc sử dụng thực sự duy nhất của nó là chuyển hướng sắp xếp của bạn giữa ASC và DESC.

Tôi đã tạo chỉ mục trên cột "empno" của bảng "emp", vẫn không phải là cho phép ORDER BY empno. Vì vậy, những gì chỉ số được cho? chúng chỉ dành cho bản ghi tìm kiếm cho giá trị cụ thể của khóa chỉ mục không?

Bạn không thể đặt hàng bộ kết quả theo cột được lập chỉ mục. Chỉ mục phụ (không giống như các đối tác quan hệ của chúng) thực sự chỉ hữu ích cho các truy vấn dựa trên phân tích, cạnh tranh. Chúng không mở rộng quy mô, do đó, khuyến cáo chung là không sử dụng các chỉ mục phụ.

Ok, điều đó đơn giản có nghĩa là không thể sử dụng một bảng để nhận các bộ kết quả khác nhau với các điều kiện khác nhau và phân loại khác nhau .

Đúng.

Do đó, đối với mỗi yêu cầu mới, chúng tôi cần tạo một bảng mới. CNTT có nghĩa là nếu chúng ta có một tỷ hàng trong bảng (nói bảng Sales), và chúng ta cần tổng doanh thu (1) Sản phẩm khôn ngoan, (2) Vùng khôn ngoan, sau đó chúng ta sẽ sao chép tất cả hàng tỷ trong 2 các bảng có một cụm theo cụm thứ tự của Sản phẩm, thứ tự theo thứ tự phân cụm của Vùng. và thậm chí nếu chúng ta cần tính tổng doanh số trên mỗi Salesman_id, thì chúng tôi sẽ tạo bảng thứ ba, một lần nữa đặt tất cả hàng tỷ tỷ đó? nó có hợp lý không?

Bạn thực sự quyết định mức độ hợp lý của nó. Nhưng thiếu tính linh hoạt của truy vấn là một nhược điểm của Cassandra. Để khắc phục nó, bạn có thể tiếp tục tạo các bảng truy vấn (I.E., đĩa giao dịch để thực hiện). Nhưng nếu nó trở thành một điểm mà nó trở nên vô duyên hoặc khó quản lý, thì đã đến lúc phải nghĩ xem Cassandra có thực sự là giải pháp đúng hay không.

EDIT 20160321

Hi Aaron, bạn nói ở trên "Dừng ngắn nói rằng ORDER BY là vô ích, tôi sẽ nói rằng việc sử dụng thực duy nhất của nó là chuyển đổi sang hướng sắp xếp của bạn giữa ASC và DESC . "

Nhưng tôi thấy ngay cả điều đó cũng không chính xác. Cassandra chỉ cho phép ORDER theo cùng một hướng như chúng ta định nghĩa trong phần "CLUSTERING ORDER BY" của CREATE TABLE. Nếu trong mệnh đề đó, chúng tôi định nghĩa ASC, nó chỉ cho phép lệnh ASC và ngược lại.

Không thấy thông báo lỗi, thật khó để biết phải nói gì với bạn. Mặc dù tôi đã nghe nói về các truy vấn bị lỗi ORDER BY khi bạn có quá nhiều hàng được lưu trữ trong một phân vùng.

ORDER BY cũng hoạt động hơi lạ nếu bạn chỉ định nhiều cột để sắp xếp theo. Nếu tôi có hai cột phân cụm được xác định, tôi có thể sử dụng ORDER BY trên cột đầu tiên bừa bãi. Nhưng ngay khi tôi thêm cột thứ hai vào mệnh đề ORDER BY, truy vấn của tôi chỉ hoạt động nếu tôi chỉ định cả hai chỉ đường sắp xếp giống nhau (như định nghĩa CLUSTERING ORDER BY) hoặc cả hai khác nhau. Nếu tôi trộn và kết hợp, tôi nhận được thông tin này:

InvalidRequest: code=2200 [Invalid query] message="Unsupported order by relation" 

Tôi nghĩ rằng phải làm thế nào để dữ liệu được lưu trữ trên đĩa. Nếu không Cassandra sẽ có nhiều việc phải làm để chuẩn bị các bộ kết quả. Trong khi nếu nó đòi hỏi mọi thứ phải khớp hoặc phản chiếu (các) hướng được chỉ định trong CLUSTERING ORDER BY, nó chỉ có thể tiếp tục đọc tuần tự từ đĩa. Vì vậy, tốt nhất là chỉ nên sử dụng một cột trong mệnh đề ORDER BY của bạn, để có kết quả dự đoán được nhiều hơn.

+0

Cảm ơn câu trả lời chi tiết của bạn! Tôi đánh giá cao. Từ câu trả lời của bạn, tôi đã kết luận 2 điều về Cassandra: (1) Không có cách nào để có được một tập kết quả mà chỉ là thứ tự của một cột đã được định nghĩa là duy nhất, và (2) Khi chúng ta định nghĩa một PK (phân vùng-key + clustering-key), sau đó kết quả sẽ luôn là thứ tự bằng cách Clustering các cột trong bất kỳ khóa phân vùng cố định nào (chúng ta phải hạn chế một giá trị khóa phân vùng), điều đó có nghĩa là không cần mệnh đề ORDER BY, vì nó không bao giờ có thể thay đổi thứ tự của các hàng (thứ tự các hàng thực sự được lưu trữ), tức là Order By là vô dụng. –

+0

Ok, cảm ơn một lần nữa. Một điều nữa, tôi tạo ra một chỉ mục trên cột "empno" của bảng "emp", nó vẫn không cho phép ORDER BY empno. Vì vậy, những gì chỉ số được cho? chúng chỉ dành cho việc tìm kiếm các bản ghi cho giá trị cụ thể của khóa chỉ mục? –

+0

Ok, điều đó đơn giản có nghĩa là không thể sử dụng một bảng để nhận các tập hợp kết quả khác nhau với các điều kiện khác nhau và thứ tự sắp xếp khác nhau. Do đó với mỗi yêu cầu mới, chúng ta cần tạo một bảng mới. IT có nghĩa là nếu chúng ta có một tỷ hàng trong bảng (nói bảng Sales), và chúng ta cần tổng doanh thu (1) Product-wise, (2) Region-wise, sau đó chúng ta sẽ nhân đôi tất cả hàng tỷ trong 2 bảng với một theo thứ tự nhóm của Sản phẩm, thứ tự khác theo thứ tự phân cụm của Vùng. và thậm chí nếu chúng ta cần tính tổng doanh số trên mỗi Salesman_id, thì chúng ta sẽ xây dựng một bảng thứ 3, một lần nữa đặt tất cả hàng tỷ tỷ đó? nó có hợp lý không? –

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