SQLite的独特特性

来自泡泡学习笔记
BrainBs讨论 | 贡献2024年10月11日 (五) 17:30的版本 (创建页面,内容为“本页重点介绍SQLite的一些不同寻常的特性,这些特性使SQLite区别于许多其他SQL数据库引擎。 ===零配置=== 在使用SQLite之前不需要“安装”。没有“设置”过程。没有需要启动、停止或配置的服务器进程。管理员不需要创建新的数据库实例或为用户分配访问权限。SQLite不使用配置文件。不需要做任何事情来告诉系统SQLite正在运行。在系统崩溃或电源故…”)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航 跳到搜索

本页重点介绍SQLite的一些不同寻常的特性,这些特性使SQLite区别于许多其他SQL数据库引擎。

零配置

在使用SQLite之前不需要“安装”。没有“设置”过程。没有需要启动、停止或配置的服务器进程。管理员不需要创建新的数据库实例或为用户分配访问权限。SQLite不使用配置文件。不需要做任何事情来告诉系统SQLite正在运行。在系统崩溃或电源故障后恢复不需要任何操作。没有什么可排除的。 SQLite只是工作。

其他更熟悉的数据库引擎一旦启动就会运行得很好。但是进行初始安装和配置可能非常复杂。


Serverless

大多数SQL数据库引擎都是作为单独的服务器进程实现的。想要访问数据库的程序使用某种进程间通信(通常是TCP/IP)与服务器通信,向服务器发送请求并接收返回结果。SQLite不是这样工作的。使用SQLite,想要访问数据库的进程直接从磁盘上的数据库文件进行读写操作。没有中间服务器进程。

无服务器既有优点也有缺点。其主要优点是不需要单独的服务器进程来安装、设置、配置、初始化、管理和排除故障。这就是为什么SQLite是一个“零配置”数据库引擎的原因之一。使用SQLite的程序在运行前不需要设置数据库引擎的管理支持。任何能够访问磁盘的程序都可以使用SQLite数据库。

另一方面,使用服务器的数据库引擎可以更好地防止客户机应用程序中的错误——客户机中的零散指针不会破坏服务器上的内存。由于服务器是单个持久进程,因此它能够更精确地控制数据库访问,从而实现更细粒度的锁定和更好的并发性。

大多数SQL数据库引擎都是基于客户机/服务器的。在这些无服务器的数据库中,SQLite是笔者所知道的唯一一个允许多个应用程序同时访问同一个数据库的数据库。


单个数据库文件

SQLite数据库是一个普通的磁盘文件,可以位于目录层次结构中的任何位置。如果SQLite可以读取磁盘文件,那么它就可以读取数据库中的任何内容。如果磁盘文件及其目录是可写的,那么SQLite可以更改数据库中的任何内容。数据库文件可以很容易地复制到USB记忆棒或通过电子邮件共享。 其他SQL数据库引擎倾向于将数据存储为大型文件集合。通常,这些文件位于只有数据库引擎本身才能访问的标准位置。这使数据更加安全,但也使其更难访问。一些SQL数据库引擎提供直接写入磁盘的选项,完全绕过文件系统。这提供了额外的性能,但代价是相当复杂的设置和维护。


稳定的跨平台数据库文件

SQLite文件格式是跨平台的。在一台机器上写入的数据库文件可以复制到具有不同体系结构的另一台机器上并在其上使用。大端或小端,32位或64位并不重要。所有机器使用相同的文件格式。此外,开发人员承诺保持文件格式的稳定和向后兼容,因此新版本的SQLite可以读取和写入旧的数据库文件。 大多数其他SQL数据库引擎要求您在从一个平台迁移到另一个平台时转储和恢复数据库,并且经常在升级到软件的新版本时进行转储和恢复。


紧凑的

当针对大小进行优化时,启用所有功能的整个SQLite库的大小小于1MiB(使用GNU编译器套件中的“size”实用程序在ix86上测量)。可以在编译时禁用不需要的特性,以进一步减小库的大小。 大多数其他SQL数据库引擎都比这个大得多。IBM自夸其最近发布的CloudScape数据库引擎“仅”是一个2mb的jar文件——即使经过压缩,也比SQLite大了一个数量级!Firebird自夸它的客户端库只有350KiB。它和SQLite一样大,甚至不包含数据库引擎。来自Oracle的Berkeley DB库是450KiB,它省略了SQL支持,仅为程序员提供简单的键/值对。


显示输入

