浅谈SQLite最新的SQL功能

sqlite 是一个被大家低估的数据库,但有些人认为它是一个不适合生产环境使用的玩具数据库。事实上,sqlite 是一个非常可靠的数据库,它可以处理 tb 级的数据,但它没有网络层。接下来,本文将与大家共同探讨 sqlite 在过去一年中最新的 sql 功能。
sqlite “只是”一个库,它不是传统意义上的服务器。因此,在某些场合下,它确实不合适。但是,在相当多的其他场合,它却是最合适的选择。sqlite 号称是部署和使用最广泛的数据库引擎。我认为这很有可能,因为 sqlite 没有版权的限制。无论何时,只要开发者想使用 sql 在文件中存储结构化的数据,sqlite 应是首选方案。
sqlite 的 sql 方言也非常强大。它比 mysql 早四年就开始支持 with 语句。最近,它还实现了对于窗口函数的支持,这仅仅比 mysql 晚五个月。
接下来,本文将介绍 sqlite 在 2018 年新增加的 sql 功能,也就是 sqlite 从版本 3.22.0 到 3.26.0 所新增加的 sql 功能。
具体内容包括:
布尔字面量和判断 窗口函数 filter子句 insert … on conflict (“upsert”) 重命名列 在modern-sql.com上接下来 布尔变量和判断
sqlite支持“假”布尔值:它接受boolean作为类型的名称,但它将其当作整数看待(这一点非常类似于mysql)。真值true和false分别由数值1和0表示(这一点和c语言一样)。
从版本3.23.0开始,sqlite将关键字true和false分别用数字1和0表示,并支持is [not] true | false的判断语句。现在,它不再支持关键字unknown。开发者可以使用空值null来代替,因为unknown和null的布尔值是一样的。
在insert和update语句中,字面量true和false可以大大提高values和set子句的可读性。
is [not] true | false这个判断语句很有用,它与比较操作的含义不一样:
我们来比较一下
where c  false  和
where c is not false 在上面的例子中,如果c是null, 那么c false的结果是unknown.
这是因为where子句只接受结果为true的值,它会过滤掉结果为false或unknown的值。这样,它就会把对应的行从结果中去掉。
与此相对应,如果c是null,那么,c is not false的判断结果是true。因此,第二个where子句也将包含c是null的行。
要达到同样的效果,您可以采用的另外一种方法是增加单独处理null值的子句。也就是使用语句:
where c  false   or c is null 这种形式的语句更长并且有一些冗余语句(c被使用了两次)。长话短说,可以使用is not false判断来替代这个or…is-null的语句。更详细的内容,请参考“binary decisions based on three-valued results”。
sqlite中对布尔字面量和布尔判断的支持现在和其他开源数据库接近,唯一的差距是sqlite不支持is[not] unknown(你可以使用is [not] null来代替)。有趣的是,这些功能在下面提到的商用产品中还不可用。
图片 0:只支持true,false.不支持notknown,如果需要,用null代替   1:不支持is [not] unknown,如果需要,用is [not] null代替 窗口函数
sqlite 3.25.0引入了窗口函数。如果你知道窗口函数,那么也知道这是一件大事。如果你不了解窗口功能,请你自己学习如何使用。这篇文章不会具体解释窗口函数,但请相信:它是最重要的“现代”sql特性。
sqlite对over子句的支持与其他数据库非常接近。唯一值得注意的限制是range语句不支持数字或间隔距离(仅支持current row和unbounded preceding|following)。在发布sqlite 3.25.0时,sql server和postgresql具有同样的限制。postgresql 11消除了这一限制。
图片 0:没有变化   1:range范围定义不支持datetime类型   2:range范围不接受关键字 (只支持unbounded和current row) sqlite对于窗口函数的支持在业界是领先的。它不支持的功能在其他一些主要产品中也同样不支持(在聚合中语句中的distinct,width_bucket, respect|ignore nulls和from first|last等语句)。
0:同样没有order by 语句   1:不允许负偏移量,nulls的特定处理:lead(, 'ignore nulls'),这里是字符串参数 2:没有缺省值(第三个参数),不支持respect|ignore nulls语句   3:不允许负偏移量,不支持ignore nulls语句   4:不允许负偏移量   5:不支持respect|ignore nulls语句   6:不允许负偏移量,不支持respect|ignore nulls语句   7:nulls的特定处理:first_value(, 1, null, 'ignore nulls') ,这里是字符串参数。 8:不支持ignore nulls语句 9:不支持ignore nulls语句和from last语句微信搜索公众号:java项目精选,回复:java 领取资料 。 过滤语句
虽然filter语句只是语法糖——你也可以很容易地使用表达式来获得相同的结果——我认为它也是必不可少的语法糖,因为它能使人们更加容易地学习和理解sql语句。
看看下面的select子句,您觉得哪一个更容易理解?
select sum(revenue) total_revenue     , sum(case when product = 1                 then revenue            end          ) prod1_revenue   ... 和
select sum(revenue) total_revenue     , sum(revenue) filter(where product = 1) prod1_revenue   ... 此示例很好地总结了filter子句的作用:它是聚合函数的后缀,可以在进行聚合之前根据特定条件,过滤掉相应的行。pivot技术是filter子句最常见的用例。这包括将实体属性值(eav)模型中的属性转换为表格的列,如果想了解更多的内容,可以参考链接“filter-selective aggregates”(https://modern-sql.com/feature/filter)。
sqlite 从版本3.25.0开始,在使用over子句的聚合函数中支持了filter子句,但是在使用group by子句的聚合函数中还不支持。不幸的是,这意味着您仍然无法在sqlite中使用filter语句来处理上述情况。你必须像以前一样使用case表达式。我真的希望sqlite在这一点上能尽快做到。
图片 insert … on conflict (“upsert”)
sqlite 从版本3.24.0开始,引入了“upsert”概念:它是一个insert语句,可以优雅地处理主键和唯一约束的冲突。您可以选择忽略这些冲突(在on conflict语句中什么都不做)或者更新当前行(在on conflict语句中执行更新操作)。
这是一个特有的sql扩展,即它不是标准sql的一部分,因此在下面的矩阵中是灰色的。但是,sqlite遵守与postgresql相同的语法来实现此功能0。该标准提供了对merge语句的支持。
与postgresql不同,sqlite在以下语句中存在问题。
insert into targetselect *  from source    on conflict (id)    do update set val = excluded.val 根据说明文档,这是因为解析器无法判断关键字on是select语句的连接约束还是upsert子句的开头。你可以通过向查询中添加子句来解决,例如where true。
insert into targetselect *  from source where true    on conflict (id)    do update set val = excluded.val 图片 0:同样记录insert、update、delete和merge操作的错误信息 (“dml error logging”)
1:on conflict语句不能紧挨查询的from语句,如果需要,可以添加  where true语句来分隔。
重命名列
sqlite引入的另一个特有功能是重命名基准数据库表中的列1。标准的sql不支持此类功能2。
sqlite遵循其他产品常用的语法来重命名列:
alter table … rename column … to
图片 0:请查阅 sp_rename.
其他消息
在2018年,sqlite除了在sql语法上的变化,还有一些应用程序接口(api)的变化。你可以查阅sqlite.com(https://www.sqlite.org/news.html)上的新闻部分来了解更详细的消息。
脚标:


小米6什么时候上市?小米6最新消息汇总
嫦娥五号将在一周内完成大量重要的动作
电动车低于50%的时候就开始极速掉电了,这是怎么回事呢?
RF在PCB设计中的相关标准介绍
饮料瓶旋转视觉定位贴标,它的工作流程是怎样的
浅谈SQLite最新的SQL功能
自动驾驶汽车会让交通变得更糟吗?
电动汽车和插电混动汽车哪个更适合居家使用
创维电视推出顶级游戏装备S81 Pro,HDMI外接游戏主机和手机投屏
Microchip新推出一系列SiC功率器件 具有良好耐用性以及宽带隙技术优势
共话5G未来,美格智能携多款新品亮相2023MWC上海世界移动通信大会
窄脉冲时域反射仪采集和存储系统的硬件设计和实现
再次挑战iPhone!华为发布P10和P10 Plus双摄智能手机!
电力负荷与电量的关系解析
Bourns新型ChipLAN Base-T变压器上市,更灵活的设计
定量医学成像技术将是医疗行业的发展方向
亮锐LUXEON C 彩色系列LEDs将可达成完美彩色混光
CAN转PROFIBUS协议转换器在风力发电中的应用
MEMS陀螺仪用在哪里?
华为已在英国伦敦设立5G研发基地 寻求与当地企业共同推进研发工作