HBase删除数据 #

一、删除语法 #

1.1 delete语法 #

ruby
# 基本语法
delete '表名', '行键', '列族:列限定符'

# 示例
delete 'user', 'user001', 'info:age'

1.2 deleteall语法 #

ruby
# 基本语法
deleteall '表名', '行键'

# 示例
deleteall 'user', 'user001'

1.3 完整语法 #

ruby
# delete完整语法
delete '表名', '行键', '列族:列限定符', 时间戳

# deleteall完整语法
deleteall '表名', '行键', '列族:列限定符'

二、基本删除操作 #

2.1 删除指定列 #

ruby
# 删除指定列
delete 'user', 'user001', 'info:age'

# 删除后查询
get 'user', 'user001'
# info:age 列不再显示

2.2 删除指定版本 #

ruby
# 删除指定时间戳的版本
delete 'user', 'user001', 'info:name', 1704067200000

# 删除后查询
get 'user', 'user001', {COLUMN => 'info:name', VERSIONS => 3}
# 指定时间戳的版本被删除

2.3 删除整行 #

ruby
# 删除整行
deleteall 'user', 'user001'

# 删除后查询
get 'user', 'user001'
# 无结果

2.4 删除指定列族 #

ruby
# 删除指定列族的所有列
deleteall 'user', 'user001', 'info'

# 删除后查询
get 'user', 'user001'
# info列族的所有列被删除

2.5 删除命名空间中的表 #

ruby
# 删除命名空间中的表数据
delete 'myapp:user', 'user001', 'info:age'
deleteall 'myapp:user', 'user001'

三、删除机制详解 #

3.1 删除标记 #

text
┌─────────────────────────────────────────────────────────────────────┐
│                         删除标记机制                                  │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  HBase删除不是物理删除,而是写入删除标记:                           │
│                                                                     │
│  删除前:                                                           │
│  ┌───────────────────────────────────────────────────────────────┐ │
│  │  user001, info:name, ts=1704067200000, value=张三             │ │
│  │  user001, info:name, ts=1704067230000, value=张三丰           │ │
│  └───────────────────────────────────────────────────────────────┘ │
│                                                                     │
│  执行 delete 'user', 'user001', 'info:name', 1704067200000        │
│                                                                     │
│  删除后:                                                           │
│  ┌───────────────────────────────────────────────────────────────┐ │
│  │  user001, info:name, ts=1704067230000, value=张三丰           │ │
│  │  user001, info:name, ts=1704067200000, type=Delete            │ │
│  └───────────────────────────────────────────────────────────────┘ │
│                                                                     │
│  查询时:                                                           │
│  - 遇到删除标记,跳过该版本                                         │
│  - 返回未删除的版本                                                 │
│                                                                     │
│  Major Compaction时:                                               │
│  - 物理删除标记删除的数据                                           │
│  - 清理删除标记                                                     │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

3.2 删除标记类型 #

类型 说明 触发命令
Delete 删除单个版本 delete ‘t’, ‘r’, ‘c’, ts
DeleteColumn 删除所有版本 delete ‘t’, ‘r’, ‘c’
DeleteFamily 删除列族 deleteall ‘t’, ‘r’, ‘cf’
DeleteFamilyVersion 删除列族版本 特定场景

3.3 删除与版本 #

ruby
# 创建表,版本数为3
create 'user', {NAME => 'info', VERSIONS => 3}

# 插入多个版本
put 'user', 'user001', 'info:name', 'v1', 1704067200000
put 'user', 'user001', 'info:name', 'v2', 1704067230000
put 'user', 'user001', 'info:name', 'v3', 1704067260000

# 查询所有版本
get 'user', 'user001', {COLUMN => 'info:name', VERSIONS => 3}
# 返回:v1, v2, v3

# 删除中间版本
delete 'user', 'user001', 'info:name', 1704067230000

# 再次查询
get 'user', 'user001', {COLUMN => 'info:name', VERSIONS => 3}
# 返回:v1, v3(v2被删除)

四、条件删除 #

4.1 检查并删除 #

ruby
# 检查并删除
# 语法:checkAndDelete '表名', '行键', '列族:列', '期望值', Delete对象

# 示例:只有当age为25时才删除name
put 'user', 'user001', 'info:age', '25'
checkAndDelete 'user', 'user001', 'info:age', '25', 'info:name'

4.2 Java API条件删除 #

java
// 创建Delete对象
Delete delete = new Delete(Bytes.toBytes("user001"));
delete.addColumns(Bytes.toBytes("info"), Bytes.toBytes("name"));

// 检查并删除
boolean success = table.checkAndDelete(
    Bytes.toBytes("user001"),
    Bytes.toBytes("info"),
    Bytes.toBytes("age"),
    Bytes.toBytes("25"),
    delete
);

if (success) {
    System.out.println("Delete successful");
} else {
    System.out.println("Delete failed - condition not met");
}

五、TTL自动删除 #

5.1 设置TTL #

ruby
# 创建表时设置TTL(7天)
create 'log', {NAME => 'data', TTL => 604800}

# 修改TTL
alter 'log', {NAME => 'data', TTL => 2592000}  # 30天

