SQLite 3.33.0 发布,新特性了解一下?

在这里插入图片描述


大家好,我是只谈技术不剪发的 Tony 老师。今天给大家带来一个关于 SQLite 嵌入式数据库的最新消息,SQLite 开发团队于 2020 年 8 月 14 日发布了 SQLite Release 3.33.0 版本。本文就来给大家分析一下这个版本中的一些新特性。

支持 UPDATE FROM 语句

UPDATE FROM 语句是针对 SQL 标准的一个扩展,允许使用其他表中的数据更新目标表。通过 UPDATE FROM 语句可以将目标表和数据库中的其他表进行连接,确定需要更新的数据行以及更新后的字段值。

SQLite 中的 UPDATE FROM 语句使用 PostgreSQL语法。假设有一个销售应用程序,SALES 表存储了产品每天的累积销售。在每天销售结束后,需要根据每天的销售情况更新 INVENTORY 库存表;为此,可以基于每天的累积销量更新 INVENTORY 表中的库存数量。例如:

UPDATE inventory
   SET quantity = quantity - daily.amt
  FROM (SELECT sum(quantity) AS amt, itemId FROM sales GROUP BY 2) AS daily
 WHERE inventory.itemId = daily.itemId;

FROM 子句中的子查询按照不同的 itemId 计算销售的数量,然后将它和 inventory 表进行连接并更新 inventory 表中的库存数量。

更新的目标表不在 FROM 子句中,除非是执行自连接查询。此时,FROM 子句中的表必须使用别名和目标表进行区分。

如果连接操作导致目标表中的同一数据行返回多行结果,只更新其中的随机一行结果。例如:

UPDATE department d
   SET d.manager = e.emp_id
  FROM (SELECT dept_id, emp_id FROM employee) AS e
 WHERE d.dept_id = e.dept_id;

一个部门可能存在多名员工,子查询 e 中的每个部门编号对应多个 emp_id,最终部门的 manager 可能是该部门中的任意员工。

数据库文件最大支持 281 TB

每个数据库由一个或多个数据页组成,一个数据库内的所有数据页大小都相同,但是不同的数据库可以使用不同的数据页大小,范围从 512 到 65536 字节。

从 SQLite 3.33.0 开始,一个数据库文件最多使用 4294967294 个数据页(由 max_page_count 编译指令决定),意味着最大支持约 2.8e+14 字节(281 TB)。

由于开发人员没有能够达到该限制的硬件,因此没有对这个上限进行测试。但是,测试验证了 SQLite 在数据库达到底层文件系统的最大文件大小(通常比该限制小得多)和磁盘空间耗尽而导致数据库无法增长时仍然能够正确且稳定地运行。

PRAGMA integrity_check 语句增强

PRAGMA integrity_check 语句现在可以选择性地针对单个表及其索引进行完整性检查,而不仅仅是针对整个数据库文件。

PRAGMA schema.integrity_check;
PRAGMA schema.integrity_check(N)
PRAGMA schema.integrity_check(TABLENAME)

默认情况下针对整个数据库文件进行检查。如果指定了 TABLENAME 参数,则只会针对该表和相关索引进行检查,也就是“部分完整性检查”。

由于只检查了数据库的部分内容,可能无法检测出某些错误,例如文件中存在的未使用部分,或者两个或多个表重复使用文件中的相同部分。只有当 TABLENAME 参数为 sqlite_schema 或者它的别名时,部分完整性检查才会验证 空闲列表(freelist)。

decimal 插件

新版本增加了 decimal 插件,支持任意精度的十进制算术运算。由于采用文本格式存储数字,因此可以保留任意精度,不需要进行近似运算。该插件包含了三个数学函数:

decimal_add(A,B)
decimal_sub(A,B)
decimal_mul(A,B)

它们分别用于计算参数相加、相减和相乘,返回一个字符串格式的结果。例如:

sqlite> select decimal_add(1, 0.23456789);
1.23456789
sqlite> select decimal_sub(1, 0.23456789);
0.76543211
sqlite> select decimal_mul(2, 0.23456789);
0.46913578

目前还没有提供除法运算函数。

函数 decimal_cmp(A,B) 可以用于比较两个数字值的大小,如果 A 小于、等于或者大于 B,分别返回一个负数、零或者正数。例如:

sqlite> select decimal_cmp(1, 2);
-1
sqlite> select decimal_cmp(2, 2);
0
sqlite> select decimal_cmp(3, 2);
1

