菜单

SQLite FAQ中文版

2018年11月16日 - sqlite
  1. 怎创造于加字段?
  2. SQLite 支持什么数据类型?
  3. 干什么能够为 SQLite 数据库的整型字段中插入入字符串?
  4. 怎么 SQLite 认为表达式 ‘0’==’00’ 为确实?
  5. 胡 SQLite 不允以一如既往摆放表里使用 ‘0’ 和 ‘0.0’
    作为少数单不同之推行之主键?
  6. 为何未可知以 Linux box 中读取在 SparcStation 中开创的 SQLite
    数据库?
    7.
    几近只应用程序或者和一个应用程序的大半个例程能以存取同一个数据库文件也?
  7. SQLite是线程安全之也?
  8. 哪些列有一个 SQLite 数据库中之具备的表/索引?
  9. SQLite数据库是否生曾经领略之大小限制?
  10. 每当 SQLite 中 VARCHAR 的极端老尺寸是微?
  11. SQLite 是否支持 BLOB 类型?
  12. 何以从一个早就存在的 SQLite 数据表中添加/删除字段?
  13. 本人去了森数码只是数据库文件并无减弱多少,是休是 Bug?
  14. 是不是能够以 SQLite 用于商业用途而不用交版权费用?
  15. 自身怎么样运用含单引号(‘)的字符串?
  16. SQLITE_SCHEMA 错误代表什么?
  17. 胡ROUND(9.95,1) 返回 9.9 而非是 10.0? 难道9.95
    不拖欠提高进发位么?
  1. 安创造于增字段?
  2. SQLite
    支持什么数据类型?
  3. 何以会往 SQLite
    数据库的整型字段中插入字符串?
  4. 怎 SQLite 认为表达式 ‘0’==’00’
    为真正?
  5. 缘何 SQLite 不允许在相同布置表里使用 ‘0’ 和 ‘0.0’
    作为片独不同的履行的主键?
  6. 何以未可知在 Linux box 中读取在 SparcStation 中创造的 SQLite
    数据库?
  7. 多个应用程序或者跟一个应用程序的大半单例程能而且存取同一个数据库文件为?
  8. SQLite是线程安全的为?
  9. 怎列有一个 SQLite
    数据库被的富有的表/索引?
  10. SQLite数据库是否发已经知道的轻重缓急限制?
  11. 在 SQLite 中 VARCHAR
    的最可怜长是微?
  12. SQLite 是否支持 BLOB
    类型?
  13. 哪些自一个曾经是的 SQLite
    数据表中添加/删除字段?
  14. 本人去了众多数而数据库文件并无减弱多少,是未是
    Bug?
  15. 是不是能以 SQLite
    用于商业用途而不用交版权费用?
  16. 自身哪使含单引号(‘)的字符串?
  17. SQLITE_SCHEMA
    错误代表什么?
  18. 怎ROUND(9.95,1) 返回 9.9 而不是 10.0? 难道9.95
    不拖欠提高进发位么?

(1) 如何创建于加字段?


大概的答疑:一个声明也 INTEGER PRIMARY KEY 的字段将自动增加。

(1) 如何创造于添字段?

此间是事无巨细的答案: 从 SQLite 的 2.3.4
版本开始,如果您将一个表中的一个字段声明也 INTEGER PRIMARY
KEY,那么不论你何时为该表的该字段插入一个 NULL 值,这个 NULL
值将电动为撤换也比表中该字段所有行的最特别价值大 1
的平头;如果表也空,那么以为更换为 1。比如,假而你闹如此的一样摆数据表:

简易的答应:一个扬言也 INTEGER PRIMARY KEY 的字段将自动增加。

此间是事无巨细的答案: 从 SQLite 的 2.3.4
版本开始,如果您用一个表中的一个字段声明也 INTEGER PRIMARY
KEY,那么不论你何时为该表的该字段插入一个 NULL 值,这个 NULL
值将自行为撤换也比表中该字段所有行的极老价值大 1
的平头;如果表也空,那么以受更换为 1。比如,假而你闹这般的同等布置数据表:

CREATE TABLE t1(

a INTEGER PRIMARY KEY,

b INTEGER

);

于当下张数表里,声明

