sqlite和其他大部分现代sql数据库在基本设计目标上是不同的,它的目标是简单。sqlite遵循这一目标,即使这样偶尔会导致某些特性实现的低效化。下面列举了sqlite的一些缺陷:
sql-92特性方面
正如前面提到的,sqlite不支持sql-92的在很多企业数据库系统中可用的一些特性。
如:
外键约束(可解析的,但非强制)
很多ALTER TABLE特性
一些TRIGGER相关的特性
RIGHT和FULL OUTER JOIN
更新一个VIEW
GRANT和REVOKE
你可以在sqlite的主页上获取最新信息。
http://www.sqlite.org/omitted.html
http://www.sqlite.org/cvstrac/wiki?p=UnsupportedSql
低并发操作
sqlite只支持平面事务;它没有嵌套和营救点能力。嵌套意味着在一个事务中可以有子事务的能力。营救点允许一个事务返回到前面已经到达的状态。它没有能力确保高层次事务的并发。它允许在单个的数据库文件上多个并发的读事务,但是只能有一个排他的写事务。这个局限性意味着如果有事务在读数据库文件的一部分,所有其他的事务将被禁止写该文件的任何一部分。类似的,如果有事务在写数据库文件的一部分,所有其他事务将被禁止读或者写该文件的任何一部分。
应用限制
因为它事务处理的有限并发,sqlite只擅长处理小型的事务。在很多情况下,这不是问题。每个应用迅速的完成它的数据库工作然后继续前进,因此没有一个事务会持有数据库超过多少毫秒。但是在一些应用中,特别是写入密集的,要求更多的并发的事务处理(表或者行级别的而不是数据库级别的)那么你将要为该应用使用其他不同的DBMS。sqlite并不打算成为一个企业DBMS。他最适合于实现,维护和管理的简单性比商业数据库的无尽复杂特性更为重要的情况。
NFS问题
sqlite使用本地文件锁原语来控制事务处理的并发性。如果数据库文件驻留在网络分区上,可能会导致文件锁不能工作。很多的NFS实现被认为在它们的文件锁中是有bug的(在Unix和Windows上)。如果文件锁不能像预计的一样工作,那么就可能会有两个或两个以上的应用程序在同时修改相同数据库的同一部分,导致了数据库的毁坏。因为这个问题的出现是因为位于下层的文件系统的实现的BUG,所以sqlite没有办法阻止它的发生。
另一原因是大多数网络文件系统的连接延时,效果不是很好。在这种环境下,在数据库文件必须要跨网络访问的情况下,实现了客户端-服务器的模型的DBMS会比sqlite更有效。
数据库规模
因为它的开发人员的开发设计选择,sqlite可能不是一个做非常大型的数据库好选择。在理论上,一个数据库文件文件可以有2TB(241)。日志子系统的内存开销和数据库大小是成比例的。对每个写事务,无论事务实际是写是读那个页,sqlite为每个数据库页维护一个内存内信息位。默认的页大小是1024字节。即使如此,对一个有超过几百万页的数据库,内存开销可能成为一个严重的瓶颈。
对象的数目和类型
一个表或者索引被限制为最多有264 – 1个项。当然,你不可能有这么多的条目,因为数据库的241字节大小限制。在sqlite的当前的实现中,一个单独的条目能够持有230字节的数据。(下层的文件格式支持行大小相当于262字节的数据。)在打开一个数据库文件时,sqlite会阅读并且预处理来自主目录表的所有条目并且创建很多内存目录对象。所以,为了最好的性能,最好控制表,索引,视图和触发器的数目。同样虽然没有限制表中列的数目,超过几百列还是似乎太过的。只有表开始的31列是候选为必然被优化的。你能够在一个索引中尽可能加入列,但是有超过30列的索引将不会被用来优化。
宿主变量引用
在一些嵌入DBMS中,sql语句能够直接引用宿主变量(即来自应用程序空间的那些值)。在sqlite中这是不行的。作为替代sqlite允许使用sqlite3_bind_* API函数来对输入参数而不是输出值绑定对sql语句宿主变量。这种策略通常比直接的访问策略更好,因为后者需要特殊的预处理来将sql语句转化为特殊的API调用。
存储过程
很多DBMS有被称为存储过程的能力来创建和存储。存储过程是形成逻辑作业单元和执行特殊任务的一组sql语句。SQL查询过程能够使用这些过程。sqlite没有这个能力。
另外一些局限
不支持外键
如果你的表格中有类似的语句,sqlite会忽略的:
create table zope_suf.userroles (
name varchar(64) not null references zope_suf.users(name)
...
上面的外键refernces约束是不支持的,如果要支持,需要手工写trigger。
参考:http://www.sqlite.org/cvstrac/wiki?p=ForeignKeyTriggers
Client/Server应用
sqlite是没有Server的,当然更适合做web应用一些。如果做C/S则需要通过文件共享来访问数据库,这个性能就差了;而且可能有写冲突。
高访问量的网站
sqlite不可能把数据库对象分别部属在不同的计算机上,也就是说不可能实现数据库的clusting。如果要有这个特性,需要考虑其他C/S架构的数据库。
非常大的数据集
在处理事务中,sqlite会在内存中分配一个脏页面表: 每1M的数据库会耗用256Byte 的内存。如果你的数据库修改达到数G,这个内存耗用会非常大。
如果数据的修改和存储超过数十G(应该不会),你应该考虑其他的数据库。
高并行