大多数SQL数据库引擎使用静态类型。数据类型与表中的每个列相关联,并且只允许将特定数据类型的值存储在该列中。SQLite通过使用清单类型放宽了这一限制。在清单类型中,数据类型是值本身的属性,而不是存储值的列的属性。因此,SQLite允许用户将任何数据类型的任何值存储到任何列中,而不管该列的声明类型是什么。(这条规则有一些例外:INTEGER PRIMARY KEY列可能只存储整数。在可能的情况下,SQLite尝试将值强制转换为列的声明数据类型。) 据我们所知,SQL语言规范允许使用清单类型。然而,大多数其他SQL数据库引擎都是静态类型的,因此有些人觉得使用清单类型是SQLite中的一个bug。但是SQLite的作者强烈认为这是一个特性。在SQLite中使用清单类型是一个经过深思熟虑的设计决策,实践证明,它使SQLite更可靠,更易于使用,特别是当与动态类型编程语言(如Tcl和Python)结合使用时。


变长记录

大多数其他SQL数据库引擎为大多数表中的每一行分配固定数量的磁盘空间。它们在处理blob和clob时使用特殊的技巧,这些blob和clob的长度变化很大。但是对于大多数表,如果您将一个列声明为VARCHAR(100),那么无论您在该列中实际存储了多少信息,数据库引擎都会分配100字节的磁盘空间。 相反,SQLite只使用实际需要的磁盘空间来存储一行中的信息。如果在VARCHAR(100)列中存储单个字符,则只消耗一个字节的磁盘空间。(实际上是两个字节——在每列的开头有一些开销来记录它的数据类型和长度。)

SQLite使用变长记录有很多优点。显然,这会导致更小的数据库文件。它还使数据库运行得更快,因为需要在磁盘之间移动的信息更少。而且,可变长度记录的使用使得SQLite可以使用清单类型而不是静态类型。


可读源代码

SQLite的源代码被设计成对普通程序员来说是可读和可访问的。所有过程和数据结构以及许多自动变量都被仔细地注释了,其中包含有关它们所做的工作的有用信息。样板注释被省略了。


SQL语句编译成虚拟机代码

每个SQL数据库引擎将每个SQL语句编译成某种内部数据结构,然后用于执行语句的工作。但是在大多数SQL引擎中,内部数据结构是由相互连接的结构和对象组成的复杂网络。在SQLite中,语句的编译形式是类似机器语言表示的短程序。数据库用户可以通过在查询前加上EXPLAIN关键字来查看该虚拟机语言。 在SQLite中使用虚拟机对库的开发有很大的好处。虚拟机在SQLite的前端(解析SQL语句并生成虚拟机代码的部分)和后端(执行虚拟机代码并计算结果的部分)之间提供了一个清晰的、定义良好的连接。虚拟机允许开发人员以一种易于阅读的形式清楚地看到SQLite试图对它编译的每条语句做什么,这对调试有很大的帮助。根据编译方式的不同,SQLite还具有跟踪虚拟机执行的能力——在执行时打印每个虚拟机指令及其结果。


公共领域

SQLite的源代码在公共领域。没有对核心源代码的任何部分提出版权要求。(文档和测试代码是另一回事——文档和测试逻辑的某些部分是由开源许可证管理的。)SQLite核心软件的所有贡献者都签署了声明,明确否认对代码有任何版权利益。这意味着任何人都可以合法地使用SQLite源代码做任何他们想做的事情。 还有其他具有自由许可的SQL数据库引擎,允许广泛和自由地使用代码。但其他引擎仍受版权法管辖。SQLite的不同之处在于版权法根本不适用。

其他SQL数据库引擎的源代码文件通常以注释开头,注释描述了查看和复制该文件的合法权利。SQLite源代码不包含许可证,因为它不受版权的约束。而不是许可证,SQLite源代码提供了一个祝福:

你们要行善,不要作恶 愿你能原谅自己,也原谅别人 愿你自由地分享,永不索取多于付出。


SQL语言扩展

SQLite提供了许多在其他数据库引擎中通常找不到的对SQL语言的增强。上面已经提到了EXPLAIN关键字和清单类型。SQLite还提供了诸如REPLACE和ON CONFLICT子句之类的语句,允许对约束冲突的解决进行额外的控制。SQLite支持ATTACH和DETACH命令,允许在同一个查询中一起使用多个独立的数据库。SQLite定义了允许用户添加新的SQL函数和排序序列的api。