-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Swift 数据压缩
用户使用应用的时间越多,其相关的数据库一般也越大。过大的数据库不仅会占用磁盘空间,而且还会给数据备份和读写等操作带来性能压力。终端数据库的内容中,占用空间大的主要是各种xml、json之类的序列化内容。我们在实际的业务场景中,一个xml长达10k的情况比比皆是。
解决数据库内容过大的直接方法,就是先将数据压缩一下再写入数据库,这样开发者就需要解决下面三个问题:
- 选择一个合适的压缩算法。
- 在所有读写环节都需要引入数据的加解压逻辑。
- 压缩存量数据。
为了解决上面提到的数据压缩时会遇到的共性问题,WCDB引入了数据压缩能力。开发者可以使用简单的配置就可以实现数据压缩了。
首先 WCDB 使用的压缩组件是 Zstd,Zstd采用的压缩算法是[ANS+FSE][]算法,是现在已知压缩率和加解压性能综合最优的算法,而且Zstd还实现了字典压缩模式,可以更好得压缩xml或json中公共标签这部分内容,进一步提高压缩率和性能。WCDB把Zstd的普通压缩和字段压缩都支持了,还支持根据某个字段的不同值使用不同的字典来压缩。下面是不同模式的配置示例:
database.setCompression { info in
// 数据库中的每个表都会回调,先判断表名
if info.tableName != "sampleTable" {
return
}
// 1. 使用Zstd的默认压缩方式来压缩表中的 content 字段
info.addZSTDNormalCompress(to: Sample.Properties.description)
// 2. 配置使用注册的字典来压缩 description 字段
// 字典需要使用 Database.trainDict(with:and:) 方法来训练,并使用 Database.register(dict:with:) 方法来提前注册
info.addZSTDDictCompress(to: Sample.Properties.description, withDict: dictId)
// 3. 配置使用多种字典来压缩 description 字段
// 其中 identifier 字段为 0 时使用 dictId1 对应的字典,为 1 时使用 dictId2,其他情况使用 dictId3。
info.addZSTDMultiDictCompress(to: Sample.Properties.description, withMatchProperty: Sample.Properties.identifier, andDicts: [
0: dictId1,
1: dictId2,
Database.DictDefaultMatchValue, dictId3
])
}
配置好之后,开发就不用关注数据加解压的实现细节了,可以照常使用这些配置了压缩的表。WCDB会自动把新写入的数据按照配置的压缩方式来压缩,读数据的时候也会自动把数据解压了之后在给出来,对原有的读写逻辑无侵入。
如果 WCDB 是通过 Swift Package Manager 或者 Cocoapod 安装的,开发者还需要在编译 WCDB 时配置
WCDB_ZSTD=1
,并且在项目中编译链接 Zstd,才能正常使用数据压缩能力。
对于存量数据,开发者如果也要压缩,可以使用Database.enableAutoCompression(_:)
方法来开启 WCDB 自动压缩逻辑逻辑。WCDB 会每隔 2 秒压缩 100 条存量数据,而且这个处理通过锁监控机制,会避免影响到数据库的写性能。开发者也可以使用Database.stepCompression()
方法手动压缩存量数据,自己控制数据压缩的节奏。可以使用Database.setNotificationWhenCompressed(_:)
方法注册压缩进度的监听,每次迁移完一个存量表格都会回调。下面是压缩过程的使用示例:
assert(!database.isCompressed())
var compressedTable: String = ""
database.setNotificationWhenCompressed { database, table in
if let table = table, !table.isEmpty {
compressedTable = table
}
}
while(!database.isCompressed()){
try database.stepCompression()
}
assert(compressedTable == "sampleTable")
同时,数据压缩可以和数据迁移可以一起配置到同一个表的,两个操作将会独立生效,互不干扰,可以实现一边迁表或拆表,一边压缩目标表的效果,这些复杂玩法就交给开发者去探索了。
- 欢迎使用 WCDB
- 基础教程
- 进阶教程
- 欢迎使用 WCDB
- 基础教程
- 进阶教程
- 欢迎使用 WCDB
- 基础教程
- 进阶教程
- 欢迎使用 WCDB
- 基础教程
- 进阶教程