函数 decimal_sum(X) 是一个类似于 sum() 的聚合函数,支持任意精度数字的计算。例如:

sqlite> WITH RECURSIVE generate_series(v) AS (
   ...>   SELECT 1
   ...>   UNION ALL
   ...>   SELECT v+1.0/3 FROM generate_series
   ...>   WHERE v+1.0/3<=10
   ...> )
   ...> SELECT decimal_sum(v)
   ...> FROM generate_series;
153.99999999999997

decimal 插件提供了“十进制”的排序规则,也就是按照数字顺序比较包含数字的文本字符串。

ieee754 插件增强

增强了 ieee754 插件,用于支持 IEEE 754 浮点数的 64 位二进制(binary64)格式和科学计数法( M × 2 E M×2^E M×2E )之间的转换:

F = M × 2 E F = M × 2^E F=M×2E

函数 ieee754(F) 接受一个浮点数的输入参数,返回一个如下所示的字符串:

'ieee754(M,E)'

其中,M 和 E 分别代表了浮点数的尾数和指数部分。例如:

sqlite> SELECT ieee754(47.49) AS x;
ieee754(6683623321994527,-47)

与此相反,函数 ieee754(M,E) 将一个使用尾数和指数表示的浮点数转换为十进制格式。例如:

sqlite> SELECT ieee754(6683623321994527,-47) as x;
47.49

函数 ieee754(F) 虽然方便阅读,但是不方便在表达式中使用。因此,增加了 ieee754_mantissa() 和 ieee754_exponent() 两个函数,分别用于返回浮点数的尾数和指数部分。例如:

sqlite> SELECT ieee754_mantissa(47.49) AS M, ieee754_exponent(47.49) AS E;
6683623321994527|-47

函数 ieee754_to_blob(F) 用于将浮点数转为为一个 8 字节 BLOB 数据,代表了该数字的 big-endian 模式的 binary64 编码。函数 ieee754_from_blob(B) 执行相反的转换。例如:

sqlite> SELECT quote(ieee754_to_blob(4.94065645841247e-324)) AS binary64;
X'0000000000000001'

sqlite> SELECT ieee754_from_blob(x'0000000000000001') AS F;
4.94065645841247e-324

命令行工具增强

SQLite 命令行工具(CLI)增加了 4 种输出模式:box、json、markdown 以及 table。例如:

sqlite> .mode box
sqlite> select 1 as val, 'sqlite' as str;
┌─────┬────────┐
│ val │  str   │
├─────┼────────┤
│ 1   │ sqlite │
└─────┴────────┘

sqlite> .mode json
sqlite> select 1 as val, 'sqlite' as str;
[{"val":1,"str":"sqlite"}]

sqlite> .mode markdown
sqlite> select 1 as val, 'sqlite' as str;
| val |  str   |
|-----|--------|
| 1   | sqlite |

sqlite> .mode table
sqlite> select 1 as val, 'sqlite' as str;
+-----+--------+
| val |  str   |
+-----+--------+
| 1   | sqlite |
+-----+--------+

column(以及 box、markdown、table)输出模式自动将字段的显示长度扩展为输出数据行的最大长度,并且自动打开 .headers 设置。

quote 输出模式支持 .separator"。例如:

sqlite> .mode quote
sqlite> select 1 as val, 'sqlite' as str;
'val','str'
1,'sqlite'

sqlite> .separator ":"
sqlite> select 1 as val, 'sqlite' as str;
'val':'str'
1:'sqlite'

CLI 默认支持 decimal 插件和 ieee754 插件。

查询计划改进

查询计划对于使用了 INDEXED BY 选项的 SQL 语句会显示 full-index-scan 信息,例如:

