小。速度很快。可靠。
选择任意三个选项。

常见问题

  1. 如何创建AUTOINCREMENT字段?
  2. SQLite支持哪些数据类型?
  3. SQLite允许我在integer类型的数据库列中插入字符串!
  4. 为什么SQLite不允许我使用“0”和“0.0”作为主键位于同一表的两个不同行上?
  5. 可以使用多个应用程序或相同的多个实例应用程序同时访问单个数据库文件?
  6. SQLite线程安全吗?
  7. 如何列出SQLite数据库中包含的所有表/索引
  8. SQLite数据库有任何已知的大小限制吗?
  9. SQLite中VARCHAR的最大大小是多少?
  10. SQLite支持BLOB类型吗?
  11. 如何在SQLite中添加、删除或重命名现有表中的列?
  12. 我删除了很多数据,但数据库文件没有得到任何数据更小。这是一个错误吗?
  13. 我可以在不支付版税的情况下在我的商业产品中使用SQLite吗?
  14. 如何使用包含嵌入单引号(')的字符串文字性格?
  15. 什么是SQLITE_SCHEMA错误,为什么会出现这种错误?
  16. 编译SQLite时收到一些编译器警告。这不是一个问题吗?这不表明代码质量很差吗?
  17. Unicode字符的大小写不敏感匹配不起作用。
  18. INSERT非常慢-我每秒只能执行几十次INSERT
  19. 我不小心从SQLite数据库中删除了一些重要信息。我怎样才能恢复它?
  20. 什么是SQLITE_CORRUPT错误?这对数据库意味着什么成为“畸形”?为什么我会收到这个错误?
  21. SQLite支持外键吗?
  22. 如果我使用SQLITE_OMIT_。。。生成SQLite时的编译时间选项。
  23. My WHERE子句表达式column1=“column1”不起作用。它会返回表中的每一行,而不仅仅是行其中column1的值为“columnl”。
  24. 如何使用语法图(也称为“铁路”图)生成SQLite?
  25. SQL标准要求强制执行UNIQUE约束,即使约束中的一个或多个列为NULL,但SQLite为NULL不要这样做。那不是一个错误吗?
  26. SQLite的出口管制分类号(ECCN)是什么?
  27. 我的查询没有返回我期望的列名。这是一个错误吗?
  28. 我的数据库去哪里了?(或者:我的数据库是如何变空的?)

(1) 如何创建AUTOINCREMENT字段?

简短回答:声明了一列整数主键自动增量。

更长的答案:如果您将表的一列声明为集成主键,然后每当插入NULL时将NULL自动转换为表中的该列变为一个整数,该整数大于该整数的最大值列覆盖表中的所有其他行,如果表为空,则为1。或者,如果正在使用现有最大整数键9223372036854775807,则未使用的键值是随机选择的。例如,假设您有这样一张表:

创建表t1(一个整数主键,b整数);

在这个表中

插入t1值(NULL,123);

在逻辑上等同于说:

插入t1值(从t1中选择max(a))+1123);

有一个名为的函数sqlite3_last_insert_rowid()它将返回整数键用于最新的插入操作。

注意,整数键比最大键大一插入之前表中的键。新密钥对于表中当前的所有键都是唯一的,但它可能与以前从中删除的键重叠表。要创建在表,添加自动更正关键字集成主键宣言。然后选择的键将比该表中有史以来最大的键。如果最大可能的键以前已经存在于该表中,那么插入将失败,并返回SQLITE_FULL(_S)错误代码。

(2) SQLite支持哪些数据类型?

SQLite使用动态键入.内容可以存储为INTEGER,REAL、TEXT、BLOB或为NULL。

(3) SQLite允许我在integer类型的数据库列中插入字符串!

这是一个功能,而不是一个错误。SQLite使用动态键入. 它不强制执行数据类型约束。任何类型的数据都可以(通常)插入任何列中。你可以把任意长度字符串转换为整数列,浮点数转换为布尔列,或字符列中的日期。这个数据类型指定给中的列CREATE TABLE命令不限制可以放入哪些数据那个专栏。每个列都能够容纳任意长度的字符串。(有一个例外:列类型集成主键只能保存64位有符号整数。将导致错误如果您尝试将除整数以外的任何内容放入集成主键列。)

但SQLite确实使用声明的列类型作为提示您更喜欢该格式的值。例如,如果列的类型为INTEGER,您尝试将字符串插入SQLite将尝试将该字符串转换为整数。如果可以,则插入整数。如果没有,它插入字符串。此功能称为类型亲和力.