INSERT INTO t1 VALUES(NULL,123);

当逻辑意义上价于:

INSERT INTO t1 VALUES((SELECT max(a) FROM t1)+1,123);

一个初的API函数
sqlite3_last_insert_rowid()
返回最近之插入操作的整形键

瞩目是整型键始终比之前插入表中的末梢一个键大1。新键相对于表中的都发出键来说是绝无仅有的,
但它可能和前面由表中删除的键值重叠。要一直抱在周表中唯一的键,在INTEGER
PRIMARY
KEY的扬言前加要词AUTOINCREMENT.这样被挑的键将总是比表中既存在的不过特别键大1。若可能的
最大键已是于表中,INSERT操作以败并回一个SQLITE_FULL错误码.

CREATE TABLE t1(
a INTEGER PRIMARY KEY,
b INTEGER
);


以及时张数表里,声明

(2) SQLite 支持什么数据类型?

INSERT INTO t1 valueS(NULL,123);

参见 http://www.sqlite.org/datatype3.html .

于逻辑意义上价于:


INSERT INTO t1 valueS((SELECT max(a) FROM t1)+1,123);

(3) 为什么能朝 SQLite 数据库的整型字段中插入入字符串?

一个新的API函数 sqlite3_last_insert_rowid()
返回最近的插操作的整形键

当即是一个功能,不是一个
bug。你得在另字段中放任何信息,而不用无配段声明为什么类型。
你得望整型字段中插任意长度的字符串,或者朝布尔字段中插入浮点数,或者往字符字段中
插入日期。在 CREATE TABLE
命令中你指定为这个字段的数据类型不会见克插入这个字段的多寡。
所有的字段可以插任意长度的字符串。但对于 INTEGER PRIMARY KEY
字段例外。这种字段只能 存放一个64位之平头,否则会出错。

而SQLite会默认你盼使声明的字段类型。所以,比如你想以一个声明也INTEGER的字段
中插入一个字符串,SQLite会试图用那易为一个平头。如果换成,那么整数将受插入,否
则插入字符串,这种特点有时让称为type or column
affinity .

只顾是整型键始终比前插入表中的结尾一个键大1。新键相对于表中之已经生键来说是唯一的,
但它或许同之前由表中删除的键值重叠。要直得到在周表中绝无仅有的键,在INTEGER
PRIMARY
KEY的扬言前加要词AUTOINCREMENT.这样让挑选的键将总是比表中已经在的尽充分键大1。若可能的
最大键已存在于表中,INSERT操作以失败并返回一个SQLITE_FULL错误码.


(2) SQLite 支持什么数据类型?

(4) 为什么 SQLite 认为表达式 ‘0’==’00’ 为真正?

参见 http://www.sqlite.org/datatype3.html.

在 2.7.0 之后,表达式不树立。参见文档 datatypes in SQLite version
3

(3) 为什么能为 SQLite 数据库的整型字段中插入字符串?


当时是一个功力,不是一个
bug。你得于另字段中放任何消息,而非用无配段声明为什么类型。
你可以于整型字段中插任意长度的字符串,或者朝布尔字段中插浮点数,或者往字符字段中
插入日期。在 CREATE TABLE
命令中而指定为此字段的数据类型不会见克插入这个字段的多寡。
所有的字段可以插任意长度的字符串。但对此 INTEGER PRIMARY KEY
字段例外。这种字段只能 存放一个64员之平头,否则会错。

(5) 为什么 SQLite 不允以同等布置表里使用 ‘0’ 和 ‘0.0’
作为片只例外之推行之主键?

只是SQLite会默认你期望使声明的字段类型。所以,比如你指望以一个声明也INTEGER的字段
中插入一个字符串,SQLite会试图以那个易为一个平头。如果换成,那么整数将为插,否
则插入字符串,这种特点有时让称作type or column affinity.

而的主键一定是数值类的,把路变更也 TEXT 就可以了。

列一行要来一个唯一的主键。作为一个数字型的字段,SQLite 认为
‘0’‘0.0’ 的价是均等之,
因为他俩当数字达到的于是等的(看眼前的题目)因此值不是绝无仅有的。

123456下一页翻阅全文


