写点什么

SQLite 你用对了吗

用户头像
这小胖猫
关注
发布于: 2020 年 07 月 04 日
SQLite你用对了吗

何时选择 SQLite?


SQLite 没法直接和那些 C/S 模型的 SQL 数据库引擎相比,比如 MySQL、Oracle、PostgreSQL、 SQL Server 等等。因为 SQLite 在试图解决不同的问题。


C/S 模型的数据库致力于实现共享的企业仓库,强调扩展性、并发性、集中化与管理;而 SQLite 致力于为独立的应用程序和设备提供本地化数据存储,强调经济、高效、可靠、独立和简单。


SQLite 与 C/S 方式使用的数据库并不构成竞争,而关注的是那些使用 fopen()的场景和地方。


SQLite 可以适用的应用场景


  • 嵌入式设备和物联网


SQLite 数据库基本上不需要管理,在没有专家支持的设备上也能跑的很好。很适合用在手机、机顶盒、电视、游戏机、相机、手表、厨房电器、温控器、汽车、机床、飞机、传感器、无人机、医疗器械和机器人等等,以及物联网涵盖的所有设备。


C/S 模式的数据库的诞生,是为了建立网络核心地带中重要的数据中心。当然 SQLite 也可以应用在这里,不过 SQLite 在网络边缘地带也能工作的非常好,尤其是在为弱联网应用程序提供快速和可靠的数据服务时,表现的更为出色。


  • 应用程序文件格式


“应用程序文件格式”是用于将应用程序状态持久化到磁盘或在程序之间交换信息的文件格式。这篇文章详细介绍了这个概念:点击查看


SQLite 在桌面应用程序中,经常被用作一种磁盘存储的文件格式,比如按版本控制系统、金融分析工具、多媒体管理和编辑套件、计算机辅助设计工具包和记录本程序等等。之前那些文件打开的操作,你现在调用 sqlite3_open()就能关联到数据库文件上了。这样当程序中的内容变化时就会自动更新到文件里,菜单里边的"文件/保存"这个选项就再没什么用了。菜单里的“文件/另存为”选项可以用backup API来实现。


这种用法有很多好处,提升了操作性能、降低了成本和复杂度、改善了程序的可靠性等等。可以参考这几个技术手册,获得更多详情:"aff_short.html""appfileformat.html""fasterthanfs.html"。这个使用场景和下边要介绍的“数据传输格式”以及“数据容器”两个使用场景密切相关。


  • 网站


SQLite 作为数据库引擎,适用于大多数中低流量规模的网站(也就是绝大部分网站),SQLite 处理的网络流量,取决于网站访问数据库的业务量。一般来讲,日点击量在 10W 以下的网站,使用 SQLite 都没问题。10W 日点击率只是一个保守的估计值,并不是严格的上限值。SQLite 已经被证明了可以处理 10 倍这样的流量也没有问题。