(4) 为什么SQLite不允许我使用“0”和“0.0”作为主在同一张表的两个不同行上键入?

当主键是数字类型时,会出现此问题。更改数据类型TEXT的主键,它应该可以工作。

每一行都必须有一个唯一的主键。对于具有数字类型,SQLite认为'0''0.0'相同的值,因为它们在数值上的比较是相等的。(请参阅前面的问题。)因此,这些值不是唯一的。

(5) 可以使用多个应用程序或相同的多个实例应用程序同时访问单个数据库文件?

多个进程可以同时打开同一数据库时间。多个进程可以执行SELECT同时。但只有一个过程可以对然而,数据库随时可用。

SQLite使用读写器锁来控制对数据库的访问。(在缺少读写器锁支持的Win95/98/ME下而是使用概率模拟。)但要小心:这种锁定机制可能如果数据库文件保存在NFS文件系统上,则无法正常工作。这是因为许多NFS实现上的fcntl()文件锁定已中断。如果有多个SQLite数据库文件,应避免将其放在NFS上进程可能会同时尝试访问该文件。在Windows上,微软的文档表明,在FAT下锁定可能不起作用文件系统(如果您没有运行Share.exe守护程序)。那些有很多使用Windows的经验告诉我网络文件有很多缺陷,不可靠。如果他们比如说,在两个或多个Windows之间共享SQLite数据库机器可能会导致意外问题。

我们不知道其他嵌入的SQL数据库引擎支持与SQLite相同的并发性。SQLite允许多个进程一次打开数据库文件,对于多个进程立即读取数据库。当任何进程想要写入时,它必须在更新期间锁定整个数据库文件。但那个通常只需要几毫秒。其他进程只需等待写完后继续写他们的生意。其他嵌入式SQL数据库引擎通常只允许单个进程连接到立即访问数据库。

然而,客户端/服务器数据库引擎(例如PostgreSQL、MySQL、,或Oracle)通常支持更高级别的并发,并允许多个进程同时写入同一数据库。这在客户机/服务器数据库中是可能的,因为始终存在单个控制良好的服务器进程可用于协调访问。如果您的应用程序需要大量并发,那么您应该考虑使用客户机/服务器数据库。但经验表明大多数应用程序需要的并发性比设计者想象的要少得多。

当SQLite试图访问另一个锁定的文件时进程,默认行为是返回SQLITE_BUSY。你可以使用sqlite3_busy_handler()sqlite3_busy_timeout()API函数。

(6) SQLite线程安全吗?

线是邪恶的.避开他们。

SQLite是线程安全的。我们做出了这一让步,因为许多用户选择忽略上一段中给出的建议。但为了线程安全,必须编译SQLite将SQLITE_THREADSAFE预处理器宏设置为1。两个窗口发行版中的Linux预编译二进制文件是这样编译的。如果您不确定链接的SQLite库是否已编译为了确保线程安全,您可以调用sqlite3_threadsafe()界面进行查找。

SQLite是线程安全的,因为它使用互斥来序列化访问公共数据结构。然而,收购和释放这些互斥会稍微降低SQLite的速度。因此,如果您SQLite不需要线程安全,您应该禁用互斥锁以获得最佳性能。请参阅线程模式文档其他信息。

在Unix下,不应携带打开的SQLite数据库对子进程进行fork()系统调用。

(7) 如何列出SQLite数据库中包含的所有表/索引

如果您正在运行方形3命令行访问程序您可以键入“.表格“获取所有表的列表。或者您可以键入“.schema模式“查看完整的数据库架构,包括所有表和索引。以下任一命令都可以后跟LIKE模式将限制显示的表格。

从C/C++程序(或使用Tcl/Ruby/Perl/Python的脚本)中绑定)可以通过执行SELECT访问表和索引名称在名为“SQLITE_SCHEMA公司“.每个SQLite数据库具有定义数据库架构的SQLITE_SCHEMA表。SQLITE_SCHEMA表如下所示:

创建表sqlite_schema(键入TEXT,名称TEXT,tbl_name文本,根页INTEGER,sql文本);

对于表格类型字段将始终为'表'名称字段将是表的名称。所以要获得数据库中的所有表,请使用以下SELECT命令:

从sqlite_schema中选择名称WHERE type=“表格”ORDER BY名称;