卿或许感兴趣之稿子:

(6) 为什么不克以 Linux box 中读取在 SparcStation 中开创的 SQLite
数据库?

汝要升级而的 SQLite 库到 2.6.3 或更新版本。

x86 处理器是 little-endian 型的要 Sparc 是 big-endian 型的。新本子的
SQLite 解决了这问题。

流淌:   big endian和little
endian是CPU处理多配节数的两样措施。例如“汉”字的Unicode编码是6C49。那么写及文件里不时,究竟是拿6C写于前边,还是将49勾以前头?如果以6C写在前方,就是big
endian。还是用49描绘于眼前,就是little endian。


(7)
多单应用程序或者与一个应用程序的基本上只例程能同时存取同一个数据库文件呢?

基本上进程可以而且开辟和一个数据库,也得同时 SELECT
。但只生一个经过可以及时改数据库。

SQLite使用读/写锁定来控制数据库访问。(Win95/98/ME
操作系统缺乏读/写锁定支持,在低于 2.7.0 的本子被,这代表在 windows
下在同一时间内只能有一个历程读数据库。在本子 2.7.0 中 这个题目经过当
windows 接口代码中尽一个用户距离几带领读写锁定策略解决了。)
但如果数据库文件在一个 NFS
文件系统中,控制并发读书之锁定机制可以见面出错。因为 NFS 的fcntl()
文件锁定有时会来题目。如果有多进程或并发读数据库则以当避免把数据库文件在
NFS 文件系统中。 根据微软的文档,如果未运行 Share.exe 后台程序则 FAT
文件系统中的锁定或者无坐班。对 Windows
非常有更的人口报自己网络文件之锁定有广大题材还要不可靠。如果是这样,在2单或上述
Windows 系统中共享一个 SQLite 数据库文件会促成不可预知的题材。

咱俩知晓没有其它的嵌入式 SQL数据库引擎比SQLite支持再次多之并发性。
SQLite允许多进程
同时开辟和读取数据库。任何一个经过要写副常,整个数据库将在当下无异过程中叫锁定。但这一般不过耗时
几毫秒。其他进程就待等候接下来继续其他事情。其他嵌入式SQL数据库引擎往往只同意单独进程看数据库。

可,client/server型的数据库引擎 (如 PostgreSQL, MySQL, 以及 Oracle)
通常支持再次胜的连发度,
并支持多进程又写副同一个数据库。由于总起一个操纵良好的服务器协调数据库的顾,这才保证了以上
特性的兑现。如果您的行使得格外高的连发度,你该考虑使用client/server数据库。事实上,经验告诉
我们大部分采用所要之并发度比她们的设计者们想象的如果丢得多。

当 SQLite 尝试操作一个于别一个进程锁定的文本时,缺省之作为是回来
SQLITE_BUSY。你可用 C代码更改这等同行事。 使用
sqlite3_busy_handler()
或sqlite3_busy_timeout()
API函数。

假设少单或更多进程又打开和一个数据库,其中一个经过创造了新的发明要索引,则其它进程或无克马上看见新的表明。其它进程可能用关闭并重新接数据库。


(8) SQLite是线程安全的吗?

偶是的。为了线程安全,SQLite 必须以编译时把 THREADSAFE
预处理宏设为1。在少省之发行的既编译版本被 Windows 版的凡线程安全之,而
Linux 版的不是。如果要求线程安全,Linux 版的设重编译。

“线程安全”是赖二个或三个线程可以而且调用独立的差的sqlite3_open()
返回的”sqlite3 “结构。而无是当多线程中还要利用以及一个 sqlite3
结构指针。

一个sqlite3 结构只能于调用
sqlite3_open
创建它的老大进程面临使用。你不能够以一个线程中开拓一个数据库然后拿指针传递让其他一个线程使用。这是坐大部分基本上线程系统的克(或
Bugs?)例如RedHat9上。在这些有问题之系统上,一个
线程创建的fcntl()锁不克由其余一个线程删除或改。由于SQLite依赖fcntl()锁来拓展并发控制,当在线程间传递数据库连接时会见现出重的问题。

想必在Linux下发出主意缓解fcntl()锁之题材,但那十分复杂并且对对的测试用凡绝困难的。因此,SQLite目前不允许在线程间共享句柄。

