1.前言
本文使用"发现"二字,是表示我作为一个用过mysql oracle hive以及各种nosql数据库的男人,竟然发现有一个如此常识的数据库我竟然不知道。
在配置airflow的时候,我想当然的认为airflow的元数据应该储存在像是mysql类型的数据库中,我从来没有安装过sqlite,但是我直接初始化的airflow的时候,竟然初始化成功了,
并产生了airflow.db这个文件。
SQLite 是一个被大家低估的数据库,但有些人认为它是一个不适合生产环境使用的玩具数据库。事实上,SQLite 是一个非常可靠的数据库,它可以处理 TB 级的数据,但它没有网络层。
它“只是”一个库,它不是传统意义上的服务器。
那我开始了解一下,sqlite是最轻量级的数据库,或者可能连数据库都算不上。但是它又具备数据库的很多功能比如增删改查等等
small, fast, self-contained, high-reliability, full-featured
那我又有疑问sqlite和mysql等数据库的应用环境差异在哪里,其实官网早有解释
SQLite is not directly comparable to client/server SQL database engines such as MySQL, Oracle, PostgreSQL, or SQL Server since SQLite is trying to solve a different problem. Client/server SQL database engines strive to implement a shared repository of enterprise data. They emphasize scalability, concurrency, centralization, and control. SQLite strives to provide local data storage for individual applications and devices. SQLite emphasizes economy, efficiency, reliability, independence, and simplicity. SQLite does not compete with client/server databases. SQLite competes with fopen()
这一页官网有一句话还是单独拿出来以证明sqllte并不小:
SQLite数据库的大小限制为140 TB(2 47字节,128 TB)。即使可以处理更大的数据库,SQLite也会将整个数据库存储在单个磁盘文件中,而许多文件系统将文件的最大大小限制为小于此大小。
2.sqlite数据库基础概念
SQLite数据存储
1.SQlite 通过文件来保存数据库,一个文件就是一个数据库。
2.数据库里又包含数个表格;
3.每个表格里面包含了多个记录;
4.每个记录由多个字段组成;
5.每个字段都有其对应的值;
6.每个值都可以指定类型,并且指定约束。
SQLite数据类型
许多SQL数据库引擎(除SQLite之外的各种SQL数据库引擎)使用静态、严格的数据类型。对于静态类型,一个值的数据类型由它的容器,即存储这个值的列来决定。
SQLite则使用更加通用的动态类型系统。在SQLite中,一个值的数据类型被关联到这个值本身,而不是它的容器。
SQLite的动态类型系统向后兼容一般静态类型系统的数据库引擎。在某种意义上,工作在静态类型数据库上的SQL声明也同样能工作在SQLite上。但是SQLite动态类型还允许做一些在传统严格类型的数据库中不能做的事情。
共有15种:
- sqlite中支持如下的类型:
- smallint 短整型
- integer 整型
- real 实数型
- float 单精度浮点
- double 双精度浮点
- currency 长整型
- varchar 字符型
- text 字符串
- binary 二进制数据
- blob 二进制大对象
- boolean 布尔类型
- date 日期类型
- time 时间类型
- timestamp 时间戳类型
1、存储类别及数据类型
在SQLite数据库中存储(或被数据库引擎操作)的每个值,都属于下面存储类别之一:
* NULL: 值为一个NULL空值。 * INTEGER: 值被标识为整数,依据值的大小可以依次被存储为1,2,3,4,6或8个字节。 * REAL: 所有值都是浮点数值,被存储为8字节的IEEE浮点数。 * TEXT: 值为文本字符串,使用数据库编码存储,如UTF-8、UTF-16BE或UTF-16-LE。 * BLOB: 值是数据的二进制对象,如何输入就如何存储,不改变格式
注意一个存储类别比一个数据类型更通用。例如INTEGER存储类别就包括6个不同长度的整型数据类型,这在磁盘上是不同的。
不过只要INTEGER值从磁盘上读到内存中进行处理,它们会转换成最通用的数据类型(8字节的整型),因此在大多数情况下,对“存储类别”和“数据类型”并不做严格区分,这两个术语可交换使用。
在SQLite 3数据库中,除了INTEGER PRIMARY KEY这一列,任何列都可以存储任何类型的数据。
SQL语句中的所有值,不管是嵌入到SQL语句文本中的字面值还是绑定到预先编译好的SQL语句中的参数值,都有一个隐式存储类别。
在下述情况中,数据库引擎将在执行查询时,可以让存储的值在数值类型(INTEGER和REAL)和文本类型之间转换。
(1)Boolean数据类型
SQLite没有单独的布尔数据类型。相应的,布尔值被存储为整数0(false)和1(true)。
(2)日期和时间数据类型
SQLite没有单独的日期/时间数据类型。相应的,内建的日期和时间函数能够把日期和时间存储为文本、实数或整数值:
- 文本值为ISO8601字符串("YYYY-MM-DD HH:MM:SS.SSS")。
- 实数值为儒略日数,即从公元前4714年11月24日格林威治正午时刻开始的天数,按公历来算。
- 整数值为Unix时间,即从1970-01-01 00:00:00 UTC开始的秒数。
应用程序可以选择其中的一种格式来存储日期和时间,也可以通过内建的日期和时间函数在这些格式之间转换。
2、列的亲和类型
在SQLite 3中,值被定义为什么类型只和值自身有关,和列没有关系,和变量也没有关系(这有时被称作弱类型)
所有其它的我们所使用的数据库引擎都受静态类型系统的限制,其值的类型是由其所属列的属性决定的,而与值本身无关。
为了最大限度的增加SQLite数据库和其他数据库的兼容性,SQLite支持列的“亲和类型”概念。
列的亲和类型是指为该列所存储的数据建议一个类型,要注意这个类型是建议而不是强迫。
任何列依然是可以存储任何类型的数据的。只是针对某些列,如果有建议类型的话,数据库将优先按所建议的类型存储。这个被优先使用的数据类型称为“亲和类型”。
SQLite 3的每个列可以使用以下亲和类型中的一种:TEXT, NUMERIC, INTEGER, REAL, NONE。
带有文本亲和类型的列可以使用NULL, TEXT或BLOB类型来存储所有数据。如果数值数据被插入到这样的列中,会在存储之前转换成文本类型。
带有数值亲和类型的列可以使用所有五种类型来存储值。
当文本数据被插入到数据值型的列中时,如果转换是无损的且可逆的,则文本会被转换成INTEGER或REAL(按优先顺序)。
为了在TEXT和REAL之间转换,SQLite尝试无损且可逆地转换文本的开头15个有效十进制数字。如果不能成功转换的话,值则只能按文本类型存储了,而不会被转换成NULL类型或BLOB类型来存储。
带有小数点或指数记法的字符串可能看起来像一个浮点字面值,但只要值能表示为一个整数,数值亲和类型将把它转换成一个整数。因此,字符串'3.0e+5'会被转换成整数300000,而不是浮点数300000.0。
使用整数亲和类型的列,其行为与数值亲和类型的列一样。但也有些区别,比如没有小数部分的实数字面值被插入整数亲和类型的列时,它将被转换成整数并按整数类型存储。
使用实数亲和类型的列,其行为与数值亲和类型的列一样。有一个区别就是整数会强制用浮点数来表示。(作为一个内部优化,没有小数部分的小浮点数会当作整数写入磁盘,以占用更少的空间。
当读出这个值时会自动转换回浮点数。这个优化在SQL级别完全不可见,并且只有通过检测数据库文件的原始比特位才能发现)。
使用NONE亲和类型的列不会优先选择使用哪个类型,在数据被存储前也不会强迫转换它的类型。而是直接按它声明时的原始类型来存储。
(1)列亲和类型的确定
列的亲和类型由列的声明类型(在写SQL语句时指定)来确定,根据以下规则顺序来判断:
- 如果声明类型包含字符中"INT",则被定义为整数亲和类型。
- 如果列的声明类型包含字符串"CHAR", "CLOB"或"TEXT"中的某一个,则列具有文本亲和类型。注意VARCHAR类型包含字符串"CHAR",因此被定义为文本亲和类型。
- 如果列的声明类型包含字符串"BLOB",或者没有为列声明数据类型,则列具有NONE亲和类型。
- 如果列的声明类型包含字符串"REAL", "FLOA"或"DOUB"中的某一个,则列具有REAL亲和类型。
- 否则,列的亲和类型为NUMERIC。
注意确定列亲和类型的规则顺序非常重要。声明类型为"CHARINT"的列匹配规则1和2,但按顺序优先使用规则1,因此列被定义为整数亲和类型。
(2)亲和类型名称实例
按照上面5条规则,下面例子显示传统SQL实现中的各种通用数据类型(CREATE TABLE语句或CAST表达式中的数据类型)怎样被转化成SQLite中的亲和类型。
这里只是所有传统数据类型中的一部分,它们能够被SQLite接受。注意跟在类型名后面的括号中的数字参数在SQLite中被忽略。
SQLite不在字符串、BLOB对象或数值上强加任何长度限制(除了大的全局SQLITE_MAX_LENGTH限制)。
- INT, INTEGER, TINYINT, SMALLINT, MEDIUMINT, BIGINT, UNSIGNED BIG INT, INT2, INT8: 定义为INTEGER亲和类型(按规则1)。
- CHARACTER(20), VARCHAR(255), VARYING CHARACTER(255), NCHAR(255), NATIVE CHARACTER(70), NVARCHAR(100), TEXT, CLOB: 定义为TEXT亲和类型(按规则2)。
- BLOB, 不声明类型: 定义为NONE亲和类型(按规则3)。
- REAL, DOUBLE, DOUBLE PRECISION, FLOAT: 定义为REAL亲和类型(按规则4)。
- NUMERIC, DECIMAL(10,5), BOOLEAN, DATE, DATETIME: 定义为NUMERIC亲和类型(按规则5)。
注意声明类型"FLOATING POINT"将得到INTEGER亲和类型,而不是REAL亲和类型,因为"POINT"中有子串"INT"。声明类型"STRING"为NUMERIC亲和类型,而不是TEXT。
SQLite中的约束
- NOT NULL :非空
- UNIQUE : 唯一
- PRIMARY KEY :主键
- FOREIGN KEY : 外键
- CHECK :条件检查
- DEFAULT : 默认
3.增删改查
建表
create table 表名(参数名1 类型 修饰条件,参数名2,类型 修饰参数,···)
create table class(num integer PRIMARY KEY,name text NOT NULL DEFAULT "1班",count integer CHECK(count>10))
删表
删除一张表适用下面的语句:
drop table class
drop table 表名
添加数据
使用下面的语句来进行数据行的添加操作:
insert into class(num,name,count) values(2,"三年2班",58)
上面的语句代码可以简化成如下格式:
insert into 表名(键1,键2,···) values(值1,值2,···)
使用下面的语句进行数据列的添加,即添加一个新的键:
alter table class add new text
alter table 表名 add 键名 键类型
修改数据
使用如下语句来进行改操作:
update class set num=3,name="新的班级" where num=1
update 表名 set 键1=值1,键2=值2 where 条件
where后面添加修改数据的条件,例如上面代码修改num为1的班级的名字和mun值。
删除数据
delete from class where num=1
delete from 表名 where 条件
上面代码删除num为1的一条数据。
查询操作
查询操作是数据库的核心功能,sqlite的许多查询命令可以快捷的完成复杂的查询功能。
查询表中某些键值:
select num from class
select 键名,键名··· from 表名
查询全部键值数据:
select * from class
select * from 表名
*是一个全通配符,代表不限个数任意字符
查询排序:
select * from class order by count asc
select 键名,键名,··· from 表名 order by 键名 排序方式
order by 后面写要进行排序的键名,排序方式有 asc升序 desc降序
查找数据条数与查找位置限制:
select * from class limit 2 offset 0
select 键名 from 表名 limit 最大条数 offset 查询起始位置
条件查询:
select * from class where num>2
select 键名 from 表名 where 条件
查询数据条数:
select count(*) from class
select count(键名) from 表名
去重查询:
select distinct num from class
select distinct 键名 from 表名
来源:https://www.cnblogs.com/wqbin/p/11938592.html