Cassandra 查询语言 (CQL):插入、更新和删除
⚡ 智能摘要
Cassandra 查询语言 (Query Language) 处理插入、更新、删除和读取操作,其语法与 SQL 类似,但底层语义不同。本页将介绍每种语句、合并了插入和更新的 upsert 行为,以及 WHERE 子句的真正局限性。

插入资料
此 Cassandra 插入语句将数据写入 Cassandra 行形式的列。 Cassandra 插入查询将仅存储用户指定的列。您必须仅指定主键列。
未指定值时不会占用任何空间。插入后不返回任何结果。
句法
INSERT INTO KeyspaceName.TableName (ColumnName1, ColumnName2, ColumnName3) VALUES (Column1Value, Column2Value, Column3Value);
例如:
这是执行的快照 Cassandra 插入表查询将在表中插入一条记录 Cassandra 表‘学生’。
INSERT INTO University.Student (RollNo, Name, dept, Semester) VALUES (2, 'Michael', 'CS', 2);
成功执行命令后插入 Cassandra,将在 Cassandra 表格学生学号为 2、姓名为 Michael、部门为 CS、学期为 2。
这是当前数据库状态的快照。
更新插入数据
Cassandra 执行 upsert。Upsert 意味着 Cassandra 如果主键不存在,则插入一行,否则,如果主键已经存在,则更新该行。
这会带来一个值得明确说明的实际后果:INSERT 语句永远不会报告重复键错误,因此意外的重复插入操作会在没有任何警告的情况下覆盖现有行。当必须避免这种情况时,可以在语句后添加 IF NOT EXISTS 语句,使其成为一个轻量级事务。
INSERT INTO University.Student (RollNo, Name) VALUES (2, 'Michael') IF NOT EXISTS;
轻量级事务使用跨副本的共识轮,因此比普通写入慢得多,应该保留给真正需要检查的情况。
更新资料
此 Cassandra 更新查询用于更新 Cassandra 表。如果更新数据后没有返回结果,则表示数据更新成功,否则将返回错误。列值在'Set'子句中更改,而数据则通过'Where'子句进行过滤。
句法
UPDATE KeyspaceName.TableName SET ColumnName1 = NewValue1, ColumnName2 = NewValue2 WHERE ColumnName = ColumnValue;
例如:
这是显示更新数据之前数据库状态的屏幕截图。
这是执行的快照 Cassandra 更新命令,更新学生表中的记录。
UPDATE University.Student SET name = 'Hayden' WHERE rollno = 1;
成功执行更新查询后 Cassandra “更新学生”,学生姓名将从“Clark”更改为“Hayden”,学号为 1。
以下是显示更新数据后的数据库状态的屏幕截图。
由于 upsert 行为,对不存在的主键执行 UPDATE 操作时,系统会创建该行而不是失败。
Cassandra 删除资料
命令“Delete”会从 Student 表中删除整行或部分列。删除数据时,不会立即从表中删除。而是用墓碑标记已删除的数据,并在压缩后删除。
句法
DELETE FROM KeyspaceName.TableName WHERE ColumnName1 = ColumnValue;
以上 Cassandra 删除行语法将根据 where 子句中的数据过滤删除一行或多行。
DELETE ColumnName1, ColumnName2 FROM KeyspaceName.TableName WHERE ColumnName1 = ColumnValue;
上述语法将从表中删除一些列。
例如:
这是显示删除数据之前当前数据库状态的快照。
这是从表 Student 中删除一行的命令的快照。
DELETE FROM University.Student WHERE rollno = 1;
成功执行 CQL 删除命令后,将从 Student 表中删除 rollno 值为 1 的一行。
这是显示删除数据后的数据库状态的快照。
墓碑标记会保留 gc_grace_seconds 秒,默认值为十天,这样,在删除操作期间离线的节点在恢复后就无法恢复该行。因此,删除大卷会留下标记,后续每次读取都必须扫描这些标记。
什么是 Cassandra 不支持
CQL 借用了 SQL 语法,但没有借用关系执行模型,因此一些熟悉的结构表现不同或缺失。
- CQL 不支持表之间的连接。相关数据必须在写入时反规范化到同一个表中。
- CQL 不支持 WHERE 子句中的 OR 条件。请使用 IN 语句处理单个列,或运行单独的查询。
- CQL 不支持 UNION 或 INTERSECT。
- 非主键列必须先建立索引才能进行筛选。
- 大于和小于比较仅适用于聚类列,因为只有这些列在磁盘上是排序的。
- 使用 LIKE 进行模式匹配需要 SASI 索引,并且不能用于普通列。
一个长期存在的说法需要纠正。聚合函数是受支持的: 计数、最小值、最大值、总和 AVG 到达 Cassandra 2.2和 通过...分组 3.10 版本已推出。需要注意的是适用范围而非可用性。
SELECT dept, COUNT(*) FROM University.Student WHERE RollNo = 1 GROUP BY dept;
如上所述,如果仅限于单个分区,聚合操作效率很高。但如果遍历整个表,则需要进行集群范围的扫描,这就是为什么…… Cassandra 仍然不适用于临时分析,这也是为什么繁重的报告工作通常会被推迟到其他场景。 Spark 或者外部仓库。
Cassandra 条款的地方
In Cassandra,数据检索是一个敏感问题。该列被过滤在 Cassandra 通过在非主键列上创建索引。
句法
SELECT ColumnNames FROM KeyspaceName.TableName WHERE ColumnName1 = Column1Value AND ColumnName2 = Column2Value;
例如:
- 下面是显示没有经过数据过滤的从学生表检索数据的快照。
SELECT * FROM University.Student;
从学生表中检索两条记录。
- 以下快照显示了通过数据过滤从 Student 检索数据的过程。检索到一条记录。
数据按名称列筛选。检索所有名称等于指定值的记录。 Guru99.
SELECT * FROM University.Student WHERE name = 'Guru99';
WHERE 子句可以引用哪些列的规则直接由主键决定。
- 此 分区键 必须完整提供该信息才能进行有效查询,因为它标识了保存数据的节点。
- Cluster列 之后可能会受到限制,但只能按照宣布的顺序进行限制。ping 其中一个被拒绝。
- 只允许对最后引用的聚类列进行范围比较,不允许对更早的聚类列进行范围比较。
- 任何 其他栏 需要一个辅助索引,这部分内容将在……中介绍。 创建和删除索引 教程。
当查询被拒绝时, Cassandra 通常建议添加 ALLOW FILTERING。请将其视为警告而非修复方案:它会扫描每个节点上的每个分区,而更改模式几乎总是正确的应对措施。










