讲师中心 微信公众号
AI工具推荐 视频效率加速

SQLDelight 中高效插入大型二进制数据(BLOB)的最佳实践

风静君_8150

风静君_8150

发布时间:2026-10-29 09:31:35

|

678人浏览过

|

来源于php中文网

原创

SQLDelight 中高效插入大型二进制数据(BLOB)的最佳实践

本文详解如何在 sqldelight 中避免内存溢出,安全高效地插入 gb 级 blob 数据,涵盖流式写入、分块处理与底层驱动适配等关键方案。

本文详解如何在 sqldelight 中避免内存溢出,安全高效地插入 gb 级 blob 数据,涵盖流式写入、分块处理与底层驱动适配等关键方案。

在使用 SQLDelight 处理大型二进制数据(如视频、模型文件或高清图像)时,直接将整个文件读入 ByteArray(例如 ByteArray(2 * 1024 * 1024 * 1024) 表示 2GB)极易触发 OutOfMemoryError,尤其在 Android 或资源受限的 Kotlin Multiplatform 环境中。SQLDelight 本身不原生支持 JDBC 风格的 setBlob(int, InputStream) 流式绑定,其生成的 insert() 方法仅接受 ByteArray 或 ByteBuffer —— 这意味着必须谨慎设计数据加载策略。

✅ 推荐方案:流式加载 + 分块缓冲(兼顾内存与性能)

若目标数据库驱动(如 SQLite via SQLiter、PostgreSQL via Ktor-Exposed 兼容层)支持 PreparedStatement.setBlob() 或 setBinaryStream(),可通过绕过 SQLDelight 自动生成的插入逻辑,直接调用底层 JDBC/SQLite API 实现零拷贝流写入:

// 假设使用 SQLiter(Android/iOS SQLite 封装)
val driver = SqliteDriver(...)
val database = Database(driver)
val file = File("large-video.mp4")

// 手动获取连接并执行流式插入(需启用 WAL 模式提升大写入性能)
driver.connection.use { conn ->
    val stmt = conn.prepareStatement("INSERT INTO MyTable (myBlob) VALUES (?)")
    file.inputStream().use { inputStream ->
        stmt.setBlob(1, inputStream) // ✅ 直接绑定 InputStream,不加载全量到内存
    }
    stmt.executeUpdate()
}

⚠️ 注意:此方式需确保所用驱动(如 sqliter ≥ 3.0 或 exposed + JDBC)实际支持 setBlob(InputStream)。SQLDelight 的 Database 抽象层不暴露该能力,因此需通过 driver.connection 访问原生连接。

炫酷的jQuery二进制数字时钟
炫酷的jQuery二进制数字时钟

炫酷的jQuery二进制数字时钟,它的时分秒都是用二进制来表示,绿色表示该位值是1,灰色则表示0,原理是将时钟的时分秒分别实时转换成二进制,然后随着本地时间的更新而实时刷新

下载

? 替代方案:分块读取 + ByteBuffer 流式构造

若必须使用 SQLDelight 的类型安全查询(如需事务一致性或复杂关联),可采用内存友好的分块读取 + ByteBuffer.allocateDirect():

fun readFileAsDirectByteBuffer(file: File): ByteBuffer {
    val channel = file.inputStream().channel
    val buffer = ByteBuffer.allocateDirect(file.length().toInt()) // 使用堆外内存
    channel.read(buffer)
    buffer.flip()
    return buffer
}

// 插入时传入 ByteBuffer(SQLDelight 支持 ByteBuffer → BLOB 映射)
val buffer = readFileAsDirectByteBuffer(file)
queries.insert(MyTable(buffer)) // MyTable 构造器需接受 ByteBuffer

? 提示:ByteBuffer.allocateDirect() 将内存分配在 JVM 堆外,减轻 GC 压力;但需手动管理(Kotlin 中 use 不适用,建议配合 Cleaner 或明确释放)。

❌ 应避免的做法

  • File.readBytes() 或 FileInputStream.readAllBytes():强制加载整个文件到堆内存,对 GB 级文件必然崩溃。
  • 无限制的 ByteArray(size) 预分配:即使未填充数据,JVM 仍会保留连续内存页,易导致 OutOfMemoryError 或 Native OOM(Android)。
  • 忽略数据库配置:SQLite 默认页大小(1KB)和缓存(PRAGMA cache_size)对大 BLOB 写入性能影响显著,建议优化:
    PRAGMA journal_mode = WAL;
    PRAGMA synchronous = NORMAL;
    PRAGMA cache_size = 10000; -- 增加缓存页数

✅ 总结:按场景选择策略

场景 推荐方式 关键优势
最大兼容性 & 最低内存占用 绕过 SQLDelight,直连底层驱动调用 setBlob(InputStream) 零堆内存拷贝,支持任意大小文件
需强类型安全 & 事务控制 分块读取 + ByteBuffer.allocateDirect() + SQLDelight 查询 保持 SQLDelight 工具链,减少堆内存压力
小文件( File.readBytes() + ByteArray 直传 简单直接,开发效率高

最终,SQLDelight 是类型安全的查询生成器,而非底层 I/O 框架。面对超大 BLOB,应主动“降级”到驱动层完成流式操作,并在业务逻辑中封装为清晰的 Repository 方法,既保障可靠性,又不失工程严谨性。

热门AI工具

更多
创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

4603

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

951

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

1209

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

6581

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

3323

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

6540

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

9001

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

1230

2024.04.29

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

40

2026.10.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 新特性与架构变化
Conan 2 新特性与架构变化

共0课时 | 0人学习

Conan DevOps 文档
Conan DevOps 文档

共0课时 | 0人学习

Conan Center 使用指南
Conan Center 使用指南

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn