我是cassandra的新手,我试图向员工插入笔记本电脑映射列表,如下所示' laptoplist'是一个UDT。
cqlsh:sourceutilization> SELECT * from employee ;
id | laptoplist | name | type
----+-----------------------------------------------------------------------------------+-----------+------------
5 | [{laptopid: 5, cpu: 9, memory: 18, networkutilization: 25, diskutilization: 85}] | testname5 | staffType5
1 | [{laptopid: 1, cpu: 94, memory: 36, networkutilization: 13, diskutilization: 66}] | testname1 | staffType1
8 | [{laptopid: 8, cpu: 64, memory: 1, networkutilization: 15, diskutilization: 71}] | testname8 | staffType8
0 | [{laptopid: 0, cpu: 4, memory: 95, networkutilization: 20, diskutilization: 16}] | testname0 | staffType0
2 | [{laptopid: 2, cpu: 49, memory: 37, networkutilization: 20, diskutilization: 88}] | testname2 | staffType2
4 | [{laptopid: 4, cpu: 13, memory: 67, networkutilization: 67, diskutilization: 10}] | testname4 | staffType4
7 | [{laptopid: 7, cpu: 11, memory: 75, networkutilization: 75, diskutilization: 97}] | testname7 | staffType7
6 | [{laptopid: 6, cpu: 27, memory: 34, networkutilization: 2, diskutilization: 92}] | testname6 | staffType6
9 | [{laptopid: 9, cpu: 12, memory: 10, networkutilization: 19, diskutilization: 73}] | testname9 | staffType9
3 | [{laptopid: 3, cpu: 47, memory: 13, networkutilization: 72, diskutilization: 54}] | testname3 | staffType3
现在,我想查询下面的内容,如何实现
select * from employee where laptoplist.networkutilization > 50;
仅供参考,我使用的是3.1 cassandra版本。
提前致谢, 哈利
答案 0 :(得分:2)
这样做不会很好。在这里获得您想要的东西需要进行一些更改。在Cassandra,有两件事情通常会有所帮助。
使用Cassandra的分布式附加存储引擎,时间序列和事件跟踪等用例很容易适应。有时候,当调整到那个角度时,数据模型更有意义(从Cassandra的角度来看)。
我看到ID可能是主要的关键。但我没有看到(至少在上面)是过滤ID的任何查询。我可以说像员工和笔记本电脑这样的东西很重要,而且可能是独一无二的。但是,唯一键并不总能成为最佳信息过滤器。
要问的主要问题是,你想要到达什么地方?
对我来说,您希望看到正在经历高网络利用率的用户。高网络利用率是(希望)暂时的事情,那么为什么我们不向它添加时间组件(checkpoint_time
)? IMO,随着时间的推移跟踪计算资源利用率是有意义的。在考虑了这些要点之后,我想出了这样一个数据模型:
cassdba@cqlsh:stackoverflow> CREATE TABLE employee_laptop__by_network_utilization (
timebucket text,
checkpoint_time timestamp,
employee_id bigint,
name text,
type text,
laptop_id bigint,
cpu bigint,
memory bigint,
network_utilization bigint,
disk_utilization bigint,
PRIMARY KEY ((timebucket),network_utilization,
checkpoint_time,employee_id,laptop_id)
) WITH CLUSTERING ORDER by
(network_utilization ASC, checkpoint_time DESC,
employee_id ASC, laptop_id ASC);
插入一些行后,我现在可以查询遇到网络利用率的员工/笔记本电脑组合> 2017年10月12日50日。
cassdba@cqlsh:stackoverflow> SELECT * FROm employee_laptop__by_network_utilization
WHERE timebucket='20171012' AND network_utilization > 50;
timebucket | network_utilization | checkpoint_time | employee_id | laptop_id | cpu | disk_utilization | memory | name | type
------------+---------------------+---------------------------------+-------------+-----------+-----+------------------+--------+----------+-----------
20171012 | 55 | 2017-10-12 12:30:00.000000+0000 | 1 | 1 | 4 | 62 | 19 | Jebediah | Pilot
20171012 | 55 | 2017-10-12 12:15:00.000000+0000 | 1 | 1 | 19 | 62 | 18 | Jebediah | Pilot
20171012 | 72 | 2017-10-12 12:00:00.000000+0000 | 3 | 3 | 47 | 54 | 13 | Bob | Scientist
(3 rows)
首先,我需要一个好的分区密钥,两者对查询有意义,和阻止我的分区无限制增长。因此,我选择了一个名为“日期存储桶”的timebucket
。这样,我可以隔离一天的查询,并确保每个查询都由单个节点提供。
接下来,我聚集在network_utilization
上,因为这是该模型主要关注的主要列。它是第一个聚类列,因为我们不希望在查询中过滤列的过多提供。
checkpoint_time
是PRIMARY KEY中的下一列,主要是因为具有相同timebucket
和network_utilization
的请求可能更有意义地按时间排序(DESCending)。
最后,我添加employee_id
表示唯一性,然后laptop_id
,因为员工可以拥有多台笔记本电脑。
现在,我确信您将找到与您的用例不完全相符的解决方案。这是因为Cassandra数据建模非常以用例为中心。通常,一个好的解决方案不是适合另一个人。但是,这是获取您所追求的数据的一种方式。
答案 1 :(得分:0)
您不能只对任何列进行范围查询。 cassandra有一些限制。
在cassandra上创建任何架构之前,您必须具体说明要以何种方式执行查询,否则大部分时间您的架构将无效。
要执行大于,大于等于,小于,小于等于的范围查询,您需要在模式中指定群集列。
我们不能简单地在cassandra中仅指定Clustering列。您必须在cassandra的每个模式中声明分区键。
要对群集列执行查询,您必须在查询中传递所有先前的主键值。