文章目录


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
    3
    sudo service mysql start

    ps -ajx|grep mysql # 查看进程中是否存在MySQL
  • 停止

    1
    sudo service mysql stop

3.2 客户端安装

1
2
3
4
5
sudo apt-get install mysql-client

mysql -uroot -pmysql #连接命令

quit #退出

3.3 MySQL 配置文件

  • 配置文件路径

    1
    /etc/mysql/mysql.conf.d/mysqld.cnf
  • 配置文件信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    bind -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

4 客户端 Navicat

  • MySQL 数据库本身自带命令行工具,但使用上功能性和易用性不是太好。

  • 安装

    1
    2
    3
    4
    5
    6
    7
    cd #安装文件所在目录

    tar -axvf #安装文件名

    cd #解压的安装文件

    ./start.mysql #运行mysql

5 MySQL 数据类型

5.1 数值

  • 整型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    TINYINT  #1Bytes

    SMALLINT #2Bytes

    MEDIUMINT #3Bytes

    INT #4Bytes #-2^31~2^31-1或0~2^32-1

    BIGINT #8Bytes
  • 浮点型

    1
    2
    3
    4
    5
    float		#保留6位小数

    double #保留16位小数

    decimal #定点数 例如:decimal(5,2) 5位数字,其中2位小数

5.2 日期 / 时间

1
2
3
4
5
6
7
8
9
date	年-月-日

datetime 年-月-日 时:分:秒

timestamp 年-月-日 时:分:秒

time 时:分:秒

year

5.3 字符串(字符)

  • char(n) 定长字符串 n 个字符
  • varchar(n) 变长字符串 n+1 个字符
  • text

5.4 枚举类型

  • enum

6 数据完整性和约束

6.1 数据完整性

  • 用于保证数据的正确性,核实其约束条件

  • 参照完整性

  • 约束

    • 作用:保证数据完整性和一致性

    • 约束类型

      1
      2
      3
      4
      5
      6
      7
      8
      9
      NOT 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
2
3
mysql -uroot -pmysql

mysql -uroot -p --输入密码

7.5.1 退出数据库

1
2
3
4
5
quit    

exit

快捷操作:Ctrl+D

7.5.2 显示数据库版本

1
2
3
select version();     

快捷操作:Ctrl +Shift +V

7.5.3 显示时间

1
select now();

7.5.4 快捷操作

1
2
3
4
5
6
7
Ctrl + a   #到行首

Ctrl + l #清屏

Ctrl + e #到行尾

Ctrl + C+回车 #结束
7.6 创建数据库文件
1
2
3
4
5
6
7
8
9
10
11
show databases;   --查看所有数据库

show create database 数据库名称; --查看创建的数据信息,包括字符集及名称等

select database(); --查看当前使用的数据库

create database 数据库名称 charset=utf8;

use 数据库名称; --使用数据库

drop database 数据库名称; --删除指定数据库
7.7 创建数据表
  • 指定字段
  • 字段类型 int varchar
  • 约束
7.8 操作数据表

7.8.1 查看表结构

1
show tables;  --查看当前所有的表
1
2
3
desc 表名; --查看表结构

show create table 表名; --查看创建的数据表详细信息

7.8.2 约束

1
2
3
4
5
6
7
int unsigned --无符号整型

auto_increment --自动增长

not null --非空

primary key --主键

7.8.3 创建数据表

1
2
3
4
5
6
7
8
create table heima(
id int unsigned primary key auto_increment not null,
name varchar(20) not null,
age int unsigned default 0,
high decimal(5,2),
gender enum("男","女"),
cls_id int unsigned
);

7.8.4 数据表操作

  • 1
    alter table 表名 add 列名 类型; --增加字段
  • 1
    2
    3
    alter 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
    5
    insert 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
    3
    update 表名 set 列名=值;

    update 表名 set 列名1=where 【条件】;
  • 1
    2
    3
    4
    5
    select * from 表名;

    select1,列2... from 表名;

    select1 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
-- 每页显示2个,显示第4页的信息, 按照年龄从小到大排序
select * from students order by age asc limit 6,2;

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. 创建数据库

    1
    create database 数据库 charset=utf8;
  2. 打开数据库

    1
    use 数据库;
    • show databases;查看所有数据库

    • show create database 数据库;查看创建的数据库信息

  3. 创建数据表

    1
    create table 数据表 (...);
    • desc 数据表;查看数据表结构信息
    • show tables; 查看所有的数据表列表
  4. 插入数据

    1
    insert into 数据库 values(...);
    • select * from 数据表;
  5. 常用数据表操作

 - 数据查询

 
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
    5
    create 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()
× 请我吃糖~
打赏二维码