文章目录
- 1 数据库基本知识
- 2 数据库管理系统
- 3 MySQL 环境搭建
- 4 客户端 Navicat
- 5 MySQL 数据类型
- 6 数据完整性和约束
- 7 数据库操作流程
- 8 数据表查询
- 9 MySQL 高级进阶
1 数据库基本知识
1.1 概念
- 以一定格式进行组织的数据的集合
1.2 特点
- 持久性存储
- 读写速度极高
- 保证数据有效性
- 对程序的支持性比较好,容易拓展
1.3 作用
- 存储数据
1.4 分类
- 关系型数据库:采用关系模型来组织数据的数据库,关系模型指的就是二维数据表模型
- MySQL:双授权政策,体积小,速度快
- Oracle
- SQL Server
- 非关系型数据库:NoSQL(Not Only SQL),非关联型。强调Key-Value 存储
- MongoDB
2 数据库管理系统
2.1 概念
DBMS (Database Management System), 为管理数据库而设计的软件系统
2.2 组成
- 数据库文件集合:存储数据
- 数据库服务器
- 数据库客户端
2.3 SQL 语句
- 作用:实现数据库客户端和数据库服务端进行通讯
- 含义:结构化查询语言,用来操作 RDBMS(Relational Database Management System)的数据库语言。
2.4 RDBMS 的核心元素
- 字段:一列数据类型相同的数据
- 记录:一行记录某个事物的完整信息的数据
- 数据表:由若干字段和记录组成
- 数据库:由若干数据表组成
- 主键:唯一标识一行记录的字段
3 MySQL 环境搭建
3.1 服务端搭建
-
安装
1
sudo apt-get install mysql-server
-
启动
1
2
3sudo service mysql start
ps -ajx|grep mysql # 查看进程中是否存在MySQL -
停止
1
sudo service mysql stop
3.2 客户端安装
1 | sudo apt-get install mysql-client |
3.3 MySQL 配置文件
-
配置文件路径
1
/etc/mysql/mysql.conf.d/mysqld.cnf
-
配置文件信息
1
2
3
4
5
6
7
8
9bind -address 表示服务器绑定的ip,默认为127.0.0.1
port 表示端口,默认为3306
datadir 表示数据库目录,默认为/var/lib/mysql
general_log_file 表示普通日志,默认为/var/log/mysql/mysql.log
log_error表示错误日志,默认为/var/log/mysql/error.log -
配置文件操作命令
1
2
3
4# 进入目录
cd /etc/mysql/mysql.conf.d
# 编辑配置文件
vi mysqld.cnf
-
MySQL 数据库本身自带命令行工具,但使用上功能性和易用性不是太好。
-
安装
1
2
3
4
5
6
7cd #安装文件所在目录
tar -axvf #安装文件名
cd #解压的安装文件
./start.mysql #运行mysql
5 MySQL 数据类型
5.1 数值
-
整型
1
2
3
4
5
6
7
8
9TINYINT #1Bytes
SMALLINT #2Bytes
MEDIUMINT #3Bytes
INT #4Bytes #-2^31~2^31-1或0~2^32-1
BIGINT #8Bytes -
浮点型
1
2
3
4
5float #保留6位小数
double #保留16位小数
decimal #定点数 例如:decimal(5,2) 5位数字,其中2位小数
5.2 日期 / 时间
1 | date 年-月-日 |
5.3 字符串(字符)
- char(n) 定长字符串 n 个字符
- varchar(n) 变长字符串 n+1 个字符
- text
5.4 枚举类型
- enum
6 数据完整性和约束
6.1 数据完整性
-
用于保证数据的正确性,核实其约束条件
-
参照完整性
-
约束
-
作用:保证数据完整性和一致性
-
约束类型
1
2
3
4
5
6
7
8
9NOT NULL 非空约束
PRIMARY KEY 主键约束
UNIQUE KEY 唯一约束
DEFAULT 默认约束
FOREIGN KEY 外键约束
-
7 数据库操作流程
7.1 安装数据库服务端
1 | sudo apt-get install mysql-server |
7.2 安装数据库客户端
1 | sudo apt-get install mysql-client |
7.3 开启服务端
1 | sudo service mysql start |
7.4 客户端链接服务端
7.5 登录数据库
1 | mysql -uroot -pmysql |
7.5.1 退出数据库
1 | quit |
7.5.2 显示数据库版本
1 | select version(); |
7.5.3 显示时间
1 | select now(); |
7.5.4 快捷操作
1 | Ctrl + a #到行首 |
7.6 创建数据库文件
1 | show databases; --查看所有数据库 |
7.7 创建数据表
- 指定字段
- 字段类型 int varchar
- 约束
7.8 操作数据表
7.8.1 查看表结构
1 | show tables; --查看当前所有的表 |
1 | desc 表名; --查看表结构 |
7.8.2 约束
1 | int unsigned --无符号整型 |
7.8.3 创建数据表
1 | create table heima( |
7.8.4 数据表操作
-
增
1
alter table 表名 add 列名 类型; --增加字段
-
删
1
2
3alter table drop table 表名; --删除字段
drop table 表名; --删除数据表 -
改
1
2
3
4
5#修改类型及约束
alter table 表名 modify 列名 类型及约束;
# 重命名
alter table 表名 change 原名 新名 类型及约束; -
查
1
desc 表名; --查看表结构
7.8.5 表数据操作
-
增
1
2
3
4
5insert into 表名 values(); --全列插入
insert into 表名 (表头1,表头2) values(值1,值2); --部分列插入
insert into 表名 values( ),( ); --多行插入 -
删
1
2#方法一
delete from 表名 where 条件;1
2
3
4#方法二
alter table 表名 add is_delete bit default 0; --定义is_delete字段来保留并标识删除的数据
update 表名 set is_delete=1 where 条件; --将删除的数据的标志物置1
select * from 表名 where is_delete=1; --查询删除的数据 -
改
1
2
3update 表名 set 列名=值;
update 表名 set 列名1=值 where 【条件】; -
查
1
2
3
4
5select * from 表名;
select 列1,列2... from 表名;
select 列1 as 别名1, 列名2 as 别名2 from 表名;
文本编辑器
notepad++
sublime Text
8 数据表查询
8.1 去重查询
1 | select distinct 列名 from 表名; |
8.2 起别名查询
-
字段起别名
1
select 字段名 as 别名 from 表名;
-
数据表起别名
1
select 字段名 from 表名 as 别名;
8.3 where 查询
对数据表中的数据进行筛选,结果为 True 的记录会出现在结果集中。
1 | select * from 表名 where 条件; |
-
比较运算符:=、>、<、>=、<=、<> 或者!=、!>、!<
1
2
3
4-- 查询年龄不为18岁的所有学生的名字
select * from students where age != 18;
select * from students where age <> 18; -
逻辑运算符:and、or、not
1
2-- 不在 18岁以上的女性 这个范围内的信息
select * from students where not (age>18 and gender="女"); -
模糊查询:like、%(替代任意多个)、_(替代任意一个)、[ ](指定一个字符、字符串或范围)、[^](指定字符以外的任一个字符)
1
2--查询姓名中 有 "小" 所有的名字
select * from students where name like "%小%"; -
范围查询:in、between … and …
1
2--查询身高在165-180,年龄在18-34岁的女性的姓名、性别、身高
select name as '姓名',gender as '性别',height as '身高' from students where (height between 165 and 180) and (age between 18 and 34) and (gender = '女'); -
空值判断:is null、is not null
1
2-- 判非空is not null
select * from students where height is not null; -
order 排序查询
1
2-- 查询年龄在18到34岁之间的女性,身高从高到矮排序, 如果身高相同的情况下按照年龄从大到小排序
select * from students where (age between 18 and 34) and gender=2 order by height desc, age desc;1
2--查询身高在165-180的男性或者年龄在20-40的女性,并以年龄升序排序,如果相同则以身高降序排列。
select * from students where (height between 165 and 180 and gender=1) and (age between 20 and 40 and gender=2) order by age asc,height desc; -
聚合函数
-
将当前所在表当做一个组进行统计
-
count ():计算总行数
1
2-- 查询男性有多少人
select count(*) from students where gender=1; -
max ():计算最大值
1
2-- 查询最大的年龄
select max(age) from students; -
min ():计算最小值
1
2-- 查询最低身高
select min(height) from students; -
sum ():求和
1
2-- 计算所有人的年龄总和
select sum(age) from students; -
avg ():求平均值
1
2-- 计算平均年龄
select avg(age) from students;1
2
3--round() 四舍五入取值
-- 计算所有人的平均年龄,保留2位小数
select round(avg(age),2) from students;
-
-
8.4 group 分组查询
group by 将查询结果按照 1 个或者多个字段进行分组
-
group by
1
2-- 按照性别分组,查询所有的性别
select gender from students group by gender;-
group by + group_concat()
group_concat (字段名) 作用:根据分组结果,使用 group_concat () 来放置每一个分组中某字段的集合
1
2-- 查询同种性别中的姓名
select group_concat(name),gender from students group by gender; -
group by + 聚合函数
作用:聚合函数在和 group by 结合使用的时候 统计的对象是每一个分组
1
2
3
4
5-- 计算每种性别中的人数
select gender,count(*) from students group by gender;
-- 查询每组性别的平均年龄
select avg(age),gender from students group by gender; -
group by + having
作用 : having 作用和 where 类似,但 having 只能用于 group by 对分组后的每组数据过滤 而 where 是用来过滤表数据
1
2-- 查询平均年龄超过30岁的性别,以及姓名 having avg(age) > 30(重点)
select group_concat(name),gender from students group by gender having avg(age) > 30; -
group by + with rollup
with rollup 的作用是:在数据表最后新增一行,来记录当前表中该字段对应的操作结果,一般是汇总结果
1
2-- with rollup 汇总的作用(了解)
select count(*),gender from students group by gender with rollup;
-
8.5 limit 分页查询
- Why:如果数据庞大,直接 select * 会导致数据库崩溃
- 含义:限制取出记录的数量,limit 要写在 SQL 语句的最后。
- 语法格式:limit 起始记录 记录数
1 | -- 每页显示2个,显示第4页的信息, 按照年龄从小到大排序 |
8.6 连接查询
当查询结果来源于多个表的时候,需要将多张表的内容连接成一个大的数据集进行汇总显示。
-
内连接:inner join
查询的结果为两个表符合条件匹配的数据集
- 语法格式:select 字段 from 表 A inner join 表 B on 表 A. 字段 1 = 表 B. 字段 2
1
2
3
4
5
6
7
8
9
10
11-- select ... from 表A inner join 表B;
select * from students inner join classes;
-- 查询 有能够对应班级的学生以及班级信息
select * from students inner join classes on students.cls_id=classes.id;
-- 显示姓名、班级
select students.name,classes.name from students inner join classes on students.cls_id=classes.id;
-- 给数据表起名字
select s.name,c.name from students as s inner join classes as c on s.cls_id=c.id;on 和 where 的区别:
-
on 连接条件
-
where 连接后进行筛选的条件
-
外连接
-
左连接:left join
主表在SQL语句的左边,连接后主表中未匹配的从表的数据对应字段以Null展示。
- 语法格式:主表 left join 从表 on 连接条件;
1
2-- 查询每位学生对应的班级信息
select * from students left join classes on students.cls_id=classes.id; -
右连接:right join
主表在SQL语句的右边,连接后主表中未匹配的从表的数据对应字段以Null展示。
- 语法格式:主表 right join 从表 on 连接条件;
1
2-- 将数据表名字互换位置,用left join完成
select * from classes right join students on students.cls_id=classes.id;
-
-
自连接
-
Why:加快查询速度,减少数据表占用空间。
source 资源 # 快速导入资源数据库
1
2-- 从sql文件中导入文件
source areas.sql
1
2
3
4
5
6
7-- 查询省的名称为“广东省”的所有城市
select city.* from
areas as city
inner join
areas as province
on city.pid=province.aid
where province.atitle="广东省"; -
8.7 子查询
-
定义:把一个查询的结果当做另一个查询的条件
-
分类
- 标量子查询:子查询返回的结果是一个数据 (一行一列)
- 列子查询:返回的结果是一列 (一列多行)
- 行子查询:返回的结果是一行 (一行多列)
-
语法格式:
1
2
3
4
5--(1)查询出高于平均身高的信息(height)
select * from students where height > (select avg(height) from students);
--(2)查询学生的班级号能够对应的 学生名字
select * from students where cls_id in (select id from classes);
9 MySQL 高级进阶
9.1 实战操作
-
创建数据库
1
create database 数据库 charset=utf8;
-
打开数据库
1
use 数据库;
-
show databases;查看所有数据库
-
show create database 数据库;查看创建的数据库信息
-
-
创建数据表
1
create table 数据表 (...);
- desc 数据表;查看数据表结构信息
- show tables; 查看所有的数据表列表
-
插入数据
1
insert into 数据库 values(...);
- select * from 数据表;
-
常用数据表操作
- 数据查询
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
-- 查询类型 cate_name 为 '超级本' 的商品名称 name 、价格 price ( where )
select name,price from goods where cate_name="超级本";
-- 显示商品的种类
-- 1 分组的方式( group by )
select cate_name from goods group by cate_name;
-- 2 去重的方法( distinct )
select distinct cate_name from goods;
-- 求所有电脑产品的平均价格 avg ,并且保留两位小数( round )
select round(avg(price),2) from goods;
-- 显示 每种类型 cate_name (由此可知需要分组)的 平均价格
select avg(price),cate_name from goods group by cate_name;
-- 查询 每种类型 的商品中 最贵 max 、最便宜 min 、平均价 avg 、数量 count
select cate_name,max(price),min(price),avg(price),count(*) from goods group by cate_name;
-- 查询所有价格大于 平均价格 的商品,并且按 价格降序 排序 order desc
-- 1 查询平局价格(avg_price)
select avg(price) as avg_price from goods;
-- 2 使用子查询
select * from goods where price>(select avg(price) as avg_price from goods) order by price desc;
-- 查询每种类型中最贵的电脑信息(难)
-- 1 查找 每种类型 中 最贵的 max_price 价格
select max(price) as max_price,cate_name from goods group by cate_name;
-- 2 关联查询 inner join 每种类型 中最贵的物品信息
select * from goods
inner join
(select max(price) as max_price,cate_name from goods group by cate_name) as max_price_goods
on goods.cate_name=max_price_goods.cate_name and goods.price=max_price_goods.max_price;
- 数据表优化
- 优化步骤
(1)创建商品种类表
(2)同步数据到商品种类表中
(3)更新商品信息表数据
(4)修改商品信息表表结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
第一步 创建表 (商品种类表 goods_cates )
create table if not exists goods_cates(
id int unsigned primary key auto_increment,
name varchar(40) not null
);
第二步 同步 商品分类表 数据 将商品的所有 (种类信息) 写入到 (商品种类表) 中
-- 按照 分组 的方式查询 goods 表中的所有 种类(cate_name)
select cate_name from goods group by cate_name;
--插入分组后的数据,注意:语句中没有values关键字
insert into goods_cates(name) (select cate_name from goods group by cate_name);
第三部 同步 商品表 数据 通过 goods_cates 数据表来更新 goods 表
-- 因为要通过 goods_cates表 更新 goods 表 所以要把两个表连接起来
select * from goods inner join goods_cates on goods.cate_name=goods_cates.name;
-- 把 商品表 goods 中的 cate_name 全部替换成 商品分类表中的 商品id ( update ... set )
update (goods inner join goods_cates on goods.cate_name=goods_cates.name) set goods.cate_name=goods_cates.id;
第四部 修改表结构
-- 查看表结构(注意 两个表中的 外键类型需要一致)
desc goods;
-- 修改表结构 alter table 字段名字不同 change,把 cate_name 改成 cate_id int unsigned not null
alter table goods change cate_name cate_id int unsigned not null;
9.2 外键
-
定义:一个数据表的主键 A 在另一个数据表 B 中出现,则称为 A 是数据表 B 的外键。
-
作用:限制无效信息的插入
-
操作说明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21-- 外键的使用
-- 向goods表里插入任意一条数据
insert into goods (name,cate_id,brand_id,price) values('老王牌拖拉机', 10, 10,'6666');
-- 约束 数据的插入 使用 外键 foreign key
-- alter table goods add foreign key (brand_id) references goods_brands(id);
alter table goods add foreign key(cate_id) references goods_cates(id);
alter table goods add foreign key(brand_id) references goods_brands(id);
-- 失败原因 老王牌拖拉机 delete
-- delete from goods where name="老王牌拖拉机";
delete from goods where name="老王牌拖拉机";
-- 如何取消外键约束
-- 需要先获取外键约束名称,该名称系统会自动生成,可以通过查看表创建语句来获取名称
show create table goods;
-- 获取名称之后就可以根据名称来删除外键约束
alter table goods drop foreign key goods_ibfk_1;
alter table goods drop foreign key goods_ibfk_2;
9.3 视图
-
定义:能够把复杂 SQL 语句的功能封装起来的一个虚表
-
特点
- 视图是对若干张基本表的引用,一张虚表,
- 不存储具体的数据(基本表数据发生了改变,视图也会跟着改变)
- 方便操作,特别是查询操作,减少复杂的 SQL 语句,增强可读性,复用性;
-
操作说明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23-- 视图的定义方式
create view 视图名称(一般使用v开头) as select语句;
-- 查出学生的id,姓名,年龄,性别 和 学生的 班级
select s.id,s.name,s.age,s.gender,c.name as cls_name
from students as s
inner join classes as c
on s.cls_id=c.id;
-- 创建上述结果的视图( v_students )
-- create view v_students as
--注意:连接后的字段名不能相同,若相同,需用as其别名区分。
create view v_students as
select s.id,s.name,s.age,s.gender,c.name as cls_name
from students as s
inner join classes as c
on s.cls_id=c.id;
--查看视图
show tables;
-- 删除视图(drop view 视图名字)
drop view v_students;
9.4 事务
-
定义:Transaction,是指作为一个基本工作单元执行的一系列 SQL 语句的操作,要么完全地执行,要么完全地都不执行。
-
应用
A 用户和 B 用户是银行的储户,现在 A 要给 B 转账 500 元,那么需要做以下几件事:
-
检查 A 的账户余额 > 500 元;
-
A 账户中扣除 500 元;
-
B 账户中增加 500 元;
-
-
事务四大特性 ACID
-
原子性 (Atomicity)[ætəˈmɪsəti]
一个事务必须被视为一个不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,
要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作。
-
一致性 (Consistency)
数据库总是从一个一致性的状态转换到另一个一致性的状态。(在前面的例子中,一致性确保了即使在执行第三、四条语句之间时系统崩溃,支票账户中也不会损失 500 元,因为事务最终没有提交,所以事务中所做的修改也不会保存到数据库中。)
-
隔离性 (Isolation)
通常来说,一个事务所做的修改在最终提交以前,对其他事务是不可见的。(在前面的例子中,当执行完第三条语句、第四条语句还未开始时,此时有另外的一个账户汇总程序开始运行,则其看到支票帐户的余额并没有被减去 500 元。)
-
持久性 (Durability)
一旦事务提交,则其所做的修改会永久保存到数据库。(此时即使系统崩溃,修改的数据也不会丢失。)
-
-
事务的使用
-
开启事务
开启事务后执行修改命令,变更会维护到本地缓存中,而不维护到物理表中 begin; 或者 start transaction;
-
提交事务
将缓存中的数据变更维护到物理表中 commit;
-
回滚事务
放弃缓存中变更的数据 表示事务执行失败 应该回到开始事务前的状态 rollback;
-
MySQL 默认的存储引擎:innodb
- 查看指令:show engines \G;
9.5 索引
-
定义:一种特殊的文件 (InnoDB 数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的位置信息。
-
使用说明
1
2
3
4
5
6
7
8查看表中已有索引
show index from 表名;
创建索引
alter table 表名 add index 索引名【可选】(字段名,…);
删除索引
drop index 索引名称 on 表名; -
优缺点
-
优点:
加快数据的查询速度
-
缺点:
创建索引会浪费时间和占用磁盘空间,并且随着数据量的增加所耗费的时间会越来越多。
-
-
使用原则
-
经常发生数据更新的表避免使用过多的索引
-
数据量小的表没有必要使用索引
-
数据量较大同时不会频发发生数据更改的表可以使用索引
-
-
代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23-- 创建测试表
create table test_index(title varchar(10));
-- 向表中插入10万条数据
python3 insert_data.py
-- 验证索引性能
-- 没有索引
-- 开启时间检测:
set profiling=1;
-- 查找第1万条数据ha-99999
select * from test_index where title="ha-99999";
-- 查看执行时间
show profiles;
-- 有索引
-- 给title字段创建索引
alter table test_index add index(title);
-- 查找第1万条数据ha-99999
select * from test_index where title="ha-99999";
-- 查看执行时间
show profiles;
9.6 数据库设计三范式
-
定义:设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,
各种范式呈递次规范,越高的范式数据库冗余越小。
-
第一范式(1NF): 强调的是字段的原子性,即一个字段不能够再分成其他几个字段。
-
第二范式(2NF): 满足 1NF 的基础上,另外包含两部分内容:
- 一是表必须有一个主键
- 二是非主键字段必须完全依赖于主键,而不能只依赖于主键的一部分
主键可以由多个字段共同组成
1
2
3
4
5create table test (
name varchar(19),
id int,
primary key (name,id)
) -
第三范式(3NF): 满足 2NF,另外非主键字段必须直接依赖于主键,不能存在传递依赖。即不能存在:非主键字段 A 依赖于非主键字段 B,非主键字段 B 依赖于主键的情况。
-
其他范式:巴斯科德范式、第五范式等
9.7 E-R 模型及表间关系
- 定义:实体 - 关系模型,用来描述数据库存储数据的结构模型
- 表现形式;
- 实体:用矩形表示,并标注实体名称
- 属性:用椭圆表示,并标注属性名称
- 关系:用菱形表示,并标注关系名称
- E-R 模型三种关系:
- 一对一
- 一对多 (1-n)
- 多对多 (n-n)
9.8 Python 连接 MySQL
-
数据库编程:通过使用程序代码的方式去连接 MySQL 数据库,然后对 MySQL 数据库进行增删改查的方式。
-
使用步骤:(调用 pymysql)
①导入 pymysql 包
import pymysql
②创建连接对象
connect()
③获取游标对象
连接对象.cursor()
④ pymysql 完成数据的查询操作
游标对象.execute()
⑤ 关闭游标和连接
游标对象.close() 连接对象.close()
-
代码实现
-
查询操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22# 导入pymysql包
import pymysql
# 创建连接对象
conn = pymysql.connect(host="localhost", port=3306, user="root", password="mysql", database="python_test_1", charset="utf8")
# 获取游标对象
cur = conn.cursor()
# pymysql完成数据的查询操作
sql = "select * from students;"
# 这里content获取的是sql影响的行数
# content = cur.execute(sql)
# print(content)
cur.execute(sql)
content = cur.fetchone()
print(content)
content = cur.fetchall()
print(content)
# 关闭游标和连接
cur.close()
conn.close() -
增删改操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27# 导入pymysql包
import pymysql
# 创建连接对象
conn = pymysql.connect(host="localhost", port=3306, user="root", password="mysql", database="python_test_1", charset="utf8")
# 获取游标对象
cs = conn.cursor()
# 增加数据
# sql = "insert into students(name) values('老王')"
# cs.execute(sql)
# 删除数据
# sql = "delete from students where id=18"
# cs.execute(sql)
# 修改数据
sql = "update students set name='老王' where id=1;"
cs.execute(sql)
for i in content:
print(i)
# 提交操作
conn.commit()
# 关闭游标和连接
cs.close()
conn.close()
-
9.9 SQL 语句参数化
-
目的:防止 SQL 注入
SQL 注入:用户提交带有恶意的数据与 SQL 语句进行字符串方式的拼接,从而影响了 SQL 语句的语义,最终产生数据泄露的现象。
-
参数化实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31# 导入pymysql包
import pymysql
# 创建连接对象
conn = pymysql.connect(host="localhost", port=3306, user="root", password="mysql", database="python_test_1", charset="utf8")
# 获取游标对象
cs = conn.cursor()
# 不安全的方式
# 根据id查询学生信息
# find_name = input("请输入您要查询的学生姓名:")
# sql = "select * from students where name='%s'" % find_name
# # 显示所有的数据
# cs.execute(sql)
# content = cs.fetchall()
# for i in content:
# print(i)
# 安全的方式
# 根据id查询学生信息
find_name = input("请输入您要查询的学生姓名:")
sql = "select * from students where name=%s"
# 显示所有的数据
cs.execute(sql, [find_name])
content = cs.fetchall()
for i in content:
print(i)
# 关闭游标和连接
cs.close()
conn.close()
最后更新: 2021年06月26日 10:45