问题描述
假设我有以下两个具有相同列但主键不同的表:
CREATE TABLE myTable1 (
id UUID,lastname text,birthday timestamp,nationality text
PRIMARY KEY ((id))
);
VS
CREATE TABLE myTable2 (
id UUID,nationality text
PRIMARY KEY ((id),lastname,birthday,nationality)
);
如本例所示,myTable2
的群集列比myTable1
多3个(没有列)。
除了upserts之外,从myTable1
到myTable2
进行读取或写入还有什么其他区别?有性能差异吗?它的影响力如何?
出于记录,我问这个问题是因为我读到COUNTER
类型的列可能是表中唯一的常规列。所以我想:为什么不将所有其他列设置为聚簇列?(可能很愚蠢,但是为什么?)
编辑:更具体地说,我问的是在查询中不使用聚类列进行任何过滤的情况。在应用以下两个查询时,myTable1
和myTable2
之间是否会有明显的性能差异?
INSERT INTO myTableX (id,nationality) VALUES (123e4567-e89b-12d3-a456-426614174000,'Smith','2013-03-10 00:00+0000','US');
SELECT * FROM myTableX WHERE id = 123e4567-e89b-12d3-a456-426614174000;
解决方法
这取决于您的用例:集群列将确保所有记录具有相同的ID。如果您要检索记录范围,将它们存储在一起并按字典顺序保存,这将非常方便。
在您的示例之后,插入以下内容:
INSERT INTO myTable2 (id,lastname,birthday,nationality) VALUES (123e4567-e89b-12d3-a456-426614174000,'Smith','2013-03-10 00:00+0000','US');
INSERT INTO myTable2 (id,'Garcia','2001-06-10 00:00+0000','ES');
INSERT INTO myTable2 (id,'1978-09-10 00:00+0000','UK');
将在数据库中记录为:
id | lastname | birthday | nationality
-------------------------------------+----------+-----------------------+-------------
123e4567-e89b-12d3-a456-426614174000 | Garcia | 2001-06-10 00:00+0000 | ES
123e4567-e89b-12d3-a456-426614174000 | Smith | 1978-09-10 00:00+0000 | UK
123e4567-e89b-12d3-a456-426614174000 | Smith | 2013-03-10 00:00+0000 | US
如果您的用例需要检索或过滤由特定id
标识的条目,并根据以下条件进行过滤,则此表结构将是理想的
- 姓氏
- 姓氏和生日
- 姓氏,生日和国籍。
如果您的用例需要从该ID中获取所有来自美国的记录,或者获取具有该ID的生日为今天的用户,则引擎将需要对分区执行完整扫描,从而影响查询的性能。
在Cassandra中,表的定义应始终取决于数据的使用方式。
,使用聚类列的优缺点不是问题。这也不是性能问题。
使用群集列确定数据在磁盘上的物理存储方式以及表中数据的结构。
当主键中只有一个分区键时(如您的myTable1
,表中的每个分区都只会有一行。
对于具有复合主键(即,如myTable2
中的分区键+群集列的表)的表,表中的每个分区将具有一行或更多行。 / p>
在您的myTable1
中,每个id
只能有一个姓氏。简而言之,您可以在一个分区(记录)中存储一个人的信息。这是传统的二维表格,就像电子表格中一样。
在myTable2
中,每个id
可以具有一行或多行姓氏。这意味着您可以在每个分区中存储几个人的信息-一个记录具有与之关联的多行。这是一个多维表,也是NoSQL在建模真实数据方面比关系数据库更强大的重要原因。干杯!