【问题标题】:Create an index, or add to the primary key and create a new table?创建索引,还是添加到主键并创建新表?
【发布时间】:2023-03-08 22:40:01
【问题描述】:

在 Cassandra 中,我有一个包含 (a,b,c) 列的表格。我要么需要查询SELECT * FROM {table} WHERE a = ? and b = ?SELECT * FROM {table} WHERE a = ? and c = ?

在这种情况下,我应该怎么做主键?我可以用PRIMARY KEY(a,b)PRIMARY KEY(a,c) 制作两张表吗,因为 Cassandra 需要按照列出的顺序列出全部分区键和/或非分区键?或者我可以做类似PRIMARY KEY(a) 并在bc 上创建INDEX 吗?

基本上,主键是否应该只包含唯一性所需的最少数量的值(并从这些值中选择适当的分区键)?如果我因为需要查询而将其他列添加到主键,性能会提高吗?

【问题讨论】:

  • 很难回答,with the information that you have provided。请编辑您的完整架构和列基数详细信息以进行更多调查。只有有了这些信息,才能分析架构。

标签: database-design cassandra database nosql


【解决方案1】:

如上所述,只有提供有关 a、b 和 c 列的基数的更多信息,才能给出有充分根据的答案。还要确保你理解分区键和集群键的含义——它们都是主键的一部分,对你的设计有很大的影响。

如果 a 列中有足够多的不同值,则可以将其设为分区键,并从以下两种方法中选择一种:

1) 每个查询都有单独的表

CREATE TABLE table1_by_ab (
  a int, b int, c int, 
  PRIMARY KEY (a, b));

CREATE TABLE table1_by_ac (
  a int, b int, c int, 
  PRIMARY KEY (a, c));

2) 一个表用于更频繁的查询,而索引用于另一列:

CREATE TABLE table2 (
  a int, b int, c int, 
  PRIMARY KEY (a, b));

CREATE INDEX ON table2 (c);

在这两种情况下,您都可以在 (a,b) 和 (a,c) 上执行查询。通常建议避免使用二级索引,但是在情况2)你对(a,c)的查询预先选择了分区键(字段a),所以二级索引可以在单个节点上执行,它的性能不会做坏事。

如果您在 a 列中没有足够的不同值,那么您无法将其设为分区键,您将需要使用复合分区键复制您的表:

CREATE TABLE table3_by_ab (
  a int, b int, c int, 
  PRIMARY KEY ((a, b)));

CREATE TABLE table3_by_ac (
  a int, b int, c int, 
  PRIMARY KEY ((a, c)));

希望对你有帮助

【讨论】:

  • 感谢您的详细解答!
  • 所以一般来说,为每个查询创建一个新表是可以的,正如我在 SO 上多次看到的那样?例如,考虑是否将这种情况扩展为一个表,其中包含以不同顺序查询的五个参数。是否可以创建多个 (3-4) 个具有相同信息但具有不同主键的表来适应这些查询?
  • 最后一个问题:使用PRIMARY KEY(a,b,c)PRIMARY KEY(a,b) 查询SELECT * FROM TABLE WHERE a = ? and b = ? and c = ?INDEX 上的INDEX 有区别吗?
  • 在 Cassandra 中复制表很好,因为写入速度非常快并且磁盘空间很便宜。但是,相同数据的 3-4 个表也可能表明错误的模型或用例并不适合 Cassandra。
  • 按主键查询总是更快。二级索引在写入和读取方面都有开销。如果分区键被预过滤,它们的性能会更好,但它们仍然需要维护和访问。另一方面,它们使用起来更方便,所以我建议创建一个 PoC 并测量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-08
  • 1970-01-01
  • 1970-01-01
  • 2011-08-20
  • 1970-01-01
  • 2013-08-02
  • 2019-06-24
相关资源
最近更新 更多