返回:SQLite—系列文章目录
上一篇:SQLite数据库中JSON 函数和运算符(二十七)
下一篇:SQLite—系列文章目录
摘要
具有定义架构的 SQLite 数据库文件 通常是一种出色的应用程序文件格式。 以下是十几个原因:
- 简化的应用程序开发
- 单文件文档
- 高级查询语言
- 可访问内容
- 跨平台
- 原子事务
- 增量和持续更新
- 易于扩展
- 性能
- 多个进程并发使用
- 多种编程语言
- 更好的应用
下面将更详细地描述这些要点中的每一个, 在首先更仔细地考虑了 “应用程序文件格式”。另请参阅此的简短版本 白皮书。
什么是应用程序文件格式?
“应用程序文件格式”是文件格式 用于将应用程序状态保存到磁盘或交换 程序之间的信息。 目前有数以千计的应用程序文件格式在使用。 这里仅举几个例子:
- DOC - Word Perfect 和 Microsoft Office 文档
- DWG - AutoCAD 图形
- PDF - 来自 Adobe 的可移植文档格式
- XLS - Microsoft Excel 电子表格
- GIT - Git 源代码存储库
- EPUB - 非 Kindle 电子书使用的电子出版物格式
- ODT - OpenOffice 和其他用户使用的 Open Document 格式
- PPT - Microsoft PowerPoint 演示文稿
- ODP - OpenOffice 和其他机构使用的 Open Document 表示格式
我们区分了“文件格式”和“应用程序格式”。 文件格式用于存储单个对象。因此,例如,GIF 或 JPEG 文件存储单个图像,XHTML 文件存储文本, 所以这些是“文件格式”而不是“应用程序格式”。一个 EPUB 文件, 相反,存储文本和图像(包含 XHTML 和 GIF/JPEG 文件),因此它被认为是一种“应用程序格式”。这篇文章是 关于“应用程序格式”。
文件格式和应用程序格式之间的界限是模糊的。 本文将 JPEG 称为文件格式,但对于图像编辑器,JPEG 可能被视为应用程序格式。很大程度上取决于上下文。 对于本文,假设文件格式存储单个对象 应用程序格式存储许多不同的对象及其关系 彼此之间。
大多数应用程序格式都属于以下三类之一:
-
完全自定义格式。自定义格式专为单个应用程序而设计。 DOC、DWG、PDF、XLS 和 PPT 是自定义格式的示例。习惯 格式通常包含在单个文件中,以便于传输。 它们通常也是二进制的,尽管 DWG 格式是一个明显的例外。 自定义文件格式需要专用的应用程序代码 读写,通常无法从 可用的工具,例如 UNIX 命令行程序和文本编辑器。 换句话说,自定义格式通常是“不透明的 Blob”。 要访问自定义应用程序文件格式的内容,需要 专门设计用于读取和/或写入该格式的工具。
-
一堆文件格式。有时,应用程序状态存储为 文件。Git 就是一个典型的例子,尽管这种现象发生了 经常用于一次性和定制应用。一堆文件格式 实质上将文件系统用作键/值数据库,存储 将信息块放入单独的文件中。这给出了 使内容更易于通用实用程序访问的优点 文本编辑器或“AWK”或“GREP”等程序。但即使很多 以一堆文件格式的文件 易于阅读,通常有些文件具有 自己的自定义格式(例如:Git “Packfiles”),因此 不可读的“不透明 Blob” 或无需专用工具即可书写。它也不太方便 将一堆文件从一个地方或机器移动到另一个地方或机器,而不是 它是移动单个文件。而且很难制作一堆文件 例如,文档添加到电子邮件附件中。最后,一堆文件 格式打破了“文档隐喻”: 没有一个用户可以指向的文件 即“文件”。
-
包装的文件堆格式。某些应用程序使用一堆文件,然后将其封装到 某种单文件容器,通常是ZIP存档。 EPUB、ODT 和 ODP 是此方法的示例。 一本 EPUB 书实际上只是一个包含各种 书籍章节文本的 XHTML 文件,GIF 和 JPEG 图像的 艺术作品,以及讲述电子书的专用目录文件 阅读所有 XML 和图像文件如何组合在一起。OpenOffice办公室 文档(ODT 和 ODP)也是包含 XML 和 表示其内容的图像以及“目录”文件 显示组件之间的相互关系。
包装的一堆文件格式是完整文件之间的折衷 自定义文件格式和纯文件堆格式。 包装的文件堆格式不是相同意义上的不透明 blob 作为自定义格式,因为仍然可以访问组件 使用任何常见的ZIP存档器,但格式不太容易访问 作为纯粹的文件堆格式,因为仍然需要 ZIP archiver,并且通常不能使用命令行工具,例如“查找” 在文件层次结构上,而无需先解压缩它。另一方面 手,包装的一堆文件格式确实保留了文档 通过将所有内容放入单个磁盘文件中来隐喻。和 因为它是压缩的,所以包装的文件堆格式倾向于 更紧凑。
与自定义文件格式一样,与纯粹的文件堆格式不同, 包装的文件堆格式不那么容易编辑,因为 通常必须重写整个文件才能更改任何 组件。
本文件的目的是支持第四个 应用程序文件格式的新类别:SQLite 数据库文件。
SQLite作为应用程序文件格式
任何可以记录在一堆文件中的应用程序状态都可以 也可以记录在具有简单键/值架构的 SQLite 数据库中 喜欢这个:
CREATE TABLE files(filename TEXT PRIMARY KEY, content BLOB);
如果内容是压缩的,那么这样的SQLite Archive数据库的大小是相同的(±1%) 作为等效的ZIP存档,它具有优势 能够在不重写的情况下更新单个“文件” 整个文档。
但是SQLite数据库并不局限于简单的键/值结构 就像一堆文件数据库。一个SQLite数据库可以有几十个 或成百上千个不同的表,有几十个或 每个表有数百或数千个字段,每个字段都有不同的数据类型 和约束和特定含义,都相互交叉引用, 适当和自动索引以便快速检索, 并且所有这些都高效而紧凑地存储在单个磁盘文件中。 所有这些结构都被简洁地记录在人类身上 通过 SQL 架构。
换句话说,SQLite数据库可以做所有事情。 一堆文件或包装的一堆文件格式可以做,还有更多, 并且更加清晰。 SQLite 数据库是一个比键/值更通用的容器 文件系统或 ZIP 存档。(有关详细示例,请参阅 OpenOffice 案例研究文章。
从理论上讲,SQLite数据库的强大功能可以使用以下方法实现 自定义文件格式。但是任何具有表现力的自定义文件格式 作为关系数据库,可能需要大量的设计规范 以及数万或数十万行代码 实现。最终结果将是一个“不透明的斑点”,即 没有专门的工具就无法访问。
因此,与其他方法相比,使用 作为应用程序文件格式的 SQLite 数据库具有 令人信服的优势。以下是其中的一些优点, 列举和阐述:
-
简化的应用程序开发。读取或写入应用程序文件不需要新代码。 只需链接到 SQLite 库,或者将单个“sqlite3.c”源文件与其余部分一起包含 应用程序 C 代码,SQLite 将负责所有应用程序 文件 I/O。这可以将应用程序代码大小减少数千个 生产线,相应节省开发和维护成本。
SQLite是世界上使用最多的软件库之一。 从字面上看,有数百亿个SQLite数据库文件正在使用中 每天,在智能手机和小工具以及桌面应用程序中。 SQLite经过仔细测试并被证明是可靠的。事实并非如此 需要大量调整或调试的组件,允许开发人员 专注于应用程序逻辑。
-
单文件文档。SQLite数据库包含在单个文件中,这很容易 复制、移动或附加。“文档”的隐喻被保留了下来。
SQLite没有任何文件命名要求 因此,应用程序可以使用它想要的任何自定义文件后缀 以帮助将文件标识为“属于”应用程序。 SQLite 数据库文件包含一个 4 字节的应用程序 ID 可设置为应用程序定义值的标头 然后用于识别实用程序的文档的“类型” file(1)等程序,进一步 增强文档隐喻。
-
高级查询语言。SQLite 是一个完整的关系数据库引擎,这意味着 应用程序可以使用高级查询访问内容。应用 开发人员无需花时间思考“如何”检索 他们需要从文档中获得的信息。开发人员编写的 SQL 表达他们想要的“什么”信息,并让数据库引擎 以弄清楚如何最好地检索该内容。这有助于开发人员 操作“抬头”并专注于解决用户的问题, 并避免花时间“低头”摆弄低级文件 格式设置详细信息。
一堆文件格式可以看作是键/值数据库。 有键/值数据库总比没有数据库好。 但是没有事务或索引或高级查询语言或 一个适当的模式, 使用键/值数据库比使用键/值数据库要困难得多,也更容易出错 关系数据库。
-
可访问的内容。SQLite 数据库文件中保存的信息可使用 常用的开源命令行工具 - 用于 默认情况下安装在 Mac 和 Linux 系统上,并且 在Windows上免费作为独立的EXE文件提供。 与自定义文件格式不同,特定于应用程序的程序是 不需要读取或写入 SQLite 数据库中的内容。 SQLite 数据库文件不是不透明的 Blob。这是真的 命令行工具,如文本编辑器或“grep”或“awk”是 对 SQLite 数据库没有用,但 SQL 查询语言非常 更强大、更方便的方式来检查内容,因此 无法使用“grep”和“awk”等不被视为损失。
SQLite数据库是一种定义明确且有据可查的文件格式,被数以百万计的应用程序广泛使用 并且向后兼容其 2004 年成立,并承诺 在未来几十年继续兼容。长寿 SQLite数据库文件对于定制应用程序尤为重要, 因为它允许在 未来,在原始应用程序的所有痕迹都丢失很久之后。 数据的寿命比代码长。 美国国会图书馆推荐将 SQLite 数据库作为长期保存数字内容的存储格式。
-
跨平台。SQLite 数据库文件可在 32 位和 64 位计算机之间移植,并且 在 big-endian 和 little-endian 架构之间,以及 各种风格的 Windows 和类 Unix 操作系统。 使用SQLite应用程序文件格式的应用程序可以存储 二进制数值数据,无需担心 整数或浮点数。 文本内容可以读取或写入 UTF-8、UTF-16LE 或 UTF-16BE 和 SQLite将自动即时执行任何必要的翻译。
-
原子事务。对 SQLite 数据库的写入是原子的。 它们要么完全发生 或者根本没有,即使在系统崩溃或电源故障期间也是如此。所以 不存在仅仅因为权力发生而损坏文档的危险 在将更改写入磁盘的同一时刻退出。
SQLite是事务性的,这意味着可以对多个更改进行分组 一起,使它们全部发生或不发生,并且 如果在提交之前发现问题,则可以回滚更改。 这允许应用程序以增量方式进行更改,然后运行 在以下操作之前对生成的数据进行各种健全性和一致性检查 将更改提交到磁盘。Fossil DVCS 使用此技术来验证在每次更改之前没有丢失存储库历史记录。
-
增量和持续更新。写入 SQLite 数据库文件时,只有文件的那些部分 实际上,更改已写入磁盘。这使得写作发生得更快 并节省 SSD 的磨损。与定制相比,这是一个巨大的优势 和包装的文件堆格式,这两种格式通常都需要 重写整个文档以更改单个字节。 纯文件堆格式也可以 在某种程度上进行增量更新,尽管写入的粒度是 通常使用一堆文件格式(单个文件)比使用 SQLite 更大 (单页)。
SQLite还支持持续更新。 而不是在内存中收集更改然后写入 它们仅在文件/保存操作时将其写回磁盘,更改可以写回 磁盘发生时。这样可以避免因系统崩溃或 电源故障。自动撤消/重做堆栈,使用触发器进行管理, 可以保留在磁盘数据库中,这意味着可以进行撤消/重做 跨会话边界。
-
易于扩展。随着应用程序的增长,可以向 只需将新表添加到架构即可实现 SQLite 应用程序文件格式 或者通过向现有表添加新列。添加列或表 不会改变先前查询的含义,因此使用 一点点的注意,以确保遗留列和 保留表,保持向后兼容性。
当然,也可以扩展自定义或一堆文件格式, 但做起来往往要困难得多。如果添加了索引,则所有应用程序 必须找到更改相应表的代码并将其修改为 使这些指数保持最新状态。如果添加了列,则所有应用程序 访问相应表的代码必须找到并修改为 考虑新列。
-
性能。在许多情况下,SQLite 应用程序文件格式将比一堆文件格式更快或 自定义格式。除了原始读取速度更快之外,还 写道,SQLite通常可以显着缩短启动时间,因为 而不必 读取整个文档并将其解析到内存中,应用程序可以 执行查询以仅提取初始屏幕所需的信息。 随着应用程序的进展,它只需要加载尽可能多的材料 需要绘制下一个屏幕,并且可以丢弃来自 不再使用的先前屏幕。这有助于保留记忆 受控应用程序的占用空间。
一堆文件格式可以像 SQLite 一样以增量方式读取。 但是许多开发人员惊讶地发现 SQLite 可以读取和 从其数据库中写入较小的 BLOB(大小小于 100KB) 比这些相同的 blob 可以作为单独的文件读取或写入更快 从文件系统。(有关详细信息,请参阅比文件系统快 35% 和内部与外部 BLOB。 操作关系相关的开销 数据库引擎,但是不应假设直接文件 I/O 比 SQLite 数据库 I/O 快,但通常不是。
在任何一种情况下,如果 SQLite 应用程序中确实出现性能问题 这些问题通常可以通过向架构中添加一个或两个 CREATE INDEX 语句或运行一次 ANALYZE 来解决 并且无需触摸任何一行 应用程序代码。但是,如果在自定义或 一堆文件格式,修复通常需要大量更改 添加到应用程序代码以添加和维护新索引或提取 使用不同算法的信息。
-
多个进程并发使用。SQLite自动协调对同一的并发访问 来自多个线程和/或进程的文档。两个或更多 应用程序可以在 同时。写入是序列化的,但仅作为正常写入 只需几毫秒,应用程序只需轮流编写即可。 SQLite 自动确保 文档未损坏。使用自定义完成相同的操作 相比之下,堆文件格式需要广泛的支持 在应用程序中。以及支持所需的应用程序逻辑 并发是一个臭名昭著的错误磁铁。
-
多种编程语言。尽管 SQLite 本身是用 ANSI-C 编写的,但接口存在 几乎所有你能想到的编程语言: C++, C#, Objective-C, Java, Tcl, Perl, Python, Ruby, Erlang, JavaScript 等。因此,程序员可以在任何方面进行开发 他们最熟悉的语言以及最匹配的语言 项目的需求。
SQLite应用程序文件格式很棒 在存在集合或“联合”的情况下进行选择 单独的程序,通常用不同的语言编写,并由 不同的开发团队。 这通常出现在研究或实验室中 一个团队负责数据采集的环境 其他团队负责各个阶段的分析。 每个团队都可以使用任何硬件、操作系统、 编程语言和开发方法 最舒服,只要所有程序都使用 SQLite 数据库具有通用模式,它们都可以互操作。
-
更好的应用程序。如果应用程序文件格式是 SQLite 数据库,则完整的 该文件格式的文档由数据库模式、 也许还有几句关于每个表和列的额外内容 代表。自定义文件格式的描述, 另一方面,通常运行数百个 页面。一堆文件格式,虽然更简单、更容易 描述比完全自定义的格式,仍然趋向于大得多 并且比 SQL 模式转储更复杂,因为名称和格式 对于仍必须描述单个文件。
这不是一个微不足道的问题。清晰、简洁、易懂 文件格式是任何应用程序设计的关键部分。 弗雷德·布鲁克斯(Fred Brooks)在他有史以来最畅销的计算机科学著作《神话般的人月》(The Mythical Man-Month)中说:
表示是 计算机编程的本质。
......
给我看你的流程图,把你的表格藏起来,我会的 继续被迷惑。给我看看你的桌子,我通常不会 需要你的流程图;它们将是显而易见的。Rob Pike在他的《编程规则》中表达了同样的想法:
数据占主导地位。如果您选择了正确的数据结构 并且组织得很好,算法几乎总是会 不言而喻。数据结构,而不是算法,是核心 到编程。
莱纳斯·托瓦兹(Linus Torvalds)用不同的词说 在 2006 年 6 月 27 日的 Git 邮件列表上也差不多:
糟糕的程序员担心代码。优秀的程序员担心 关于数据结构及其关系。
关键是:SQL 数据库架构几乎总是如此 更好地定义和组织表格和 数据结构及其关系。 并具有清晰、简洁和明确的表示形式 几乎总是导致应用程序性能更好, 问题较少,更易于开发和维护。
结论
SQLite并不是适用于每种情况的完美应用程序文件格式。 但在许多情况下,SQLite 是比任何一个自定义都更好的选择 文件格式、一堆文件或一堆包装的文件。 SQLite是一款高级、稳定、可靠、跨平台、广泛部署、 可扩展、高性能、可访问、并发的文件格式。它应得的 您考虑作为下一个应用程序的标准文件格式 设计。