sqlite> create table t(id int, c1 int);
sqlite> create index idx_t_id on t(id);
sqlite> EXPLAIN QUERY PLAN select * from t indexed by idx_t_id;
QUERY PLAN
`--SCAN TABLE t USING INDEX idx_t_id

如果在之前的版本中执行以上命令,将会返回错误信息:

sqlite> EXPLAIN QUERY PLAN select * from t indexed by idx_t_id;
Error: no query solution

SQLite 可以更好地检测丢失的、不完整的和/或不可靠的 sqlite_stat1 统计数据,并且在存在错误信息能够生成良好的查询计划。

如果 t(x,y) 上存在索引,能够提高类似以下查询语句的性能:

SELECT min(x) FROM t WHERE y IN (?,?,?);

WAL 索引文件恢复

在预写式日志(WAL)模式下,如果写入器崩溃导致 shm 文件处于不一致状态,随后的事务可以恢复该 shm 文件,即使存在活动的读取事务。

在此之前,这种情况下恢复 shm 文件将会导致 SQLITE_PROTOCOL 错误。

总结

了解了这么多新特性,哪个是你最期待的功能?赶快点击下载最新版使用吧!

如果觉得文章对你有用,或者想要学习更多数据库相关的知识,欢迎关注❤️、评论

原文地址:https://tonydong.blog.csdn.net

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


SQLite架构简单,又有Json计算能力,有时会承担Json文件/RESTful的计算功能,但SQLite不能直接解析Json文件/RESTful,需要用Java代码硬写,或借助第三方类库,最后再拼成insert语句插入数据表,代码非常繁琐,这里就不展示了。参考前面的代码可知,入库的过程比较麻烦,不能只用SQL,还要借助Java或命令行。SPL是现代的数据计算语言,属于简化的面向对象的语言风格,有对象的概念,可以用点号访问属性并进行多步骤计算,但没有继承重载这些内容,不算彻底的面向对象语言。...
使用Python操作内置数据库SQLite以及MySQL数据库。
破解微信数据库密码,用python导出微信聊天记录
(Unity)SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。SQLite 源代码不受版权限制。本教程将告诉您如何使用 SQLite 编程,并让你迅速上手。.................................
安卓开发,利用SQLite实现登陆注册功能
相比大多数数据库而言,具有等优势,广泛应用于、等领域。
有时候,一个项目只有一个数据库,比如只有SQLite,或者MySQL数据库,那么我们只需要使用一个固定的数据库即可。但是一个项目如果写好了,有多个用户使用,但是多个用户使用不同的数据库,这个时候,我们就需要把软件设计成可以连接多个数据库的模式,用什么数据库,就配置什么数据库即可。4.Users实体类,这个实体类要和数据库一样的,形成一一对应的关系。11.Sqlite数据库,需要在代码里面创建数据库,建立表,再建立数据。8.我们开启MySQL数据库,然后进行调试,看程序的结果。2.安装SqlSugar。
基于Android的背单词软件,功能强大完整。
SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统。说白了就是使用起来轻便简单,
Android的简单购物车案例
SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库...
Qt设计较为美观好看的登录注册界面(包含SQLite数据库以及TCP通信的应用)
SQLite是用C语言开发的跨平台小型数据库,可嵌入其他开发语言,也可在单机执行。SPL是用Java开发的跨平台的数据计算语言,可嵌入Java,可在单机执行,可以数据计算服务的形式被远程调用。两者的代码都是解释执行的。...
新建库.openDATA_BASE;新建表createtableLIST_NAME(DATA);语法:NAME关键字...<用逗号分割>删除表droptableNAME;查看表.schema查看表信息新建数据insertintoLIST_NAMEvalues();语法:CLASS,PARAMETER...,CLASS是类别,PARAMETER是参数<用逗号分割新建的
importsqlite3classDemo01:def__init__(self):self.conn=sqlite3.connect("sql_demo_001.db")self.cursor1=self.conn.cursor()self.cursor1.execute("select*fromtable_001wherename=?andid=?",('ssss&#0
 在客户端配置文件<configuration>节点下,添加:<connectionStrings>      <add name="localdb" connectionString="Data Source=config/local.db;Version=3;UseUTF16Encoding=True;" providerName="System.Data.SQLite.SQLiteFactory"/&g
提到锁就不得不说到死锁的问题,而SQLite也可能出现死锁。下面举个例子:连接1:BEGIN(UNLOCKED)连接1:SELECT...(SHARED)连接1:INSERT...(RESERVED)连接2:BEGIN(UNLOCKED)连接2:SELECT...(SHARED)连接1:COMMIT(PENDING,尝试获取EXCLUSIVE锁,但还有SHARED锁未释放,返回SQLITE_BUSY)连接2:INSERT...
SQLite是一种嵌入式数据库,它的数据库就是一个文件。由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,甚至在iOS和Android的App中都可以集成。Python就内置了SQLite3,所以,在Python中使用SQLite,不需要安装任何东西,直接使用。在使用SQLite前,我们先要搞清楚几个概念:表
设计思想————首先要确定有几个页面、和每个页面的大致布局由于是入门,我也是学习了不是很长的时间,所以项目比较low。。。。第一个页面,也就是打开APP的首页面:今天这个博客,先实现添加功能!:首先对主界面进行布局:其中activity_main.xml的代码为<?xmlversion="1.0"encoding="