当然,SQLite 的官方网站(https://www.sqlite.org/)也在使用 SQLite,在写本文时(2015 年),SQLite 网站上每日处理大约 40W-50W 的 HTTP 请求,其中 15%-20%的内容是动态页面。动态页面每个网页使用大约 200 个 SQL 语句。这些在一个 VM 上运行,该 VM 与其他 23 个 VM 共享一台物理机。就这样,大部分时候负载也保持在 0.1 以下。


  • 数据分析


会用 SQL 的人们可以使用 SQL 命令行工具(或者其他第三方 SQLite 访问工具)来处理分析大量的数据集。原始数据可以从 CSV 文件导入,然后把数据切片并生成大量的摘要报告。也可以使用基于 Tcl 或者 Python(SQLite 原生支持)写的脚本做更复杂的分析工作,也可以基于 R 语言或者其他方便适配的编程语言。也可以去做其他的事情,比如网站日志分析,体育报告,程序度量指标的汇总,实验报告的分析等等。很多生物信息研究人员都用这种方式使用 SQLite。


当然,企业级的 C/S 数据库也可以做这些事情。但 SQLite 更容易安装和使用,并且生成的数据库是一个单独的文件,可以 U 盘拷贝,也可以电子邮件发给同事。


  • 数据缓存


很多应用程序使用 SQLite 做缓存,暂存企业级关系型数据库中的相关内容。这样如果大部分查询都在本地缓存命中的话,就避免了网络上的往返过程,从而大大减少了延迟,也减少了网络和数据库服务器的负载。并且这就意味着,在很多场景下,即使网络中断了,客户端程序依然可以使用。


  • 服务端数据库


系统设计人员报道了 SQLite 在服务端程序上做数据存储的成功案例,也就是说,在服务器程序上使用 SQLite 作为底层存储引擎。


这种场景下,整个系统也是 C/S 模型:客户端发送请求到服务端,并通过网络接收响应。不过,并不是发送原生的 SQL 查询然后收到数据库表的原始数据这种模式,请求和响应包是由应用程序指定的更高级的自定义格式。服务端把收到的请求转化成多个 SQL 查询,并收集查询结果,然后处理、过滤和分析,把要返回的必要信息构造成一个自定义的更高级的响应包。


据开发者反馈,这种使用场景下,SQLite 经常比 CS 模型的数据库表现的更快。数据库请求被服务端程序做了串行化,所以也不会存在并发访问的问题了。可以基于“数据库分片”来做并发,也就是不同的业务使用不同的数据库文件。比如:服务端针对每个用户都使用一个独立的 SQLite 数据库,这样服务端就能同时处理成千上万个大量的同样的连接,不过这样也有个弊端:每个 SQLite 数据库只能被一个连接使用。


  • 数据传输格式


SQLite 数据库是一个单独的压缩文件,其内容是一种定义良好的跨平台的格式,他经常被用作两个系统之间交换数据的容器,发送方将数据放在 SQLite 文件里,然后把文件发给对方,接收方在使用 SQL 提取需要的数据。


SQLite 促进了不同系统之间的数据传输,即使两个系统有不一样的字大小或者不同的字节序,也都没有问题。数据可以是二进制块、文本或者数字等等不同类型的组合,数据格式也可以通过新建表或者增加列方便的进行扩展,传输方式不用有任何变化。使用 SQL 查询语言也就意味着接收方不用一次性解析整个传输内容,而是根据需要查询收到的数据。数据格式是透明的,人们使用各种常见的工具可以很容易的进行解码。


  • 文件存档(数据容器)


SQLite 的归档思想展示了如何使用 SQLite 作为 zip 和 tar 的替代品,存在 SQLite 中的文件归档之比对应的 zip 格式稍微大一点儿,有时实际会更小一些。并且 SQLite 归档具备增量和原子性更新的特点,能存储更加丰富的数据类型。


Fossil2.5 和更新版本提供 SQLite 的归档文件作为下载格式,除此之外也支持 zip 和 tar 格式。SQLite3.22 以上版本使用.archive 命令可以创建、列出和解包 SQL 存档。


SQLite 是一个很好的解决方案,适用于需要将各种内容捆绑到一个自包含的、自描述的包中以便通过网络进行传输的任何情况。内容以良好的定义形式编码到跨平台和稳定的文件格式中。这种编码非常高效,接收者可以提取内容中的一小部分子集,而不需要读取和解析整个文件。


如果你需要一种向大量客户端广播软件或新内容的分发格式,SQL 归档就非常有用。比如传输电视节目指南到机顶盒和发送更新到车辆导航系统。


  • 替代临时文件


许多程序使用 fopen()、fread()和 fwrite()来创建和管理本地格式的数据文件。SQLite 作为这些数据文件的替代品尤其好用。与直觉相反,SQLite 可以比文件系统更快地将内容读写到磁盘。


  • 内部或临时数据库


一些程序针对海量数据,存在各式各样的筛选和排序需求,如果使用 SQLite 数据库,可以方便和快速的把数据加载到内存里,然后使用带 join 和 order by 子句的查询按需要的格式和顺序解析出数据,不用再手动的做各种繁琐的操作得到你想要的结果。在内部使用 SQLite 数据库,可以让你的程序具备更好的灵活性,不用修改你的每个查询,你也可以新增不同列和索引。


  • 在 demo 或测试阶段,作为企业级数据库的替代品


客户端程序通常使用通用的数据库接口,接口可以连接到各种 SQL 数据库引擎。将 SQLite 包含在受支持的数据库中,并静态地将 SQLite 引擎链接到客户端,这是很有意义的。通过这种方式,客户端程序可以与 SQLite 数据文件一起单独使用,用于测试或演示。


  • 教育和培训


SQLite 的设置和使用都很简单,非常适合于 SQL 教学(安装很简单:只需把 sqlite3 或者 sqlite3.exe 可执行文件复制到目标机器,然后运行它就可以了。)。学生们可以很方便的创建很多他们想用的数据库,并用电子邮件发给讲师进行评分或者征求老师意见。对于有兴趣研究关系型数据库是如何实现的高年级学生来说,SQLite 的代码是个不错的参考,代码是结构化设计,注释清晰,文档齐全。


  • SQL 语言的实验性扩展


SQLite 的简单和模块化设计使其成为一个很好的平台,可以为实验性的数据库语言新特性快速构建原型。


C/S 的 RDBMS 更适合的一些情况


  • C/S 模型的程序 如果有大量的客户端程序通过网络同时向一个数据库发送 SQL 查询,那么请选择 C/S 的数据库而不是 SQLite。SQLite 也可以跑在网络文件系统上,但是大多数网络文件系统都存在延迟,性能不会很好。并且,在很多的网络文件系统实现上,文件锁的逻辑一般都有 bug,当出现 bug 时,如果两个以上的客户端同时尝试修改数据中的同一条数据,就可能导致数据损坏。这个问题是由底层文件系统实现中的 bug 导致的,所以 SQLite 也无可奈何。 一个最近原则就是避免多端需要直接访问同一个数据库(不需要介入应用程序服务器)的场景下使用 SQLite,可以考虑在网络上的每台计算机上同时使用 SQLite。

  • 大流量的网站


作为一个网站的后端数据库,SQLite 可以表现的很好。但是如果网站是写密集型的,或者负载很高,需要多台服务器,那么可以考虑使用企业级的 C/S 数据库引擎,而不是 SQLite。


  • 非常大的数据集


一个 SQLite 数据库的容量最多为 128TiB, 但即使可以处理这么大的数据量,SQLite 把整个数据库放在单个文件里,很多文件系统中单个文件的容量并没有这么多。如果你在考虑使用这样大数据规模的数据库的话,那就不用选 SQLite 了。最好虑使用 C/S 数据库引擎,这类引擎可以将数据库内容放到多个磁盘文件,甚至可能跨多个卷。


  • 高并发场景


SQLite 虽然不限制读连接的数量,但同一时刻只允许一个连接写数据。在很多场景下,这都没问题,因为写请求可以做排队。每个应用程序都快速地执行 SQL 查询并继续以后的处理,没有一个锁持续几十毫秒以上。但是有些应用程序需要更多的并发性,SQLite 可能就无法满足了。


  • 选择合适数据库的检查清单


  1. 数据需要通过网络与应用程序分离 → 选择 C/S 数据库


当数据位于独立于应用程序的设备上时,通常最好选择 C/S 数据库引擎。Nota Bene:在这个规则中,“应用程序”是指发出 SQL 语句的代码。如果“应用程序”是一个应用程序服务器,并且内容驻留在与应用程序服务器相同的物理机器上,那么 SQLite 可能仍然是合适的,即使最终用户是另一个网络用户。


  1. 存在大量的并发写 → 选择 C/S 数据库


如果许多线程或进程需要同时写数据库(不能排队写),那么最好选择 C/S 数据库引擎。SQLite 对于每个数据库文件一次只支持一个写入。但在大多数情况下,写事务只需要几毫秒,所以多个写可以轮流执行,用这种方式 SQLite 可以处理很多的并发写,虽然很多人都比较怀疑。然而,由于 C/S 数据库系统有一个长期运行的服务器进程来协调访问,因此它们通常可以处理比 SQLite 多得多的并发写。


  1. 数据量很大 → 选择 C/S 数据库


如果您的数据增长到让您感到不舒服或无法放入单个磁盘文件的大小,那么您应该选择 SQLite 以外的解决方案。SQLite 支持最大 128IiB 的数据库(前提是文件系统支持,磁盘够大)。即便如此,当数据容量可能会达到 TB 级时,最好考虑使用集中式客户机/服务器数据库。


  1. 其他情况 → 选择 SQLite!


如果写并发不多,数据容量少于 1tb,SQLite 几乎总是一个很好的选择。SQLite 是快速和可靠的,它不需要配置或维护。


点击查看E文原文https://www.sqlite.org/whentouse.html


更多互动和内容:加入作者私人小密圈,和作者更多互动,并获取更多成长路上的分享


发布于: 2020 年 07 月 04 日阅读数: 303
用户头像

这小胖猫

关注

可能是有思想的一只 2017.10.25 加入

程序员长工,服侍过两个东家,第一个4年从开发工程师做到主程,第二个4年从开发工程师做到部门研发总监,用谦虚、热情和创业的心态做事儿。常常做些编程、冥想、写东西和打球之类的事情,乐此不疲

评论

发布
暂无评论
SQLite你用对了吗