SQLite常见问题解答(1)

Frequently Asked Questions

  1. 如何建立自动增长字段?
  2. SQLite支持何种数据类型?
  3. SQLite允许向一个integer型字段中插入字符串!
  4. 为什么SQLite不允许在同一个表不同的两行上使用0和0.0作主键?
  5. 多个应用程序或一个应用程序的多个实例可以同时访问同一个数据库文件吗?
  6. SQLite线程安全吗?
  7. 在SQLite数据库中如何列出所有的表和索引?
  8. SQLite数据库有已知的大小限制吗?
  9. 在SQLite中,VARCHAR字段最长是多少?
  10. SQLite支持二进制大对象吗?
  11. 在SQLite中,如何在一个表上添加或删除一列?
  12. 我在数据库中删除了很多数据,但数据库文件没有变小,是Bug吗?
  13. 我可以在商业产品中使用SQLite而不需支付许可费用吗?
  14. 如何在字符串中使用单引号(')?
  15. SQLITE_SCHEMA error是什么错误?为什么会出现该错误?
  16. 为什么 ROUND(9.95,1) 返回 9.9 而不是 10.0? 9.95不应该圆整(四舍五入)吗?

(1) 如何建立自动增长字段?

简短回答:声明为 INTEGER PRIMARY KEY 的列将会自动增长。

长一点的答案: 如果你声明表的一列为 INTEGER PRIMARY KEY,那么, 每当你在该列上插入一NULL值时, NULL自动被转换为一个比该列中最大值大1的一个整数,如果表是空的, 将会是1。 (如果是最大可能的主键 9223372036854775807,那个,将键值将是随机未使用的数。) 如,有下列表:

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允许向一个integer型字段中插入字符串!

这是一个特性,而不是一个bug。SQLite不强制数据类型约束。 任何数据都可以插入任何列。你可以向一个整型列中插入任意长度的字符串, 向布尔型列中插入浮点数,或者向字符型列中插入日期型值。 在 CREATE TABLE 中所指定的数据类型不会限制在该列中插入任何数据。 任何列均可接受任意长度的字符串(只有一种情况除外: 标志为INTEGER PRIMARY KEY的列只能存储64位整数, 当向这种列中插数据除整数以外的数据时,将会产生错误。

但SQLite确实使用声明的列类型来指示你所期望的格式。所以, 例如你向一个整型列中插入字符串时,SQLite会试图将该字符串转换成一个整数。 如果可以转换,它将插入该整数;否则,将插入字符串。 这种特性有时被称为 类型或列亲和性(type or column affinity).


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

主键必须是数值类型,将主键改为TEXT型将不起作用。

每一行必须有一个唯一的主键。对于一个数值型列, SQLite认为 '0''0.0' 是相同的, 因为他们在作为整数比较时是相等的(参见上一问题)。 所以,这样值就不唯一了。


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

多个进程可同时打开同一个数据库。多个进程可以同时进行SELECT 操作,但在任一时刻,只能有一个进程对数据库进行更改。

SQLite使用读、写锁控制对数据库的访问。(在Win95/98/ME等不支持读、 写锁的系统下,使用一个概率性的模拟来代替。)但使用时要注意: 如果数据库文件存放于一个NFS文件系统上,这种锁机制可能不能正常工作。 这是因为 fcntl() 文件锁在很多NFS上没有正确的实现。 在可能有多个进程同时访问数据库的时候,应该避免将数据库文件放到NFS上。 在Windows上,Microsoft的文档中说:如果使用 FAT 文件系统而没有运行 share.exe 守护进程,那么锁可能是不能正常使用的。那些在Windows上有很多经验的人告诉我: 对于网络文件,文件锁的实现有好多Bug,是靠不住的。如果他们说的是对的, 那么在两台或多台Windows机器间共享数据库可能会引起不期望的问题。

我们意识到,没有其它嵌入式的 SQL 数据库引擎能象 SQLite 这样处理如此多的并发。SQLite允许多个进程同时打开一个数据库, 同时读一个数据库。当有任何进程想要写时,它必须在更新过程中锁住数据库文件。 但那通常只是几毫秒的时间。其它进程只需等待写进程干完活结束。 典型地,其它嵌入式的SQL数据库引擎同时只允许一个进程连接到数据库。

但是,Client/Server数据库引擎(如 PostgreSQL, MySQL, 或 Oracle) 通常支持更高级别的并发,并且允许多个进程同时写同一个数据库。 这种机制在Client/Server结构的数据库上是可能的, 因为总是有一个单一的服务器进程很好地控制、协调对数据库的访问。 如果你的应用程序需要很多的并发,那么你应该考虑使用一个Client/Server 结构的数据库。但经验表明,很多应用程序需要的并发,往往比其设计者所想象的少得多。

当SQLite试图访问一个被其它进程锁住的文件时,缺省的行为是返回 SQLITE_BUSY。 可以在C代码中使用 sqlite3_busy_handler()sqlite3_busy_timeout() API 函数调整这一行为。

 
目录 sqlite_array_query —— 发送一条 SQL 查询,并返回一个数组。 sqlite_busy_timeout —— 设置超时时间(busy timeout duration),或者频繁的用户失去权限(disable busy handlers)。 sqlite_changes —— 返回被最新的SQL 查询(changed by the most recent SQL statement)改变的行数。 sqlite_close —— 关闭一个打开的SQLite数据库sqlite_column —— 在当前的行中取得一列(a column from the current row of a result set)。 sqlite_create_aggregate —— Register an aggregating UDF for use in SQL statements。 sqlite_create_function —— Registers a "regular" User Defined Function for use in SQL statements。 sqlite_current —— 在返回的数组中取得当前的行(the current row from a result set as an array)。 sqlite_error_string —— 返回错误代码的原始描述(the textual description of an error code)。 sqlite_escape_string —— 释放一个用于查询的字符串(Escapes a string for use as a query parameter)。 sqlite_fetch_array —— 取得下一行并设置成一个数组(the next row from a result set as an array)。 sqlite_fetch_single —— 取得第一列并设置成一个字符串(Fetches the first column of a result set as a string)。 sqlite_fetch_string —— sqlite_fetch_single()的别名。 sqlite_field_name —— 取得结果中指定字段的字段名。 sqlite_has_more —— 返回是否有更多可用的行(whether or not more rows are available)。 sqlite_last_error —— 返回数据库的最新的错误代码(the error code of the last error for a database)。 sqlite_last_insert_rowid —— 返回最新插入的行的行号(the most recently inserted row)。 sqlite_libencoding —— 返回SQLite库(SQLite library)的编码(encoding)。 sqlite_libversion —— 返回SQLite库(SQLite library)的版本。 sqlite_next —— 返回下一行的行号。 sqlite_num_fields —— 取得结果集中字段的数目。 sqlite_num_rows —— 取得结果集中行的数目。 sqlite_open —— 打开一个SQLite数据库。如果文件不存在则尝试创建之。 sqlite_popen —— 用永久连接的方式打开一个SQLite数据库。如果文件不存在则尝试创建之。 sqlite_query —— 发送一条 SQL 查询,并返回一个结果句柄(a result handle)。 sqlite_rewind —— 倒回第一行(Seek to the first row number)。 sqlite_seek —— 在缓存结果中查找特定的行号(Seek to a particular row number of a buffered result set)。 sqlite_udf_decode_binary —— Decode binary data passed as parameters to an UDF。 sqlite_udf_encode_binary —— Encode binary data before returning it from an UDF。 sqlite_unbuffered_query —— 发送一条 SQL 查询,并不获取和缓存结果的行。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值