在UNIX下,你无能够由此一个 fork() 系统调用把一个开拓的 SQLite
数据库放入子过程遭到,否则会拧。


(9) 如何列有一个 SQLite 数据库中的富有的表/索引?

sqlite3 命令行程序中若可以为此命令 “.tables
来展示所有的表或者用 “.schema
“来展示所有的表明结构及目录。但令后不用跟 LIKE
语句,否则会限制表的示。

在 C/C++ 程序中 (或用
Tcl/Ruby/Perl/Python绑定的下本中)你得经拜访名也”SQLITE_MASTER
的表来实现。每个 SQLite 数据库来一个 SQLITE_MASTER
表,表内出数据库的组织。SQLITE_MASTER表是这般的:

CREATE TABLE sqlite_master (

type TEXT,

name TEXT,

tbl_name TEXT,

rootpage INTEGER,

sql TEXT

);

对于表来说,type 字段的价为‘table’name
字段是表明底称。使用以下语句可以等及所有表的列表:

SELECT name FROM sqlite_master

WHERE type=’table’

ORDER BY name;

对索引来说, type = ‘index’ , name 是索引的名称,
tbl_name 是索引所属的发明的名号。对于表及目录,sql
字段是创办表要索引的原始语句文本。对于自动创建的目录(一般是使用
PRIMARY KEY 或 UNIQUE 创建的),sql 字段为 NULL.

SQLITE_MASTER表是只读的。你切莫可知对该表使用 UPDATE, INSERT, 或
DELETE。该表自动由 CREATE TABLE, CREATE INDEX, DROP TABLE 和 DROP
INDEX 命令更新。

临时表及其索引不在 SQLITE_MASTER 表中只要于 SQLITE_TEMP_MASTER
中出现。SQLITE_TEMP_MASTER 与 SQLITE_MASTER
表一样干活,但一味于开创临时表的次可见。要落所在表包括临时表可以应用如下命令:

SELECT name FROM 

(SELECT FROM sqlite_master UNION ALL

SELECT
FROM sqlite_temp_master)

WHERE type=’table’

ORDER BY name


(10) SQLite数据库是否来曾了解之轻重限制?

数据库大小为限制以 2TB(241 bytes).
这是理论限制。事实上,你应该把
SQLite数据库的深浅限制于100GB以下,以免出现运行性能及之问题。如果你得仓储100GB或还多数据以一个数据库被,
考虑以也是要计划之营业所版数据库吧。

一个数据库的争辩行数限制是 264
-1,显然你见面以上行数限制之前先行超过文件大小的范围。目前一行可以存放
230 bytes 数据。而基本的文件格式可以支撑实施大小及横
262 bytes.

或者还会有于表、索引的数码或表和目录中的配段往往的克,但没有人领略凡是微。事实上,每当新数据库打开时,SQLite需要读取和
分析所有表和目录声明的初始SQL,所以,为了调用
sqlite3_open()
时获得最佳性能,最好减少声明的表底多少。同样的,即使
对于表中配段往往没有界定,多于100个吗显示太多了。
只来说明开的31只字段会收获优化。你可以以一个目中放入任意多的字段但过30字段的目将非用于优化查询。

申,索引,视图,触发器和字段名称可以任意长,但SQL 函数名 (由
sqlite3_create_function()
API创建的)不得超过255独字符。


(11) 在 SQLite 中 VARCHAR 的绝特别长是不怎么?

SQLite不强制VARCHAR的长短。你可声明一个VARCHAR(10),SQLite一样可以于您存放500只字符在里边。
并且其会始终完整无缺——决不会被截断。


(12) SQLite 是否支持 BLOB 类型?

SQLite 3.0 版支持以旁字段存放 BLOB 数据,不管字段声明为什么类型。


(13) 如何自一个曾经是的 SQLite 数据表中添加/删除字段?

SQLite有零星的ALTER
TABLE
支持,可以用于补充加字段到表的末尾
或改动表名。如果您只要对表的结构作更复杂的修改,你待再创建表。你得当一个临时表中备份数据,撤销原表,重建新表后还回复数据。

