SQLite分片存储超大单行数据技巧

SQLite是一个轻量级数据库,无法在数据表中存储数据量过大的单行数据。SQLite 在 Android 上单行默认最大大概是 2MB 左右(CursorWindow 限制),超出限制会报错:Row too big to fit into CursorWindow。

所以如果我们有存储大量数据的需求时,可以采用文件存储或者选择更换数据库。而使用SQLite也有相应的解决办法,就是分片存储。本文则简述如何使用SQLite分片存储数据。

一、存储原理与思路

分片存储就是把内容切成多段存多行,再拼接。

本文以存储List<double> curveData为例,讲述如何分片存储该数据。

思路就是给curveData单独建一个表,使用外键关联,每个片段存一条记录,同时存一个分片序号(beanId),方便查询时再拼接回来。

二、存储示例

1)DataBean数据结构代码如下:

class DataBean {
  int? id;
  int? timestamp;
  List<double>? curveData;

  DataBean({
    this.id,
    this.timestamp,
    this.curveData,
  });

  DataBean.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    timestamp= json['timestamp'];
    // curveData 不存 JSON,单独存表
  }

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'timestamp': timestamp,
      // curveData 不存 JSON,单独存表
    };
  }
}

2)因为要给给curveData单独建一个表

@startuml 'actor User participant "LocalRecordManager" as LocalRecordManager participant "IPCMediaPlayer" as MediaPlayer ' participant "PlayerEngine" as Engine participant "DataSource" as DataSource participant "Demux&Mux" as MuxDemux participant "DataOut" as DataOut ' participant "UI" as UI 'database SQLite activate LocalRecordManager #LightBlue LocalRecordManager -> LocalRecordManager: 读取配置信息,初始化剩余时长 = 总时长 LocalRecordManager -> MediaPlayer: 准备录制 activate MediaPlayer #LightBlue MediaPlayer -> DataOut: 创建录像文件夹 activate DataOut #LightBlue DataOut -> DataOut: 录像文件夹是否存在 alt 录像文件夹不存在 DataOut -> DataOut: 创建录像文件夹 else 录像文件夹存在 DataOut -> DataOut: 判断录像文件夹剩余空间是否低于预警阈值 alt 录像文件夹剩余空间低于预警阈值 DataOut -> MediaPlayer: 通知UI提醒用户及时清理录像文件夹 MediaPlayer --> DataOut: 返回 end end DataOut --> MediaPlayer: 创建成功 deactivate DataOut MediaPlayer -> DataSource: 根据码流类型发送拉流请求 activate DataSource #LightBlue alt 设备已拉取指定码流类型的数据流 DataSource -> DataSource: 复用流数据 else 设备未被拉流或拉取了其他码流类型的数据流 DataSource -> DataSource: 为该设备启动拉流 end DataSource --> MediaPlayer: 拉流成功 deactivate DataSource MediaPlayer -> LocalRecordManager: 准备录制完成 deactivate MediaPlayer loop 当剩余时间大于零 LocalRecordManager -> LocalRecordManager: 当前片段时长=min(单文件时长, 剩余时长) LocalRecordManager -> LocalRecordManager : 启动定时器(当前片段时长) LocalRecordManager -> MediaPlayer: 开始录制 'IPCMediaPlayer录制操作 activate MediaPlayer #LightBlue loop 持续录制 MediaPlayer -> MuxDemux: 先对TS流数据解复用, 再复用为MP4流数据 activate MuxDemux #LightBlue MuxDemux -> DataOut: 将MP4数据写入文件 deactivate MuxDemux activate DataOut #LightBlue DataOut -> DataOut: 将MP4数据写入到硬盘文件 alt 录像文件夹容量达到用户设置上限 DataOut -> DataOut: 删除最老的录像文件,释放30%的空间 end DataOut --> MediaPlayer: 写入成功 deactivate DataOut alt 用户手动关闭本地录制 LocalRecordManager -> LocalRecordManager : 终止定时器 LocalRecordManager -> MediaPlayer: 停止录制 '操作, 省略,见录制停止流程。 deactivate MediaPlayer end alt end loop LocalRecordManager -> LocalRecordManager : 定时器超时 LocalRecordManager -> MediaPlayer: 进行分片 activate MediaPlayer #LightBlue MediaPlayer -> DataOut: 进行分片 activate DataOut #LightBlue DataOut -> DataOut: 保存录像文件 DataOut --> MediaPlayer: 保存录像文件成功 deactivate DataOut MediaPlayer -> LocalRecordManager: 保存分片录制文件成功 deactivate MediaPlayer LocalRecordManager -> LocalRecordManager : 剩余时长 = 剩余时长 - 当前片段时长 end loop LocalRecordManager -> MediaPlayer: 定时时间到, 停止录制 '操作, 省略,见录制停止流程。 LocalRecordManager -> LocalRecordManager: 定时录制完成 ' deactivate LocalRecordManager @enduml 我想在注释省略的地方,将省略文字展示在uml时序图上,怎么写?语法是什么?
最新发布
09-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HQL_seven

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值