我在卡桑德拉有一个表,定义如下
CREATE TABLE IF NOT EXISTS PRODUCT_INV (
Product_Code TEXT,
Storecode TEXT,
StoreType TEXT,
ProductInfo TEXT,
PRIMARY KEY ((Product_Code, Storecode, StoreType)));
现在我想获取特定于商店代码和商店类型的所有Product_Code的列表。 什么是最有效的方法。该表可以包含大量记录。
例如:
Product_Code Storecode StoreType ProductInfo
12 601 Retail ABC
12 601 Supermart ABC
13 601 Retail DEF
14 701 Retail QWE
13 601 Supermart ZXC
结果应该是:
Storecode: 601
StoreType: Retail
List of Product_Code : 12,13
Storecode: 601
StoreType : Supermart
List of Product_Code : 12,13
Storecode: 701
StoreType: Retail
List of Product_Code:14
Cassandra数据建模都是关于非规范化的。如果有疑问,非规范化通常是做某事的最有效方法。
在这种情况下,如果创建下表:
CREATE TABLE IF NOT EXISTS product_codes_by_store (
product_code TEXT,
storecode TEXT,
store_type TEXT
PRIMARY KEY ((storecode, store_type), product_code));
现在,您可以进行此查询以获取所有产品代码:
SELECT * FROM product_codes_by_store WHERE storecode = 'aaa' AND store_type = 'bbb';
这种方法非常有效,因为 Cassandra 只需要命中单个分区(因此也只需要一个节点)即可完成查询。
但是,您需要记住几件事:
- 如果有大量结果,则可能需要对查询进行分页,以便查询不会超时。以下是有关如何执行此操作的 Java 驱动程序的文档:https://docs.datastax.com/en/developer/java-driver/3.1/manual/paging/
- 由于我在此处添加了一个聚类列(
product_code
),因此您需要确保(storecode, store_type)
定义的分区不会太大。建议尽可能将分区保持在 100MB 以下,因为非常大的分区可能会导致性能问题。不过这里有一点回旋余地 - 如果你超过100MB,那还不错,特别是在较新版本的Cassandra上,它对大分区有更好的支持(见 https://issues.apache.org/jira/browse/CASSANDRA-11206)。