比如说,假而你出一个名为也 “t1” 的阐明,有名吧 “a”, “b”, 和 “c”
三独字段,你若刨除字段 “c” 。可据如下步骤操作:

BEGIN TRANSACTION;

CREATE TEMPORARY TABLE t1_backup(a,b);

INSERT INTO t1_backup SELECT a,b FROM t1;

DROP TABLE t1;

CREATE TABLE t1(a,b);

INSERT INTO t1 SELECT a,b FROM t1_backup;

DROP TABLE t1_backup;

COMMIT;


(14) 我去了众数据而数据库文件并不曾减弱多少,是不是 Bug?

不是的。当您于 SQLite
删除数据之后,未下的磁盘空间被补加至一个内在的“空闲列表”中用于存储你下次安插的数据。磁盘空间并没有少,但是呢不向操作系统返回磁盘空间。

而你剔除了汪洋底数码都想只要抽数据库文件,执行
VACUUM 命令。VACUUM
命令会清空“空闲列表”,把多少库尺寸缩到最小。注意, VACUUM
会耗费一些日(在 Linux
系统下约0.5秒/兆)并且使下有限倍于数据库文件大小的磁盘空间。

对于SQLite version 3.1, 替代VACUUM命令的一个办法是auto-vacuum模式,用
auto_vacuum
pragma
语法开启该模式。


(15) 是否能以 SQLite 用于商业用途而不要交版权费用?

可以。SQLite 是公开的
。代码的其它有都没有声明所有权。你可据此她来举行你想使的别样业务。


(16) 如何插入有单引号(’)的字符串?

采取对单引号即可,例如:

    INSERT INTO xyz VALUES('5 O''clock');

插入数据库的凡:5 0’clock。


(17) SQLITE_SCHEMA 错误代表什么?

于 SQLite 版本3受到,当一个先行处理 SQL 语句不合法不克履行时即会回到一个
SQLITE_SCHEMA 错误。当这荒唐产生时,该语句应当用
sqlite3_prepare()
API函数重新编译。在 SQLite 版本3挨,只有利用
sqlite3_prepare()
/sqlite3_step()
/sqlite3_finalize()
API函数执行 SQL 才见面生此似是而非,而使用
sqlite3_exec() .
则无见面。这和版本2不同。

大部来是荒唐的缘故是当 SQL
预处理完时数据库已经变更了(可能是给别一个经过改变的)。还可能发如下原因:

  • 本着一个数据库进行DETACH
    操作
  • 针对一个数据库进行VACUUM
    操作
  • 一个用户函数定义为去除或改动了。
  • 一个排序定义为删去或改了。
  • 一个授权函数改变了。

化解的方是重新编译并更尝试实行。所有涉及
sqlite3_prepare()
/sqlite3_step()
/sqlite3_finalize()
API 函数的还应更编译。参见下例:

    int rc;

sqlite3_stmt *pStmt;

char zSql[] = “SELECT …..”;

do {

/ Compile the statement from SQL. Assume success. /

sqlite3_prepare(pDb, zSql, -1, &pStmt, 0);

while( SQLITE_ROW==sqlite3_step(pStmt) ){

/ Do something with the row of available data /

}

/ Finalize the statement. If an SQLITE_SCHEMA error has

occured, then the above call to sqlite3_step() will have

returned SQLITE_ERROR. sqlite3_finalize() will return

** SQLITE_SCHEMA. In this case the loop will execute again.

/

rc = sqlite3_finalize(pStmt);

} while( rc==SQLITE_SCHEMA );


(18) 为什么ROUND(9.95,1) 返回 9.9 而无是 10.0? 难道9.95
不该提高进发位么?

SQLite 内部以二进制运算,9.95据此 64-bit IEEE 浮点数 ( SQLite
内部使用的)
表示也9.949999999999999289457264239899814128875732421875。所以当你输入
“9.95”时,SQLite
就知道为上述的数字,进而四放弃五可得9.9。这个题目在处理浮点二进制数总会来。通常的条条框框是十进制的少浮点数通常无法表示为二进制有限浮点数,只能出于最相仿的次上制数来代替。这个类似数会非常接近原数,但终归有细小的差,所以可能无法赢得你预期的结果。

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图