对于指数,类型等于'索引',名称索引名称和tbl名称是指向的表的名称索引属于。对于表和索引sql语言字段是原始CREATE TABLE或CREATE INDEX语句的文本创建了表或索引。对于自动创建的索引(使用实现PRIMARY KEY或UNIQUE约束)sql语言领域为空。

不能使用UPDATE、INSERT、,或DELETE(除了在特殊情况). SQLITE_SCHEMA表由以下命令自动更新CREATE TABLE、CREATE INDEX、DROP TABLE和DROP INDEX。

临时表不会出现在SQLITE_SCHEMA表中。临时表及其索引和触发器出现在另一个特殊表中名为SQLITE_TEMP_SCHEMA。SQLITE_TEMP_SCHEMA的工作原理与SQLITE_SCHEMA类似但它只对创建了临时表。获取所有表的列表,包括永久表和临时的,可以使用类似以下命令:

从中选择名称(从sqlite_schema UNION ALL中选择*从sqlite_temp_schema中选择*)WHERE type=“表格”ORDER BY名称

(8) SQLite数据库有任何已知的大小限制吗?

请参见限制.html进行全面讨论SQLite的极限。

(9) SQLite中VARCHAR的最大大小是多少?

SQLite不强制VARCHAR的长度。你可以申报VARCHAR(10)和SQLite很乐意存储5亿个字符把绳子挂在那里。它将保持所有5亿个字符的完整性。您的内容永远不会被截断。SQLite了解列类型“VARCHAR”的(N个)“与”TEXT“相同,不考虑值属于N个.

(10) SQLite支持BLOB类型吗?

SQLite允许您将BLOB数据存储在任何列,甚至声明为包含其他类型的列。BLOB甚至可以用作主键。

(11) 如何在SQLite中添加、删除或重命名现有表中的列?

SQLite具有有限的ALTER TABLE支持,可以用于添加、重命名或删除列或更改表名详见ALTER表格.

如果您想对结构或表或其列的约束,则必须重新创建它。您可以将现有数据保存到临时表中,删除旧表,创建新表,然后从中复制数据临时表。请参见进行其他类型的表架构更改用于程序。

(12) 我删除了很多数据,但数据库文件没有得到任何数据更小。这是一个错误吗?

否。当您从SQLite数据库中删除信息时未使用的磁盘空间被添加到内部“自由列表”中并被重用下次插入数据时。磁盘空间不会丢失。但是它也没有返回到操作系统。

如果您删除了大量数据并想收缩数据库文件,运行真空命令。真空将重建从头开始创建数据库。这将使数据库为空免费列表和最小大小的文件。但请注意VACUUM可能需要一些时间才能运行,最多可以使用两次运行时与原始文件相同的临时磁盘空间。

使用VACUUM命令的替代方法是自动真空模式,使用自动真空杂波.

(13) 我可以在不支付版税的情况下在我的商业产品中使用SQLite吗?

对。SQLite位于公共领域.未提出所有权主张代码的任何部分。你可以用它做任何你想做的事。

