首先,我会告诉你一个不好的做法。如果你插入以下这些行:
insert into foo (row,column,txt) values (1,1,'First Insert');
insert into foo (row,column,txt) values (1,2,'Second Insert');
insert into foo (row,column,txt) values (2,1,'First Insert');
insert into foo (row,column,txt) values (2,2,'Second Insert');
做一个
'select row from foo;'
将会给你以下内容:
row
-----
1
1
2
2
由于它显示了所有可能的行和列的组合,因此不是唯一的。要查询获取一个行值,可以添加一个列值:
select row from foo where column = 1;
但是你会收到这个警告:
Bad Request: Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING
好的。那么,有了这个:
select row from foo where column = 1 ALLOW FILTERING;
row
1
2
很好,这正是我想要的。但我们不能忽视那个警告。如果你只有少量的行,比如10000行,那么这个查询不会对性能造成很大影响。但是如果我有10亿行呢?根据节点数和副本因子的不同,性能将受到严重影响。首先,查询必须扫描表中的每一行(称为全表扫描),然后过滤结果集中的唯一值。在某些情况下,此查询可能会超时。考虑到这一点,这可能不是你要找的。
你提到你担心在多个表中插入数据会影响性能。在数据建模方面,多表插入是一种完全有效的技术。Cassandra可以处理大量写入操作。至于在同步方面是否会有问题,我不知道你的具体应用程序,但我可以给出一些一般性的建议。
如果你需要进行唯一扫描,你需要考虑分区列。这就是我们所谓的索引或查询表。在任何Cassandra数据模型中,考虑到应用程序查询至关重要。例如,如果我正在使用IP地址作为行键,我可能会创建以下内容以按顺序扫描所有IP地址。
CREATE TABLE ip_addresses (
first_quad int,
last_quads ascii,
PRIMARY KEY (first_quad, last_quads)
);
现在,要在我的192.x.x.x地址空间中插入一些行:
insert into ip_addresses (first_quad,last_quads) VALUES (192,'000000001');
insert into ip_addresses (first_quad,last_quads) VALUES (192,'000000002');
insert into ip_addresses (first_quad,last_quads) VALUES (192,'000001001');
insert into ip_addresses (first_quad,last_quads) VALUES (192,'000001255');
为了在192个空间中获取不同的行,我这样做:
SELECT * FROM ip_addresses WHERE first_quad = 192;
first_quad | last_quads
192 | 000000001
192 | 000000002
192 | 000001001
192 | 000001255
要获取每一个地址,您只需要迭代从0到255的每一个可能的行键。在我的示例中,我希望应用程序请求特定的范围以保持性能。您的应用程序可能有不同的需求,但希望您可以看到这里的模式。