删除数据 #

一、DELETE概述 #

1.1 DELETE特点 #

Cassandra的DELETE语句有以下特点:

text
DELETE特点:

✓ 创建墓碑而非立即删除
✓ 支持条件删除
✓ 支持范围删除
✓ 支持删除特定列
✓ 支持删除集合元素

1.2 基本语法 #

sql
DELETE [column_name [, ...]]
FROM [keyspace_name.]table_name
[USING TIMESTAMP timestamp]
WHERE condition
[IF condition | IF EXISTS];

二、基本删除 #

2.1 删除整行 #

sql
-- 删除整行
DELETE FROM users 
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;

-- 删除指定键空间的行
DELETE FROM my_app.users 
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;

2.2 删除特定列 #

sql
-- 删除单个列
DELETE email FROM users 
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;

-- 删除多个列
DELETE email, phone, address FROM users 
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;

2.3 WHERE条件 #

sql
-- 必须指定完整主键
DELETE FROM orders 
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000 
AND order_id = 660e8400-e29b-41d4-a716-446655440001;

-- 范围删除(仅限聚簇列范围)
DELETE FROM events 
WHERE device_id = 'device-001'
AND event_time >= '2024-01-01'
AND event_time < '2024-02-01';

-- 删除整个分区
DELETE FROM events 
WHERE device_id = 'device-001';

三、墓碑机制 #

3.1 什么是墓碑 #

text
墓碑(Tombstone)机制:

删除操作
    │
    ▼
创建墓碑标记
    │
    ▼
数据仍存在但标记为删除
    │
    ▼
gc_grace_seconds后真正删除

墓碑作用:
├── 支持分布式删除
├── 保证最终一致性
└── 支持删除恢复

3.2 墓碑影响 #

text
墓碑对性能的影响:

读取
├── 需要过滤墓碑
├── 增加读取延迟
└── 消耗内存

压缩
├── 压缩时清理墓碑
└── 增加IO开销

修复
├── 修复时传播墓碑
└── 增加网络开销

3.3 墓碑配置 #

yaml
# cassandra.yaml

# 墓碑保留时间(秒)
gc_grace_seconds: 864000  # 10天

# 墓碑警告阈值
tombstone_warn_threshold: 1000

# 墓碑失败阈值
tombstone_failure_threshold: 100000

四、条件删除 #

4.1 IF EXISTS #

sql
-- 仅当记录存在时删除
DELETE FROM users 
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000
IF EXISTS;

-- 返回结果
-- [applied] | user_id
------------+--------------------------------------
--      True | 550e8400-e29b-41d4-a716-446655440000

4.2 IF条件 #

sql
-- 条件删除
DELETE FROM orders 
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000
AND order_id = 660e8400-e29b-41d4-a716-446655440001
IF status = 'pending';

-- 多条件删除
DELETE FROM products 
WHERE product_id = 770e8400-e29b-41d4-a716-446655440002
IF stock = 0 AND status = 'discontinued';

4.3 条件删除结果 #

sql
-- 条件删除返回结果
DELETE FROM users 
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000
IF name = '张三';

-- 成功
-- [applied] | name
------------+--------
--      True | 张三

-- 条件不满足
-- [applied] | name
------------+--------
--     False | 李四

五、范围删除 #

5.1 聚簇列范围删除 #

sql
-- 删除时间范围内的数据
DELETE FROM events 
WHERE device_id = 'device-001'
AND event_time >= '2024-01-01'
AND event_time <= '2024-01-31';

-- 删除ID范围内的数据
DELETE FROM orders 
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000
AND order_id > min_uuid
AND order_id < max_uuid;

5.2 分区删除 #

sql
-- 删除整个分区
DELETE FROM events 
WHERE device_id = 'device-001';

-- 删除特定日期分区
DELETE FROM sensor_data 
WHERE sensor_id = 'sensor-001'
AND date = '2024-01-01';

5.3 范围删除注意事项 #

text
范围删除注意事项:

✓ 仅支持聚簇列范围
✓ 必须指定分区键
✓ 创建范围墓碑

