常见的关系型数据库有SQLite,MySQL,SQL Server等,通常学习关系型数据库时不会使用SQLite,但是SQLite 是世界上使用最广泛的数据库引擎。SQLite 内置于所有手机和大多数计算机中,并捆绑在人们每天使用的无数其他应用程序中。SQLite 是一个由C语音开发的嵌入式库,具有小型、 快速、 自包含、 高可靠、 功能齐全等特点。
文章以3.32.2
版本为例讲述SQLite的一些基本知识
在命令行中使用SQLite命令,需要先执行sqlite3
命令,进入SQLite提示符
。
有两种方法可以创建或打开数据库,一个是在sqlite3
命令后面加上数据库路径,另一个是使用点命令.open
通过执行这个命令进入SQLite提示符
时,如果数据库文件已经存在,则直接打开对应数据库,否则不会立即在对应路径创建xxx.db文件。要等到执行了添加数据表,视图等数据库对象的命令之后。
示例
先执行如下命令,此时没有创建出comms_ease.db
文件
sqlite3 comms_ease.db
再执行如下命令创建一张表,在当前目录出现comms_ease.db
文件
使用.open
是一个点命令,使用它需要先执行sqlite3
命令进入SQLite提示符
。.open
命令的使用方式也是在命令后面追加数据库路径,不过和sqlite3 /.../xxx.db法
不同的是,执行.open
命令后,数据库文件会被直接创建出来,不需要再创建数据库对象。
SQLite的创建语句为CREATE TABLE,完整的创建表语句内容丰富,除了创建普通表外,还能具备判断表是否已经存在,创建临时表等能力。常见的创建普通表的句式为。
CREATE TABLE 表名 (
列1名称 列类型 以空格隔开的一个或多个列约束,
列2名称 列类型 以空格隔开的一个或多个列约束,
...
);
默认情况下,一张表的最大列数为2000,每一行能存下的最大字节数为十亿,能满足绝大多数的需求,创建普通表的示例如下
CREATE TABLE table_comms_ease (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
value VARCHAR
);
例子中,创建了一个名为table_comms_ease
的数据表,包含两列,第一列是id
,类型是整形,不能为空,而且是表的主键,并可以自动生成; 第二列是value
,类型为字符串
在表名已经存在的情况下,调用CREATE TABLE 表名
语句会报错,要避免,可以使用CREATE TABLE IF NOT EXISTS 表名
语句。如果不存在,则创建表,如果存在,则什么都不做。示例如下
CREATE TABLE IF NOT EXISTS table_comms_ease (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
value VARCHAR
);
如果希望临时存储一些数据,而且只对当前连接有效,可以试试临时表。临时表的创建语句为CREATE TEMP TABLE
。临时表只对当前数据库连接有效,重新建立连接或者同时存在的其他连接都无法访问到。示例如下
CREATE TEMP TABLE temp_table_comms_ease (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
value VARCHAR
);
点命令是SQLite
数据库独特的命令形式,它们通常比较简单,而且不需要以分号结尾,常见的点命令如下表所示
命令 | 描述 | 使用示例 |
---|---|---|
.backup | 备份数据库到文件 | .backup comms_ease_backup |
.databases | 列出数据库的名称及其所依附的文件 | .databases |
.exit | 退出SQLite提示符 |
.exit |
.help | 帮助 | .help |
.quit | 退出SQLite提示符 |
.quit |
.show | 各种设置的值 | .show |
.schema | 查看创建命令。以LIKE`的模式匹配参数,如果没有参数,则查看所有表格的创建命令 | .schema .schema table% |
.tables | 搜索表名。以LIKE`的模式匹配参数,如果没有参数,则搜索所有表名(临时表不会出现在结果中) | .tables .tables table% |
向表内添加一行,即为每一列构建一个值,并填入新的一行中。添加行的命令是INSERT,添加方式有三种,一种是指定值添加;二是添加Select语句的结果;三是默认添加。
指定值添加就是指定部分或者所有列的值,剩下列使用默认值的方式,对于没有通过DEFAULTE
,AUTOINCREMENT
等方式声明默认值的列,如果没有指定NOT NULL
则填入NULL
,否则报错。至少需要指定一列的值,如需全部填写默认值,可以使用默认添加
方式。需要注意的是,值的顺序要和列的顺序保持一致。示例如下:
INSERT INTO table_comms_ease (value) VALUES ('value of 1');
INSERT INTO table_comms_ease (value, id) VALUES ('value of 2', 2);
如果需要指定填入所有列的值,也可以不把列名列举出来,将值按创建表时各个列的顺序列举出来即可。示例如下:
INSERT INTO table_comms_ease VALUES (3, 'value of 3');
通过添加加Select语句的结果添加一行的格式为INSERT INTO 表名 SELECT ...
通过此方法添加一行时,默认值不会被自动填充,SELECT语句查出的数据量必须和表的列数一致。假设已经存在表operator
包含列key
和description
而且某一行的key
为’.backup’,description
为备份数据库到文件
,给出示例如下:
INSERT INTO table_comms_ease SELECT 4, description FROM operator WHERE key IS '.backup';
默认添加的格式为INSERT INTO 表名 DEFAULT VALUES;
为每一列都填入默认值,如果没有特别声明默认值,则填入NULL。示例如下:
INSERT INTO table_comms_ease DEFAULT VALUES;
通过创建表章节的示例语句创建出数据表,再依次调用上述示例语句,则数据表内会出现5行数据,如下
id | value |
---|---|
1 | value of 1 |
2 | value of 2 |
3 | value of 3 |
4 | 备份数据库到文件 |
5 |
删除表内的一行,命令是DELETE,常用格式为
DELETE FROM 表名 WHERE 过滤语句
删除命令本身比较简单,指定表名和删除条件即可删除一列,如下示例表示如果value
列中的值有value of
开头,则删除。
DELETE FROM table_comms_ease WHERE value LIKE 'value of %';
如上命令操作后,table_comms_ease
表还剩的数据为
id | value |
---|---|
4 | 备份数据库到文件 |
5 |
修改表内数据的命令为UPDATE,其常用格式为
UPDATE 表名 SET 一个或多个列的赋值 WHERE 过滤语句
修改多列内容时可以采用先写出列名,再按顺序赋值的方式,也可以采用一列一列修改的方式。如果要更新id为4的所在行的值,设置id
为123
,value
为new value
,两种修改方式分别如下
UPDATE table_comms_ease SET (id, value)= (123, 'new value') WHERE id = 4;
或者
UPDATE table_comms_ease SET id=123, value='new value' WHERE id = 4;
修改后,table_comms_ease
表中的数据为
id | value |
---|---|
5 | |
123 | new value |
修改单列的方法和修改多列的方法相似,比如将id
为5这一行的value
也修改为new value
,可以如下操作
UPDATE table_comms_ease SET (value)=('new value') WHERE id = 5;
或者
UPDATE table_comms_ease SET value='new value' WHERE id = 5;
修改后,table_comms_ease
表中的数据为
id | value |
---|---|
5 | new value |
123 | new value |
查询语句的命令是SELECT,它不会修改数据库,结果的行数在自然数范围内,每一行代表一个查询结果。SELECT
命令的常用格式为
SELECT 去重策略 列名列表 FROM 表名或者子查询语句 WHERE 过滤语句 ORDER BY 排序策略 LIMIT 数量限制
查询语句中可用的配置比较多,但是大都不是必须的。查询table_comms_ease
表的所有内容只需要如下命令即可
SELECT * FROM table_comms_ease;
上面命令中的*
表示所有列,命令相当于
SELECT id,value FROM table_comms_ease;
结果为
id | value |
---|---|
5 | new value |
123 | new value |
另外,可以通过VALUES
语句构建一个查询结果,结果的列名为column1
, column2
, column3
等等。比如
VALUES (1,2,3),('a','b','c');
的结果为
column1 | column2 | Column3 |
---|---|---|
1 | 2 | 3 |
a | b | c |
去重策略有两种,一种是默认策略ALL
,代表不去重;另一种是DISTINCT
,代表去重。table_comms_ease
表中value
列的值相同,使用ALL
和DISTINCT
分别查询value列时,命令和结果如下:
ALL命令
SELECT ALL * FROM table_comms_ease;
结果为
value |
---|
new value |
new value |
DISTINCT命令
SELECT DISTINCT value FROM table_comms_ease;
结果为
value |
---|
new value |
可以看出在有重复结果时,ALL策略会保留所有结果,而DISTINCT策略只保留其中一个
查询语句的FROM
关键字后面可以跟表名或者子查询语句,用于限制查询范围。当填写表名时,可以填写多个表名,用逗号或者连接运算符分隔。当填写查询语句时,可以视为先查询出一张表,再从此表中查询出数据。
假设还有一张表table_comms_ease_1
,列信息和table_comms_ease
表相同,值为
id | value |
---|---|
1 | value of 1 in table_comms_ease_1 |
2 | value of 2 in table_comms_ease_1 |
则此字段填写table_comms_ease,table_comms_ease_1
时得到如下命令
SELECT * FROM table_comms_ease, table_comms_ease_1;
结果为
table_comms_ease.id | table_comms_ease.value | table_comms_ease_1.id | table_comms_ease_id.value |
---|---|---|---|
5 | new value | 1 | value of 1 in table_comms_ease_1 |
5 | new value | 2 | value of 2 in table_comms_ease_1 |
123 | new value | 1 | value of 1 in table_comms_ease_1 |
123 | new value | 2 | value of 2 in table_comms_ease_1 |
当此字段填写两个子查询语句,如一个是id为5,另一个是id为123时,则得到如下命令
SELECT * FROM (SELECT * FROM table_comms_ease WHERE iD=5), (SELECT * FROM table_comms_ease WHERE iD=123);
结果为
table_comms_ease.id | table_comms_ease.value | table_comms_ease.id | table_comms_ease.value |
---|---|---|---|
5 | new value | 123 | new value |
将子查询语句的结果视为一张表,则可以统一对两种填写格式的理解。另外查询命令也支持混合填写表名和查询语句。
排序条件决定了结果的排列顺序,常用格式如下
ORDER BY 列名 COLLATE 比较方式 排序方式 NULL值的排序方式
比较方式有三种,分别为BINARY
, NOCASE
和 RTRIM
通过下面命令为表table_comms_ease
添加几条数据,
INSERT INTO table_comms_ease VALUES (6, 'A'), (7, 'new value '), (8, 'Z');
则表中的数据变为
id | value |
---|---|
5 | new value |
6 | A |
7 | new value |
8 | Z |
123 | new value |
注意:id为7的一行对应的value的末尾有一个空格
如下示例展示了三种不同比较方式的区别
BINARY命令
SELECT * FROM table_comms_ease ORDER BY table_comms_ease.value COLLATE BINARY;
结果:
id | value |
---|---|
6 | A |
8 | Z |
5 | new value |
123 | new value |
7 | new value |
NOCASE命令
SELECT * FROM table_comms_ease ORDER BY table_comms_ease.value COLLATE NOCASE;
结果:
id | value |
---|---|
6 | A |
5 | new value |
123 | new value |
7 | new value |
8 | Z |
RTRIM命令
SELECT * FROM table_comms_ease ORDER BY table_comms_ease.value COLLATE RTRIM;
结果:
id | value |
---|---|
6 | A |
8 | Z |
5 | new value |
7 | new value |
123 | new value |
数量限制语句可以限制查询结果的行数,常用格式如下
LIMIT 数量 OFFET 偏移量
设数量为n,偏移量为o,则上面格式的意义是从第o+1
条开始,取最多n
条数据,如果没有符合条件的数据,则结果为空。
限制数量为3,得到如下表达式
SELECT * FROM table_comms_ease LIMIT 3;
结果为
id | value |
---|---|
5 | new value |
6 | A |
7 | new value |
由于表的总行数是5,所以如果限制数量≥5,则会查出整张表。
如果限制数量为3,同时指定偏移量为1,得到如下表达式
SELECT * FROM table_comms_ease LIMIT 3 OFFSET 1;
结果过滤掉第一条数据(5, newvalue)
,并向后取3条,得到
id | value |
---|---|
6 | A |
7 | new value |
8 | Z |
如果限制数量为3,同时指定偏移量为3,得到如下表达式
SELECT * FROM table_comms_ease LIMIT 3 OFFSET 3;
结果过滤掉前三条数据,并向后取3条,但是后面只有2条,所以得到
id | value |
---|---|
8 | Z |
123 | new value |
如果偏移量≥5,则什么都查不到
类别 | 限制 | 备注 |
---|---|---|
字符串长度 | 1亿 | 由宏SQLITE_MAX_LENGTH定义,可以提高或降低限制,最大到231-1 |
单行最大字节数 | 1亿 | 由宏SQLITE_MAX_LENGTH定义 |
最大列数 | 2000 | 由宏SQLITE_MAX_COLUMN定义,可以提高或降低限制,最大到32767 |
语句最大长度 | 10亿 | 由宏SQLITE_MAX_SQL_LENGTH定义,可以降低限制 |
连接中最大表数 | 64 | 不可改变 |
表达式树的最大深度 | 1000 | 由宏SQLITE_MAX_EXPR_DEPTH定义,可以降低或消除限制 |
函数的最大参数数 | 100 | 由宏SQLITE_MAX_FUNCTION_ARG定义,可以提高,最大到 127 |
复合 SELECT 语句中的SELECT数 | 500 | 由宏SQLITE_MAX_COMPOUND_SELECT定义,可以降低 |
库文件最大页数 | 1073741823 | 由宏SQLITE_MAX_PAGE_COUNT定义,可以提高或降低限制,最大到4294967294。 |
最大数据库大小 | 281TB | 结合最大页数4294967294和最大页面大小65536,得到最大数据库大小为281TB,但是这是个理论值,未经官方验证过。 |
表中的最大行数 | 2^64 | 无法达到,会先达到281TB的数据库大小限制 |
B树是一种平衡多路查找树,每个结点包含三个部分:键,值,指向子结点的指针。假设一个B树结点中有n
个键,则它同时有n
个值。如果这是一个叶子结点,则它没有指向子结点的指针,否则有n+1
个指向子结点的指针。下图为n==2
时的结点情况。
图中键1
和键2
两个值需要满足键1<键2
。 值1
和值2
分别与键1
和键2
对应;三个指向子结点的指针
,分别指向具有不同范围的键
的子结点。子结点1
中的键
都小于键1
;子结点2
中的键
都大于键1
,且小于键2
;子结点3
中的键
都大于键2
。如下图提供了一个3路B树的示例。
上图中每个结点有三排,第一排是键
;第二排是值
;第三排是指向子结点的指针
。根节点有50
和100
两个键
,因此它的左子树中结点的键
都小于50
;中子树中结点的键
都大于50
且小于100
;右子树中结点的键
都大于100
。
B+树和B树类似,但是B+树的内部结点中只有键
和指向子结点的指针
,而叶子结点具有键
、值
和指向下一组值的指针
,即只在叶子结点上存储数据。因此父结点中的键还会再出现在子结点上。而且B+树的叶子结点的指向下一组值的指针
,将所有值
都串成了一个链表。由于内部结点不需要存储值
,B+树可以存储更多的键
。下图用5路B+树存储了上面3路B树的内容。
数据库文件由一页或多页组成。同一个数据库中,每页的大小相同,都是 在512 和 65536 之间,并且为2的整数次幂。数据库的页分为锁定字节(lock-byte)页、freelist页、B树页、负载溢出页和指针映射页。
B树算法为SQLite提供了键值存储模式,而且保证了键的有序性和唯一性。SQLite数据库中B树的结点就是一个页面,所以指向的子结点的指针实际上是对应页面的页码。SQLite数据库使用了两种B树变体,在叶子节点存储数据的表B树
和不存储数据的索引B树
。一颗完整的树只能是完全的表B树
或者完全的索引B树
。
表B树类似B+树,只将值存放在叶子结点中;索引B树是一颗没有值的树,键就是数据本身,因此索引B树其实类似于B树。下表列出了它们之间的一些差异。
对比项 | 表B树 | 索引B树 |
---|---|---|
键长度(byte) | 8 | 最长2147483647的随机值 |
值存放点 | 叶子结点 | 没有值,键就是数据 |
值长度 | 最长2147483647 | 没有值,键就是数据 |
叶子结点结构 | 键 | 键和值 |
主要使用场景 | rowid表 | 索引、WITHOUT_ROWID表 |
文章浏览阅读1.6w次,点赞8次,收藏18次。已解决(selenium操作火狐浏览器报错)TypeError: __init__() got an unexpected keyword argument ‘firefox_options‘_typeerror: __init__() got an unexpected keyword argument 'chrome_options
文章浏览阅读315次。python实现代码# -*- coding: utf-8 -*-import mathdef get_average(records):"""平均值"""return sum(records) / len(records)def get_variance(records):"""方差 反映一个数据集的离散程度"""average = get_average(records)return sum(..._pycharm方差计算代码
文章浏览阅读902次。一、前提:cookie是保存在本地,用来记录用户信息,最典型的作用是判断用户是否已经登录。如果一个接口,需要用户登录后,才能进行操作,如下,修改用户信息那么这时候,就需要用到cookie去识别这个登录的用户,因为要修改的是这个登录的用户的信息。二、使用1、jmeter.properties 中 将CookieManager.save.cookies 设置为true。完成后重启jmet..._jmeter中post请求如何更改每次的用户名
文章浏览阅读7.5k次,点赞2次,收藏2次。虚拟环境的好处:搭建独立的python运行环境,不与其他产生冲突虚拟环境有助于包的管理和防止版本冲突3.删除卸载方便虚拟环境的搭建:1.进入python的Scripts下,执行:pip3 install virtualenv2.选择建立虚拟环境的文件夹,我这边是直接在D盘software下面创建了一个virtualenv,如图:image.png3.创建虚拟环境:virtualenv --no-s..._pycharm没有venv怎么办
文章浏览阅读2.3k次。--pod install时报错,且错误提示中有“ffi”字眼,提示错误:/Library/Ruby/Gems/2.6.0/gems/ffi-1.15.3/lib/ffi/library.rb:275: [BUG] Bus Error at 0x00000001042fc000 ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.arm64e-darwin20]解决方案:juejin.cn/post/698064…--pod repo upd_oc cocospods 安装依赖库之后不能使用模拟器了
文章浏览阅读540次。工欲善其事必先利其器,趁手的工具会使我们开发事半功倍。市面上的编辑器我用过许多,编辑器使用经历Notepad++,(开源)这个应该是最轻量级的吧,查看代码还好,编辑代码就算了官网地址:https://notepad-plus-plus.org/Brackets,(开源)这个也不错,github-star:30k了,上次发布版本是6月..._vscode nextick
文章浏览阅读95次。前言:织梦程序是最知名的cms程序,使用广泛,但很多朋友对织梦还不太熟悉,通过工单分析得知,经常容易出现本文中的问题,本次统一整理出来,希望对新手朋友有帮助,本文写的非常详细,请仔细阅读,一、描述:“dedecms错误警告:连接数据库失败,可能数据库密码不对或数据库服务器出错”如图:分析:用织梦程序制作的站点做迁移服务器后容易出现这个问题,原因是程序中设置的数据库连接信息有误连接不到数据库,解决方..._西部数码支不支持织梦的程序
文章浏览阅读295次。上午在win7下安装MYSQL,只到“net start mysql”这一步报错:3534的错误:于是在百度中搜索关键字“mysql服务无法启动3534”。参考以下两个链接中的方法,解决了3534启动失败的问题:mysql服务无法启动3534错误。http://jingyan.baidu.com/article/219f4bf7e978fcde442d38a9.htmlhttp://blog.cs..._免安装mysql启动失败
文章浏览阅读5.1w次,点赞58次,收藏295次。最近在做项目和复习的时候,用了不少流程图软件给我帮了大忙,所以今天就来分享分享你在网上搜索一下流程图软件,能找到很多很多:但这些软件多数并不是专门绘制流程图的软件,它可能是一些思维导图软件、或者说一些产品交互原型图软件,使用时或多或少有些麻烦。而且,普遍这些软件缺点也很多,比如:只有在线版:ProcessOn(https://www.processon.com)导出功能收费:迅捷流程图软件体积庞大:VISIO就没有一款简单易用、绿色免费的流程图软件吗?阿虚花了不少时间,挨着_好用的流程图软件免费
文章浏览阅读1.4k次。cd /data/install_pkgwget https://github.com/azkaban/azkaban/archive/3.50.0.tar.gztar -zxvf 3.50.0.tar.gzvi /data/install_pkg/azkaban-3.50.0/azkaban-common/src/main/java/azkaban/utils/EmailMessage..._centos6.9 azkaban
文章浏览阅读586次,点赞23次,收藏30次。博主介绍:CSDN特邀作者、985计算机专业毕业、某互联网大厂高级全栈开发程序员、码云/掘金/华为云/阿里云/InfoQ/StackOverflow/github等平台优质作者、专注于Java、小程序、前端、python等技术领域和毕业项目实战,以及程序定制化开发、全栈讲解、就业辅导、面试辅导、简历修改。精彩专栏 推荐订阅2023-2024年最值得选的微信小程序毕业设计选题大全:100个热门选题推荐2023-2024年最值得选的Java毕业设计选题大全:500个热门选题推荐。
文章浏览阅读944次。由于需要用pyqt给yolov8做一个界面,而ultralytics一层嵌一层,不是很好用,所以对它的这个源码进行精简,具体代码我放到了这里,ultralytics使用的版本是8.0.54。具体代码如下,需要根据自己的情况来修改data的配置文件以及权值文件,在代码的49和50行。_from ultralytics.utils.plotting import annotator, colors, save_one_box modul