5.2 TTL工作机制 #

text
TTL工作机制
├── 数据写入时记录时间戳
├── 查询时检查是否过期
├── 过期数据不返回
├── Major Compaction时物理删除
└── MIN_VERSIONS可设置保留的最小版本数

5.3 TTL与MIN_VERSIONS #

ruby
# 设置TTL和MIN_VERSIONS
alter 'log', {NAME => 'data', TTL => 604800, MIN_VERSIONS => 1}

# 即使数据过期,也保留至少1个版本

六、删除示例 #

6.1 删除用户信息 #

ruby
# 删除单个属性
delete 'user', 'user001', 'info:phone'

# 删除用户所有信息
deleteall 'user', 'user001'

# 删除用户历史记录列族
deleteall 'user', 'user001', 'history'

6.2 删除订单信息 #

ruby
# 删除订单状态
delete 'order', 'order001', 'detail:status'

# 删除整个订单
deleteall 'order', 'order001'

6.3 清理过期日志 #

ruby
# 使用TTL自动清理
create 'log', {NAME => 'data', TTL => 604800}

# 或手动删除旧数据
deleteall 'log', 'log_20230101'

七、Java API删除 #

7.1 删除指定列 #

java
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

public class DeleteExample {
    public static void main(String[] args) throws Exception {
        Connection connection = ConnectionFactory.createConnection();
        Table table = connection.getTable(TableName.valueOf("user"));
        
        // 创建Delete对象
        Delete delete = new Delete(Bytes.toBytes("user001"));
        
        // 删除指定列
        delete.addColumns(Bytes.toBytes("info"), Bytes.toBytes("name"));
        
        // 执行删除
        table.delete(delete);
        
        table.close();
        connection.close();
    }
}

7.2 删除指定版本 #

java
// 创建Delete对象
Delete delete = new Delete(Bytes.toBytes("user001"));

// 删除指定时间戳的版本
delete.addColumns(
    Bytes.toBytes("info"), 
    Bytes.toBytes("name"),
    1704067200000L
);

// 执行删除
table.delete(delete);

7.3 删除整行 #

java
// 创建Delete对象(不添加任何列,删除整行)
Delete delete = new Delete(Bytes.toBytes("user001"));

// 执行删除
table.delete(delete);

7.4 批量删除 #

java
// 创建多个Delete对象
List<Delete> deletes = new ArrayList<>();
deletes.add(new Delete(Bytes.toBytes("user001")));
deletes.add(new Delete(Bytes.toBytes("user002")));
deletes.add(new Delete(Bytes.toBytes("user003")));

// 批量删除
table.delete(deletes);

八、删除与Compaction #

8.1 Minor Compaction #

text
Minor Compaction
├── 合并部分StoreFile
├── 不清理删除标记
├── 不清理过期数据
└── 执行频率高

8.2 Major Compaction #

text
Major Compaction
├── 合并所有StoreFile
├── 清理删除标记
├── 物理删除标记删除的数据
├── 清理过期数据(TTL)
└── 执行频率低,资源消耗大

8.3 手动触发Major Compaction #

ruby
# 对表执行Major Compaction
major_compact 'user'

# 对Region执行Major Compaction
major_compact 'region_encoded_name'

九、常见问题 #

9.1 删除后数据仍存在 #

ruby
# 问题:删除后查询仍有数据
delete 'user', 'user001', 'info:name'
get 'user', 'user001', 'info:name'

# 原因:删除的是最新版本,还有旧版本
# 解决:删除所有版本或使用deleteall

# 查看所有版本
get 'user', 'user001', {COLUMN => 'info:name', VERSIONS => 10}

9.2 删除标记占用空间 #

ruby
# 问题:删除大量数据后,存储空间未释放
# 原因:删除标记占用空间
# 解决:执行Major Compaction

major_compact 'user'

9.3 删除性能问题 #

ruby
# 问题:大量删除操作慢
# 原因:每个删除都是写操作
# 解决:批量删除或使用TTL

# 批量删除
table.delete(deletes)

# 使用TTL自动清理
alter 'log', {NAME => 'data', TTL => 604800}

十、最佳实践 #

10.1 删除策略 #

text
删除策略建议
├── 使用TTL自动清理过期数据
├── 批量删除减少网络开销
├── 低峰期执行大量删除
└── 定期执行Major Compaction

10.2 性能优化 #

text
性能优化建议
├── 避免频繁删除同一行
├── 使用批量删除
├── 合理设置TTL
└── 控制Major Compaction频率

10.3 数据安全 #

text
数据安全建议
├── 删除前确认数据
├── 重要数据先备份
├── 使用条件删除保证一致性
└── 记录删除操作日志

十一、总结 #

本节介绍了HBase删除数据:

操作 语法
删除列 delete ‘表’, ‘row’, ‘cf:col’
删除版本 delete ‘表’, ‘row’, ‘cf:col’, ts
删除整行 deleteall ‘表’, ‘row’
删除列族 deleteall ‘表’, ‘row’, ‘cf’
条件删除 checkAndDelete
TTL删除 alter ‘表’,

下一步,让我们学习扫描数据!

最后更新:2026-03-27