⚠ 范围删除创建单个范围墓碑
⚠ 比逐行删除更高效
⚠ 但仍需等待压缩清理

六、集合删除 #

6.1 删除整个集合 #

sql
-- 删除整个List
DELETE tags FROM users 
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;

-- 删除整个Set
DELETE emails FROM users 
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;

-- 删除整个Map
DELETE preferences FROM users 
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;

6.2 删除集合元素 #

sql
-- 删除List元素
UPDATE users 
SET tags = tags - ['old_tag']
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;

-- 删除Set元素
UPDATE users 
SET emails = emails - {'old@example.com'}
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;

-- 删除Map键
DELETE preferences['theme'] 
FROM users 
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;

七、时间戳删除 #

7.1 设置删除时间戳 #

sql
-- 设置时间戳删除
DELETE FROM users 
USING TIMESTAMP 1704067200000000
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000;

7.2 时间戳作用 #

text
删除时间戳作用:

冲突解决
├── 相同主键多次删除
├── 时间戳大的覆盖小的
└── 用于数据恢复

数据导入
├── 控制删除顺序
└── 数据迁移场景

调试分析
├── 追踪删除操作
└── 问题排查

八、批量删除 #

8.1 BATCH删除 #

sql
-- 批量删除
BEGIN BATCH
    DELETE FROM users WHERE user_id = uuid1;
    DELETE FROM users WHERE user_id = uuid2;
    DELETE FROM users WHERE user_id = uuid3;
APPLY BATCH;

-- 条件批量删除
BEGIN BATCH
    DELETE FROM orders 
    WHERE user_id = uuid1 AND order_id = order1
    IF status = 'cancelled';
    
    UPDATE user_stats 
    SET order_count = order_count - 1
    WHERE user_id = uuid1;
APPLY BATCH;

8.2 批量删除最佳实践 #

text
BATCH删除最佳实践:

推荐
├── 同一分区的删除
├── 需要原子性的操作
└── 少量操作(< 20条)

不推荐
├── 跨分区的大量删除
├── 纯粹为了批量删除
└── 大量数据清理

九、删除性能优化 #

9.1 删除策略 #

text
删除策略选择:

少量删除
├── 使用DELETE语句
└── 正常性能

大量删除
├── 使用TRUNCATE清空表
├── 使用范围删除
└── 考虑TTL自动过期

分区删除
├── 删除整个分区最高效
└── 创建单个范围墓碑

9.2 监控墓碑 #

bash
# 查看墓碑统计
nodetool cfstats my_app.users | grep -i tombstone

# 查看表统计
nodetool tablestats my_app.users

# 监控墓碑警告
grep "tombstone" /var/log/cassandra/system.log

9.3 减少墓碑影响 #

text
减少墓碑影响:

1. 使用TTL代替删除
   └── 数据自动过期

2. 批量删除代替逐行删除
   └── 减少墓碑数量

3. 调整gc_grace_seconds
   └── 加快墓碑清理

4. 定期压缩
   └── 手动触发压缩

5. 监控和告警
   └── 及时发现墓碑问题

十、常见问题 #

10.1 删除后数据仍存在 #

text
问题:删除后查询仍能看到数据

原因:
├── 复制延迟
├── 墓碑未传播
└── 一致性级别问题

解决:
├── 等待复制完成
├── 执行repair
└── 使用更高一致性级别

10.2 删除性能问题 #

text
问题:大量删除导致性能下降

原因:
├── 大量墓碑
├── 读取需要过滤墓碑
└── 压缩压力大

解决:
├── 使用TTL
├── 使用范围删除
├── 调整压缩策略
└── 监控墓碑数量

十一、总结 #

删除数据要点:

  1. 墓碑机制:删除创建墓碑而非立即删除
  2. 条件删除:使用IF条件保证原子性
  3. 范围删除:比逐行删除更高效
  4. 集合删除:支持删除整个集合或元素
  5. 性能影响:大量墓碑影响性能
  6. TTL替代:考虑使用TTL自动过期

下一步,让我们学习查询数据!

最后更新:2026-03-27