• 爬虫学习(06): 数据存储_mysql篇


    一、mysql简介

    数据库是一个能存数据的软件, 提供各种数据的查询操作, 以及对数据的修改操作

    mysql的具体安装操作,这里就不做过多的介绍了。主要讲讲如何通过py程序来实现mysql操作。
    具体的安装操作可以看下面这一篇
    链接: mysql的安装与配置

    这里的操作基本都在navicat里实现可视化

    1. 安装python连接mysql的模块 -> pymysql模块

    pip install pymysql
    
    • 1

    2. pymysql导包:

    import pymysql
    
    • 1

    二、mysql基本操作

    1. 创建表

    SQL语句创建表格

    create table student(
        -- 字段=列=column=属性
    	sno int(10) primary key auto_increment,
        sname varchar(50) not null, 
        sbirthday date not null,
        saddress varchar(255),
        sphone varchar(12),
        class_name varchar(50)
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    项目数据类型
    double小数
    varchar字符串
    date时间(年月日)
    datetime时间(年月日时分秒)
    text大文本
    项目约束条件
    primary key主键, 全表唯一值. 就像学号. 身份证号. 能够唯一的确定一条数据
    auto_increment主键自增. 必须是整数类型
    not null不可以为空.
    null可以为空
    default设置默认值

    2. 修改表

    -- 添加一列
    ALTER TABLE table_name
    ADD COLUMN column_name datatype
    
    -- eg
    ALTER TABLE student 
    ADD COLUMN f_name VARCHAR(20) NOT NULL
    AFTER sno;  -- AFTER 用于将新加的列在指定列的后面插入
    
    
    -- 删除一列
    ALTER TABLE table_name 
    DROP COLUMN column_name
    
    -- 修改一列的数据类型
    ALTER TABLE table_name
    MODIFY COLUMN column_name datatype
    
    -- 表格重命名
    ALTER TABLE table_name RENAME TO new_name;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3. 在navicat中实现创建表和修改表

    3.1 navicat与mysql连接

    在这里插入图片描述
    在这里插入图片描述
    创建完毕后,还需要右键或者双击打开连接
    在这里插入图片描述

    3.2 navicat创建数据库

    在这里插入图片描述
    在这里插入图片描述
    和连接一样,也是需要进行开启的
    在这里插入图片描述

    至此, Navicat可以操纵你的数据库了.

    3.3 navicat创建表

    在这里插入图片描述
    傻瓜式操作
    在这里插入图片描述

    3.4 navicat设计表

    选择创建好的表,右键设计表,就可以进行修改表操作了
    在这里插入图片描述

    4. 数据的操作-增删改查-数据

    4.1 增加数据
    INSERT INTO table_name(col1, col2, col3...) values (val1,val2,val3)
    
    • 1
    -- 添加学生信息
    INSERT INTO STUDENT(sname, sbirthday, saddress, sage, class_name) values ('周杰伦', '2020-01-02', "北京市昌平区", 18, "二班");
    
    • 1
    • 2

    注意, 如果主键设置自增, 就不用处理主键了. mysql会自动的帮我们按照自然顺序进行逐一自增.

    4.2 删除数据
    DELETE FROM table_name where_clause
    
    • 1
    -- 删除学生信息
    DELETE FROM STUDENT where sno = 1 ; 
    
    • 1
    • 2
    4.3 修改数据
    UPDATE table_name SET col1 = val1, col2 = val2... where_clause
    
    • 1
    -- 修改学生信息
    UPDATE STUDENT SET SNAME = '王力宏' where sno = 1;
    
    • 1
    • 2
    4.4 查询数据
    4.4.1 基础查询
    SELECT *|col1, col2, col3 
    FROM table_name 
    where_clause
    
    • 1
    • 2
    • 3
    -- 全表查询
    SELECT * FROM STUDENT;
    
    -- 查询学生姓名, 年龄
    SELECT sname, sage FROM STUDENT;
    
    -- 查询学号是1的学生信息
    select * from student where sno = 1;
    
    -- 查询年龄大于20的学生信息
    select * from student where sage > 20;
    
    -- 查询学生年龄大于20 小于40的信息(包含)
    select * from student where sage >= 20 and sage <= 40;
    select * from student where sage between 20 and 40 ;
    
    -- 查询姓张的学生信息
    -- 		_一位字符串
    -- 		%多位字符串
    select * from student where sname like '张%';
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    4.4.2 分组查询和聚合函数

    如何查询每个班级学生的平均年龄?

    我们先把数据扩充一下下

    在这里插入图片描述

    每个班级的平均年龄. 我们是不是需要先把班级与班级先分开. 每个班级自己内部进行计算.对吧. 此时, 我们需要的就是一个分组的操作. 此时需要用到group by语句

    select * from table_name group by col_name
    
    • 1

    注意, 上方的sql是无法使用的. sql要求分组后, 到底要做什么必须明确指出. 否则报错

    那很容易呀, 我们分完组要计算每个班级的平均年龄. 平均数如何计算, 这就要用到聚合函数. sql中提供5种聚合函数, 分别是: avg(), sum(), min(), max(), count()

    -- 查询每一个班级的平均年龄
    select avg(sage), class_name from STUDENT group by class_name;
    
    -- 查询每个班级最小的年龄
    select min(sage), class_name from STUDENT group by class_name;
    
    -- 查询每个班的最大年龄
    select max(sage), class_name from STUDENT group by class_name;
    
    -- 查询每个班的学生数量
    select count(*), class_name from STUDENT group by class_name;
    
    -- 查询每个班级的年龄和
    select sum(sage), class_name from STUDENT group by class_name;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    注意, 不要把没有放在group by的内容直接放在select中. 你想想. 按照班级来查询平均年龄, 你非要把某一个人的信息放在结果里. 是不合适的.

    4.4.4 having语句

    如果我们需要对聚合函数计算的结果进一步的筛选. 可以用having语句

    -- 查询平均年龄在15岁以上的班级信息
    select avg(sage), class_name from student group by class_name having avg(sage) > 15;
    
    • 1
    • 2

    having和where的区别:

    1. where, 在原始数据上进行的数据筛选.

    2. having, 在聚合函数计算后的结果进行筛选.

    4.4.5 排序

    sql中使用order by语句对查询结果进行排序.

    -- 按照年龄从小到大查询学生信息
    select * from student order by sage asc
    
    -- 按照年龄从大到小查询学生信息
    select * from student order by sage desc
    
    • 1
    • 2
    • 3
    • 4
    • 5
    4.5 多表联合查询

    在实际使用中, 一个表格肯定是无法满足我们数据存储的. 比如, 在学生选课系统中. 我们就可以设计成以下表结构:

    1. 学生表: 学号, 姓名, 性别, 住址等…
    2. 课程表: 课程编号, 课程名称, 授课教师等…
    3. 学生课程-成绩表: 成绩表编号, 学号, 课程编号, 成绩

    在这样的表结构中:

    优势: 每个表的结构相对明确. 不存在歧义. 数据保存完整, 没有冗余.
    劣势: 新手不太好想. 想不通为什么要这样设计. 这里涉及到数据库表结构设计范式, 该模型属于第三范式(听过就行).

    在该模型表结构中. 成绩表是非常重要的. 在成绩表中, 明确的说明了哪个学生的哪一门课程得了多少分. 它将两个原来毫不相关的表关联了起来. 建立了主外键关系.

    何为主外键关系:

    ​ 把A表中的主键放在另一张表里作为普通字段使用, 但数据要求必须来自于A. 这个很好理解. 比如, 学生成绩表中的学生编号数据就必须来自于学生表. 否则该数据是无意义的.

    注意, 以上结构只是为了讲解多表关系. 并非完整的学生选课系统表结构.

    建表语句:

    -- 创建学生表, 课程表, 成绩表
    -- 1. 学生表: 学号, 姓名, 性别, 住址等...
    -- 2. 课程表: 课程编号, 课程名称, 授课教师等...
    -- 3. 学生课程-成绩表:  成绩表编号, 学号, 课程编号, 成绩
    create table stu(
    	sid int primary key auto_increment,
    	sname varchar(50) not null, 
    	gender int(1),
    	address varchar(255)
    );
    
    create table course(
    	cid int primary key auto_increment,
    	cname varchar(50) not null, 
    	teacher varchar(50)
    );
    
    create table sc(
    	sc_id int primary key auto_increment,
    	s_id int, 
    	c_id int,
    	score int,
    	CONSTRAINT FK_SC_STU_S_ID FOREIGN key(s_id) REFERENCES stu(sid),
    	CONSTRAINT FK_SC_COURSE_C_ID FOREIGN key(c_id) REFERENCES course(cid)
    );
    
    
    • 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
    4.5.1 子查询

    ​ 在where语句中可以进行另外的一个查询.

    ​ 例如, 查询选择了"编程"这门课的学生

    -- 查询选择了"编程"这门课的学生
    -- 先查询编程课程的编号
    select cid from course where cname = '编程';
    -- 根据cid可以去sc表查询出学生的id
    select s_id from sc where c_id = 2;
    -- 根据学生ID查询学生信息
    select * from stu where sid in (1,2,3,4,5,6);
    
    -- 把上面的sql穿起来 
    select * from stu where sid in (
        select s_id from sc where c_id in (
            select cid from course where cname = '编程'
        )
    );
    
    -- 查询课程名称为“编程”,且分数低于60的学生姓名和分数
    select stu.sname, sc.score from stu, sc where stu.sid = sc.s_id and sc.score < 60 and sc.c_id in (
    	select cid from course where cname = '编程'
    )
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    4.5.2 关联查询

    关联查询就是把多个表格通过join的方式合并在一起. 然后进行条件检索.

    语法规则:

    select ... from A xxx join B on A.字段1 = b.字段2
    
    表示:  A表和B表连接. 通过A表的字段1和b表的字段2进行连接. 通常on后面的都是主外键关系
    
    • 1
    • 2
    • 3
    4.5.2.1 inner join
    -- 查询每门课程被选修的学生数
    -- count(*)
    -- group by cid
    
    select c.cid,c.cname, count(*) from sc inner join course c on sc.c_id = c.cid group by c.cid, c.cname
    
    • 1
    • 2
    • 3
    • 4
    • 5
    4.5.2.2 left join
    -- 查询所有学生的选课情况
    select s.sname, c.cname from stu s left join sc on s.sid= sc.s_id left join course c on sc.c_id = c.cid
    
    -- 查询任何一门课程成绩在70分以上的姓名、课程名称和分数
    -- score > 70 sc
    -- sname student
    -- cname course
    select s.sname, c.cname, sc.score from stu s inner join sc on s.sid = sc.s_id inner join course c on sc.c_id = c.cid
    where sc.score > 70
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    三、python连接mysql

    3.1 查找数据

    import pymysql  # 导入模块
    from pymysql.cursors import DictCursor  # 导入字典模块
    #  1. 创建连接
    conn = pymysql.connect(
        #  当忘记参数是什么的时候,直接按住commond点进去看看
            user='root',  # 用户名
            password="x",  # 密码
            host='127.0.0.1',  # 端口
            database='test',  # 数据库名
    )
    
    #  2. 创建cursor, 游标 -> 用于执行sql语句,,以及获取sql执行结果
    cursor = conn.cursor()
    #  2.1 执行sql语句
    cursor.execute('select * from student')
    r = cursor.fetchall()  # 获取结果
    print(r)  # 运行完毕,会发现是元组套元组的形式 # ( (), () )
    #  而我们喜欢的数据类型应该是 [{cno:1, cname:xxx, xxx: xxx}, {}, {}]
    #  所以需要导入一个字典模块
    
    #  将导入的模块放到游标里
    cursor1 = conn.cursor(DictCursor)
    #  2.1 执行sql语句
    cursor1.execute('select * from student')
    r = cursor1.fetchall()  # 获取结果
    print(r)  # 可以发现已经成为我们想要的那个类型了
    
    • 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

    运行结果
    在这里插入图片描述

    3.2 新增数据

    import pymysql  # 导入模块
    from pymysql.cursors import DictCursor  # 导入字典模块
    #  1. 创建连接
    conn = pymysql.connect(
        #  当忘记参数是什么的时候,直接按住commond点进去看看
            user='root',  # 用户名
            password="x",  # 密码
            host='127.0.0.1',  # 端口
            database='test',  # 数据库名
    )
    
    
    #  2. 新增数据
    cursor = conn.cursor()
    sname = 'wby'
    sbirthday = '2010-08-10'
    saddress = '浙江宁波'
    class_name = '少年团'
    #  准备好sql语句
    #  注意: 这种sql的问题 1. 很乱, 2. 有被注入的风险,可以选择下面的方式
    sql = f'insert into student(sname, sbirthday, saddress, class_name) values ("{sname}", "{sbirthday}", "{saddress}", "{class_name}")'
    cursor.execute(sql)
    #  数据增加后,需要提交
    conn.commit()
    
    #  %s字符串的占位符  用来预处理,有几个参数要填入,就写几个%s   ->  推荐这种方法
    sql = f'insert into student(sname, sbirthday, saddress, class_name) values (%s, %s, %s, %s)'
    #  在execute中放预处理的内容, 注意传入的是元组的形式
    cursor.execute(sql, (sname, sbirthday, saddress, class_name))
    conn.commit()
    
    • 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

    四、关于mysql总结

    1. 爬虫常用的增加数据操作
    insert into(字段1,字段2,字段3...) values (1,2,3...)
    
    • 1
    1. 爬虫常用的修改数据操作
    updateset 字段=, 字段=where 条件
    
    • 1
    1. 爬虫常用的删除数据操作
    delete fromwhere 条件
    
    • 1
    1. 爬虫常用的查询数据操作
    select * fromwhere 条件
    
    • 1
  • 相关阅读:
    【白板推导系列笔记】线性分类-高斯判别分析(Gaussian Discriminant Analysis)-模型定义
    excel提取某列字符串数据
    学生花卉网网页设计作品 学生鲜花网页模板 简单在线花店主页成品 鲜花网页制作 HTML学生花店商城网站作业设计
    PHP中文转拼音实现
    如何设计一个机器学习驱动的策略?
    nginx 的学习报告
    【Web安全】sqlmap的使用笔记及示例
    场景应用:设计一个论坛的评论回复功能
    渗透测试 | IP信息收集
    Java面试题-Java核心基础-第三天(基本数据类型)
  • 原文地址:https://blog.csdn.net/m0_48936146/article/details/127473183