(14) 如何使用包含嵌入单引号(')的字符串文字性格?

SQL标准指定对字符串中的单引号进行转义把两个单引号放在一行。SQL的工作原理与Pascal编程类似这方面的语言。例子:

插入xyz值(“5 O”“clock”);

(15) 什么是SQLITE_SCHEMA错误,为什么会出现这种错误?

SQLITE_SCHEMA公司准备好的SQL语句不再有效,无法执行。发生这种情况时,必须使用这个sqlite3_prepare()应用程序编程接口。仅当使用sqlite3_prepare(),sqlite3_step()接口来运行SQL。你永远不会收到SQLITE_SCHEMA公司错误来自sqlite3_exec()。如果您使用准备语句sqlite3_prepare_v2()而不是sqlite3_prepare().

这个sqlite3_prepare_v2()接口创建准备好的报表它将自动重新编译自身,如果模式发生更改。最简单的处理方法SQLITE_SCHEMA公司错误总是使用sqlite3_prepare_v2()而不是sqlite3_prepare().

(17) 当我编译SQLite时,我收到了一些编译器警告。这不是一个问题吗?这不表明代码质量很差吗?

SQLite的质量保证使用全覆盖测试,不是通过编译器警告或其他静态代码分析工具。换句话说,我们验证SQLite实际上获得了正确的答案,并不是说它仅仅满足了文体限制。大多数SQLite代码库纯粹用于测试。SQLite测试套件运行成千上万个单独的测试用例这些测试用例中的许多都是参数化的,因此数以亿计的运行和评估了涉及数十亿条SQL语句的测试确保每次发布前的正确性。开发人员使用代码覆盖率工具,以验证通过代码的所有路径都经过了测试。每当在SQLite中发现错误时,都会写入新的测试用例展示错误,这样错误就不会在未来再次出现而未被发现。

在测试期间,SQLite库使用特殊的允许测试脚本模拟各种故障,以验证SQLite是否恢复正确地。仔细跟踪内存分配,没有内存即使在内存分配失败后也会发生泄漏。一种风俗VFS层用于模拟操作系统崩溃和电源失败,以确保跨这些事件。故意注入I/O错误的机制表明SQLite对此类故障具有弹性。(作为尝试在其他SQL数据库上诱发此类错误引擎,看看会发生什么!)

我们还使用瓦尔格林德并验证它没有检测到任何问题。

有些人说我们应该消除所有警告,因为良性警告掩盖了未来变化中可能出现的实际警告。这是真的。但作为回应,开发人员发现警告已在生成中修复用于SQLite开发(各种版本的GCC、MSVC、,和叮当声)。编译器警告通常只出现在编译器或编译时SQLite开发人员自己不使用的选项。

(18) Unicode字符的大小写不敏感匹配不起作用。

SQLite的默认配置仅支持区分大小写ASCII字符的比较。这样做的原因是完整的Unicode区分大小写的比较和大小写转换需要的表和逻辑的大小几乎是SQLite库。这个SQLite开发人员认为任何需要完整的应用程序Unicode大小写支持可能已经有了必要的表和因此SQLite不应占用空间来复制这个能力。

默认情况下不提供完整的Unicode案例支持,SQLite提供了与外部链接的能力Unicode比较和转换例程。应用程序可能会重载内置无案例整理顺序(使用sqlite3_create_collation())和内置类似(),upper()、和下部()功能(使用sqlite3_create_function()). SQLite源代码包含一个“ICU”扩展这些过载。或者,开发人员可以编写自己的重载基于他们自己的Unicode软件比较例程包含在他们的项目中。

(19) INSERT非常慢-我每秒只能执行几十次INSERT

实际上,SQLite很容易做到50000或更多插入每秒语句数在普通的台式计算机上。但它只做几十笔交易每秒。事务速度受您的磁盘驱动器。一个事务通常需要两个完整的循环在7200RPM磁盘驱动器上,磁盘盘的容量限制为每秒60个事务。

事务速度受磁盘驱动器速度的限制,因为(默认情况下)SQLite实际上一直等到数据真正安全地存储在磁盘上在事务完成之前浮出水面。这样,如果你突然输了如果你的操作系统崩溃,你的数据仍然是安全的。有关详细信息,阅读有关SQLite中的原子提交。.

默认情况下,每个INSERT语句都是自己的事务。但是如果你将多个INSERT语句括起来开始...承诺然后所有的插入被分组到单个事务中。承诺所需的时间该交易在所有随附的插入报表中摊销因此,每个insert语句的时间大大缩短。

另一种选择是运行PRAGMA同步=关闭。此命令将导致SQLite不等待数据到达磁盘表面,这将使写操作似乎要快得多。但如果你在在事务处理过程中,数据库文件可能会损坏。

(20) 我不小心从SQLite数据库中删除了一些重要信息。我怎样才能恢复它?

如果您有数据库文件的备份副本,请恢复信息从您的备份中。

如果没有备份,恢复将非常困难。你可能会能够在原始数据库的二进制转储中找到部分字符串数据文件。如果使用特殊工具,也可以恢复数字数据,尽管据我们所知,还不存在这样的工具。有时会编译SQLite使用SQLITE_SECURE_DELETE公司覆盖所有已删除内容的选项带有零。如果是这样,那么复苏显然是不可能的。如果你跑步了,恢复也不可能真空因为数据是删除。如果未使用SQLITE_SECURE_DELETE且未运行VACUUM,那么一些删除的内容可能仍在数据库文件中标记为重复使用的区域。但是,同样没有程序或工具帮助您恢复数据。

(21)什么是SQLITE_CORRUPT错误?这对数据库意味着什么“畸形”?为什么我会收到这个错误?

SQLITE_CORRUPTSQLite检测到错误时返回错误的结构、格式或其他控制元素中数据库文件。

没有外部帮助,SQLite不会损坏数据库文件。如果您的应用程序在更新,您的数据是安全的。即使您的操作系统是安全的崩溃或断电。SQLite的防撞性经过了广泛的研究和测试,并经过多年的实际验证数十亿用户的体验。

也就是说,有很多外部程序或bug在硬件或操作系统中可能会损坏数据库文件。请参见如何损坏SQLite数据库文件对于更多信息。

你可以使用PRAGMA完整性检查对数据库完整性进行彻底但耗时的测试。

你可以使用PRAGMA快速检查做得更快但对数据库完整性的测试不够彻底。

根据数据库损坏的程度,您可以通过使用CLI转储架构和内容来恢复部分数据然后重新创建。不幸的是,一旦驼背垃圾掉落墙,通常是不可能把他放回一起的。

(22)SQLite支持外键吗?

截至版本3.6.19(2009-10-14), SQLite支持外键约束.但强制执行默认情况下,将关闭外键约束(用于向后兼容)。要启用外键约束强制,请运行PRAGMA foreign_keys=开或使用编译-DSQLITE_DEFAULT_foregin_KEYS=1.

(23)如果我使用SQLITE_OMIT_。。。生成SQLite时的编译时间选项。

这个SQLITE_OMIT_。。。编译时选项仅起作用从规范源文件生成时。他们确实如此工作当您从SQLite构建时合并或从预处理的源文件。

可以建造一个特殊的合并这将与一组预定的SQLITE_OMIT_。。。选项。操作说明所以可以用SQLITE_OMIT_。。。文档.

(24)My WHERE子句表达式column1=“column1”不起作用。它会返回表中的每一行,而不仅仅是行其中column1的值为“columnl”。

在SQL中的字符串文字周围使用单引号,而不是双引号。这就是SQL标准所要求的。WHERE子句表达式应为:column1=“第1列”

SQL在标识符(列或表名)周围使用双引号包含特殊字符或关键字。所以双引号是转义标识符名称的方法。因此,当你说column1=“column1”这相当于column1=列1这显然总是正确的。

(25)如何使用语法图(也称为“铁路”图)生成SQLite?

每个图表都是使用Pikchr公司图表语言。这些手写规范转换为SVG并作为文档构建过程的一部分在HTML文件中内联插入。

SQLite文档的许多历史版本使用了不同的过程生成语法图。历史过程基于Tcl/Tk描述于http://wiki.tcl-lang.org/21708更新的基于Pikchr的语法图2020-09-26年首次降落在树干上。

(26)SQL标准要求强制执行UNIQUE约束,即使约束中的一个或多个列为NULL,但SQLite为NULL不要这样做。那不是一个错误吗?

可能您指的是SQL92中的以下语句:
当且仅当表在唯一列中具有相同的非空值。
这一说法模棱两可,至少有两种可能的解释:
  1. 当且仅当表具有相同的值,并且在唯一列中具有非空值。
  2. 当且仅当表在不为null的唯一列的子集中具有相同的值。
SQLite遵循解释(1),PostgreSQL、MySQL、Oracle、,和Firebird。Informix和Microsoft SQL Server确实使用解释(2),然而我们SQLite开发人员认为口译(1)是最自然的阅读我们还希望最大限度地与其他SQL数据库引擎和大多数其他数据库引擎也与(1)、,这就是SQLite所做的。

(27)SQLite的出口管制分类号(ECCN)是什么?

在仔细审查商业控制清单(CCL)后,我们确信任何ECCN都没有描述核心公共域SQLite源代码,因此,ECCN应报告为EAR99公司.

对于核心公共域SQLite,上述情况是正确的。如果您延长通过添加新代码或静态链接SQLite应用程序,这可能会在您的特定情况下更改ECCN。

(28)我的查询没有返回我期望的列名。这是一个错误吗?

如果结果集的列是由AS子句命名的,那么SQLite保证使用AS关键字右侧的标识符作为列名。如果结果集不使用AS子句,则SQLite可以随意为列命名。请参阅sqlite3_column_name()文档以获取更多信息。

(29)我的数据库去了哪里?(或者:我的数据库是如何变空的?)

除非打开时带有阻止它的标志,否则将创建SQLite数据库如果它还不存在。新创建的数据库最初为空。这可能会让无意中打开不同数据库文件的人感到困惑在不同的上下文中,由于文件名中的输入错误或使用与一起使用的相对路径名打开进程的不同当前目录。

此页面上次修改时间2023-12-22 14:38:37联合技术公司