sqliteSQLite FAQ中文版

  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 的字段将电动增加。

此处是事无巨细的答案: 从 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错误码.


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

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


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

当即是一个功效,不是一个
bug。你可在其它字段中放任何音讯,而非用无配段声明为什么类型。
你可通往整型字段中插任意长度的字符串,或者向布尔字段中插入浮点数,或者朝字符字段中
插入日期。在 CREATE TABLE
命令中若指定给这个字段的数据类型不见面限制插入这个字段的数。
所有的字段可以插任意长度的字符串。但于 INTEGER PRIMARY KEY
字段例外。这种字段只能 存放一个64个之整数,否则会拧。

然SQLite会默认你想采取声明的字段类型。所以,比如您期望于一个宣称也INTEGER的字段
中插入一个字符串,SQLite会试图以该转移为一个平头。如果换成,那么整数将吃插入,否
则插入字符串,这种特征有时被名type or column
affinity .


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

每当 2.7.0 之后,表达式不成立。参见文档 datatypes in SQLite version
3


(5) 为什么 SQLite 不容许以平等张表里使用 ‘0’ 和 ‘0.0’
作为少数独例外之实施之主键?

若的主键一定是数值类的,把品种变更吧 TEXT 就好了。

每一行要产生一个唯一的主键。作为一个数字型的字段,SQLite 认为
‘0’‘0.0’ 的值是同的,
因为他们在数字上之比是相等的(看前面的问题)因此值未是绝无仅有的。


(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
    操作
  • 一个用户函数定义为去除或改动了。
  • 一个排序定义为删或转移了。
  • 一个授权函数改变了。

缓解之措施是又编译并再尝试实行。所有sqlite涉及
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地图