作为新手,我有一个关于 Cassandra 的问题。 我想知道是否有可能以某种方式使用 contains 语句进行查询(我发现 in 语句可能不是适合大量数据的最佳选择),该语句接受一系列事物。
类似这样的:
SELECT * FROM table WHERE column CONTAINS('valueA', 'valueB');
在网上搜索时,我读到这是不可能的,但如果我使用太多值,我将不得不编写 60 个 CONTAINS,而且我猜查询会太重。
所以我想知道 Cassandra 是否可以做到这一点,或者是否有解决方法。谢谢!
SELECT * FROM table WHERE column CONTAINS('valueA', 'valueB');
因此,虽然您确实提到了
IN
声明,但这基本上就是您在这里要求它执行的操作。这肯定会起作用。如果我有一个名为 times
且具有单个主键 id
的表,我可以使用 IN
运算符来执行此操作:
SELECT * FROm times WHERE id IN (2,4);
id | time_timestamp | time_uuid
----+---------------------------------+--------------------------------------
2 | 2038-01-19 03:14:07.000000-0600 | 5d83408f-6944-11fe-7f7f-7f7f7f7f7f7f
4 | 2038-01-18 21:14:07.000000-0600 | 12e8d08f-6912-11fe-7f7f-7f7f7f7f7f7f
(2 rows)
CONTAINS
运算符有点不同。我很确定它只接受一个参数。但CONTAINS
仅适用于集合列; List、Set 或 Map 类型的列。因此,如果我有一个表 playlists
,其中包含 tags LIST<TEXT>
列,并在 tags
列上有一个索引,那么这是有效的:
SELECT * FROM playlists WHERE tags CONTAINS 'Progressive Rock';
name | song | artist | tags
--------------+---------------------+--------+------------------------------
favorite 70s | La Villa Strangiato | Rush | ['Rock', 'Progressive Rock']
favorite 70s | Xanadu | Rush | ['Rock', 'Progressive Rock']
(2 rows)
至于“对于大量数据来说不是最好的”部分,你是对的。这两种方法都不适合 Casandra。第一个是我们所说的“多键查询”,第二个是“二级索引查询”。 Cassandra 在大行场景中运行良好,因为它可以通过对分区键运行哈希来找出哪些节点拥有数据。
当 Cassandra 无法精确定位包含数据的节点时(多键查询和二级索引查询都是如此)。它选择一个节点作为“协调节点”。然后,该节点负责联系(在二级索引查询的情况下)集群中的所有其他节点、组装结果集并将其返回给调用应用程序。这将网络时间引入等式中。
如果您运行的是 6 节点集群,那可能还不错。然而,60 个节点的集群就不那么宽容了。此外,如果查询拉回太多结果,它可能会耗尽协调器节点上的所有可用堆内存,导致其崩溃。
这就是为什么基于主键运行查询是推荐的方法。因为只联系1、2个节点就可以返回结果,而不需要轮询所有节点。所以坚持使用你的主键。如果这对您的查询不起作用,则创建一个具有不同主键的新表,因为这在集群上会 A) 更快,B) 更容易。