一、表之间的关系

  1、如何找出两张表之间的关系

分析步骤:
#1、先站在左表的角度去找
是否左表的多条记录可以对应右表的一条记录,如果是,则证明左表的一个字段foreign key 右表一个字段(通常是id)#2、再站在右表的角度去找
是否右表的多条记录可以对应左表的一条记录,如果是,则证明右表的一个字段foreign key 左表一个字段(通常是id)#3、总结:
#一对多:
如果只有步骤1成立,则是左表多对一右表
如果只有步骤2成立,则是右表多对一左表#多对多
如果步骤1和2同时成立,则证明这两张表时一个双向的多对一,即多对多,需要定义一个这两张表的关系表来专门存放二者的关系#一对一:
如果1和2都不成立,而是左表的一条记录唯一对应右表的一条记录,反之亦然。这种情况很简单,就是在左表foreign key右表的基础上,将左表的外键字段设置成unique即可

  2、建立两张表之间的关系

# 一对多关系
# 咱们以出版社和书籍为例(大家分析一下,二者之间的关系)。
# 1、创建表
create table press(
id int primary key auto_increment,
name varchar(32)
);create table book(
id int primary key auto_increment,
name varchar(32),
press_id int,
foreign key(press_id) references press(id) on delete cascade on update cascade
);# 2、插入记录
# 先插被关联的表
insert into press(name) values
('华山出版社'),
('少林出版社'),
('明教出版社'),
('武当出版社'),
('丐帮出版社');# 再插关联的表
insert into book(name,press_id) values
('独孤九剑',1),
('华山剑法',1),
('九阳神功',2),
('九阴真经',2),
('易筋经',2),
('葵花宝典',3),
('乾坤大挪移',3),
('太极拳',4),
('天罡北斗阵',4);
insert into book(name) values("吸星大法");
# 多对多关系
# 1、创建表
# 先建作者表
create table author(
id int primary key auto_increment,
name varchar(32)
);# 再建存放作者与书的关系表,即查询二者的关系查这表就可以了
create table author2book(
id int not null unique auto_increment,
author_id int,
book_id int,
foreign key(author_id) references author(id) on delete cascade on update cascade,
foreign key(book_id) references book(id) on delete cascade on update cascade,
primary key(author_id,book_id)
);# 2、插入记录
# 先插作者表
insert into author(name) values
('张无忌'),
('令狐冲'),
('东方不败'),
('张三丰'),
('冲虚道长');# 再插入对应的关系记录
insert into author2book(author_id,book_id) values
(1,3),
(1,7),
(2,1),
(2,2),
(3,6),
(4,8);# 一对一关系# 两张表:学生表和客户表# 一对一:一个学生是一个客户,一个客户有可能变成一个学校,即一对一的关系# 关联方式:foreign key+unique# 1、创建表# 一定是student来foreign key表customer,这样就保证了:# 1 学生一定是一个客户,# 2 客户不一定是学生,但有可能成为一个学生
# 先建客户表
create table customer(
id int primary key auto_increment,
name varchar(32) not null,
qq varchar(32)not null,
tel varchar(32) not null
);
# 再建学生表
create table student(
id int primary key auto_increment,
class_name varchar(32) not null,
customer_id int unique,  # 该字段一定要是唯一的
foreign key(customer_id) references student(id) on delete cascade on update cascade
);# 2、插入记录
# 先插客户表
insert into customer(name,qq,tel) values
('alex',1223,135666544),
('egon',34322,13438895),
('yuan',84322,13954893);insert into student(class_name,customer_id) values
('脱产2期',1),
('脱产3期',2),
('周末13期',3);

二、多表连接查询

  1、外连接语法

SELECT 字段列表FROM 表1 INNER|LEFT|RIGHT JOIN 表2ON 表1.字段 = 表2.字段;

  2、交叉连接(笛卡尔积)

# 注意:这种连接毫无意义
mysql> select * from book,press;  # 简单粗暴的将两张表连接起来
+----+------------+----------+----+------------+
| id | name       | press_id | id | name       |
+----+------------+----------+----+------------+
|  1 | 独孤九剑   |        1 |  1 | 华山出版社 |
|  1 | 独孤九剑   |        1 |  2 | 少林出版社 |
|  1 | 独孤九剑   |        1 |  3 | 明教出版社 |
|  1 | 独孤九剑   |        1 |  4 | 武当出版社 |
|  1 | 独孤九剑   |        1 |  5 | 丐帮出版社 |
|  2 | 华山剑法   |        1 |  1 | 华山出版社 |
|  2 | 华山剑法   |        1 |  2 | 少林出版社 |
|  2 | 华山剑法   |        1 |  3 | 明教出版社 |
|  2 | 华山剑法   |        1 |  4 | 武当出版社 |
|  2 | 华山剑法   |        1 |  5 | 丐帮出版社 |
|  3 | 九阳神功   |        2 |  1 | 华山出版社 |
|  3 | 九阳神功   |        2 |  2 | 少林出版社 |
|  3 | 九阳神功   |        2 |  3 | 明教出版社 |
|  3 | 九阳神功   |        2 |  4 | 武当出版社 |
|  3 | 九阳神功   |        2 |  5 | 丐帮出版社 |
|  4 | 九阴真经   |        2 |  1 | 华山出版社 |
|  4 | 九阴真经   |        2 |  2 | 少林出版社 |
|  4 | 九阴真经   |        2 |  3 | 明教出版社 |
|  4 | 九阴真经   |        2 |  4 | 武当出版社 |
|  4 | 九阴真经   |        2 |  5 | 丐帮出版社 |
|  5 | 易筋经     |        2 |  1 | 华山出版社 |
|  5 | 易筋经     |        2 |  2 | 少林出版社 |
|  5 | 易筋经     |        2 |  3 | 明教出版社 |
|  5 | 易筋经     |        2 |  4 | 武当出版社 |
|  5 | 易筋经     |        2 |  5 | 丐帮出版社 |
|  6 | 葵花宝典   |        3 |  1 | 华山出版社 |
|  6 | 葵花宝典   |        3 |  2 | 少林出版社 |
|  6 | 葵花宝典   |        3 |  3 | 明教出版社 |
|  6 | 葵花宝典   |        3 |  4 | 武当出版社 |
|  6 | 葵花宝典   |        3 |  5 | 丐帮出版社 |
|  7 | 乾坤大挪移 |        3 |  1 | 华山出版社 |
|  7 | 乾坤大挪移 |        3 |  2 | 少林出版社 |
|  7 | 乾坤大挪移 |        3 |  3 | 明教出版社 |
|  7 | 乾坤大挪移 |        3 |  4 | 武当出版社 |
|  7 | 乾坤大挪移 |        3 |  5 | 丐帮出版社 |
|  8 | 太极拳     |        4 |  1 | 华山出版社 |
|  8 | 太极拳     |        4 |  2 | 少林出版社 |
|  8 | 太极拳     |        4 |  3 | 明教出版社 |
|  8 | 太极拳     |        4 |  4 | 武当出版社 |
|  8 | 太极拳     |        4 |  5 | 丐帮出版社 |
|  9 | 天罡北斗阵 |        4 |  1 | 华山出版社 |
|  9 | 天罡北斗阵 |        4 |  2 | 少林出版社 |
|  9 | 天罡北斗阵 |        4 |  3 | 明教出版社 |
|  9 | 天罡北斗阵 |        4 |  4 | 武当出版社 |
|  9 | 天罡北斗阵 |        4 |  5 | 丐帮出版社 |
| 10 | 吸星大法   |     NULL |  1 | 华山出版社 |
| 10 | 吸星大法   |     NULL |  2 | 少林出版社 |
| 10 | 吸星大法   |     NULL |  3 | 明教出版社 |
| 10 | 吸星大法   |     NULL |  4 | 武当出版社 |
| 10 | 吸星大法   |     NULL |  5 | 丐帮出版社 |
+----+------------+----------+----+------------+

# 咱们只想取到两表有关系的记录怎么办呢,有同学会说,我们加一个where条件。
mysql> select * from book,press where book.press_id=press.id;
+----+------------+----------+----+------------+
| id | name       | press_id | id | name       |
+----+------------+----------+----+------------+
|  1 | 独孤九剑   |        1 |  1 | 华山出版社 |
|  2 | 华山剑法   |        1 |  1 | 华山出版社 |
|  3 | 九阳神功   |        2 |  2 | 少林出版社 |
|  4 | 九阴真经   |        2 |  2 | 少林出版社 |
|  5 | 易筋经     |        2 |  2 | 少林出版社 |
|  6 | 葵花宝典   |        3 |  3 | 明教出版社 |
|  7 | 乾坤大挪移 |        3 |  3 | 明教出版社 |
|  8 | 太极拳     |        4 |  4 | 武当出版社 |
|  9 | 天罡北斗阵 |        4 |  4 | 武当出版社 |
+----+------------+----------+----+------------+
# 确实可以取到,但是不用这样自己去写where条件,SQL语句有对应的语法来实现。咱们接下来就详细说一下。

  3、内连接(inner join)

    内连接,只取两表的共同部分。

mysql> select * from book inner join press on book.press_id = press.id;
+----+------------+----------+----+------------+
| id | name       | press_id | id | name       |
+----+------------+----------+----+------------+
|  1 | 独孤九剑   |        1 |  1 | 华山出版社 |
|  2 | 华山剑法   |        1 |  1 | 华山出版社 |
|  3 | 九阳神功   |        2 |  2 | 少林出版社 |
|  4 | 九阴真经   |        2 |  2 | 少林出版社 |
|  5 | 易筋经     |        2 |  2 | 少林出版社 |
|  6 | 葵花宝典   |        3 |  3 | 明教出版社 |
|  7 | 乾坤大挪移 |        3 |  3 | 明教出版社 |
|  8 | 太极拳     |        4 |  4 | 武当出版社 |
|  9 | 天罡北斗阵 |        4 |  4 | 武当出版社 |
+----+------------+----------+----+------------+
# 此查询结果是不是跟上面的一样啊,说明上面的where条件就是内连接。

  4、左连接(left join)

    左连接,在内连接的基础上保留左边的记录。

mysql> select * from book left join press on book.press_id = press.id;
+----+------------+----------+------+------------+
| id | name       | press_id | id   | name       |
+----+------------+----------+------+------------+
|  1 | 独孤九剑   |        1 |    1 | 华山出版社 |
|  2 | 华山剑法   |        1 |    1 | 华山出版社 |
|  3 | 九阳神功   |        2 |    2 | 少林出版社 |
|  4 | 九阴真经   |        2 |    2 | 少林出版社 |
|  5 | 易筋经     |        2 |    2 | 少林出版社 |
|  6 | 葵花宝典   |        3 |    3 | 明教出版社 |
|  7 | 乾坤大挪移 |        3 |    3 | 明教出版社 |
|  8 | 太极拳     |        4 |    4 | 武当出版社 |
|  9 | 天罡北斗阵 |        4 |    4 | 武当出版社 |
| 10 | 吸星大法   |     NULL | NULL | NULL       |
+----+------------+----------+------+------------+

  5、右连接(right join)

    右连接,在内连接的基础上保留右边的记录。

mysql> select * from book right join press on book.press_id = press.id;
+------+------------+----------+----+------------+
| id   | name       | press_id | id | name       |
+------+------------+----------+----+------------+
|    1 | 独孤九剑   |        1 |  1 | 华山出版社 |
|    2 | 华山剑法   |        1 |  1 | 华山出版社 |
|    3 | 九阳神功   |        2 |  2 | 少林出版社 |
|    4 | 九阴真经   |        2 |  2 | 少林出版社 |
|    5 | 易筋经     |        2 |  2 | 少林出版社 |
|    6 | 葵花宝典   |        3 |  3 | 明教出版社 |
|    7 | 乾坤大挪移 |        3 |  3 | 明教出版社 |
|    8 | 太极拳     |        4 |  4 | 武当出版社 |
|    9 | 天罡北斗阵 |        4 |  4 | 武当出版社 |
| NULL | NULL       |     NULL |  5 | 丐帮出版社 |
+------+------------+----------+----+------------+

  6、全外连接

    全外连接,在内连接的基础上保留左右两表没有对应关系的记录。

# 注意:mysql不支持全外连接 full JOIN
mysql> select * from book full join press on book.press_id = press.id;
ERROR 1054 (42S22): Unknown column 'book.press_id' in 'on clause'# 强调:mysql可以使用此种方式间接实现全外连接(自己实现全外连接的效果)
# union 连接两个以上的 SELECT 语句的结果组合到一个结果集合中。多个 SELECT 语句会删除重复的数据。
mysql> select * from book left join press on book.press_id = press.id-> union-> select * from book right join press on book.press_id = press.id;
+------+------------+----------+------+------------+
| id   | name       | press_id | id   | name       |
+------+------------+----------+------+------------+
|    1 | 独孤九剑   |        1 |    1 | 华山出版社 |
|    2 | 华山剑法   |        1 |    1 | 华山出版社 |
|    3 | 九阳神功   |        2 |    2 | 少林出版社 |
|    4 | 九阴真经   |        2 |    2 | 少林出版社 |
|    5 | 易筋经     |        2 |    2 | 少林出版社 |
|    6 | 葵花宝典   |        3 |    3 | 明教出版社 |
|    7 | 乾坤大挪移 |        3 |    3 | 明教出版社 |
|    8 | 太极拳     |        4 |    4 | 武当出版社 |
|    9 | 天罡北斗阵 |        4 |    4 | 武当出版社 |
|   10 | 吸星大法   |     NULL | NULL | NULL       |
| NULL | NULL       |     NULL |    5 | 丐帮出版社 |
+------+------------+----------+------+------------+

三、符合条件连接查询

  1、准备数据

# 咱们为book表新增单价字段
mysql> alter table book add price decimal(5,2) not null;
# 查看表结构
mysql> desc book;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| name     | varchar(32)  | YES  |     | NULL    |                |
| press_id | int(11)      | YES  | MUL | NULL    |                |
| price    | decimal(5,2) | NO   |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+
# 新增的字段,默认为0
mysql> select * from book;
+----+------------+----------+-------+
| id | name       | press_id | price |
+----+------------+----------+-------+
|  1 | 独孤九剑   |        1 | 60.00 |
|  2 | 华山剑法   |        1 |  0.00 |
|  3 | 九阳神功   |        2 |  0.00 |
|  4 | 九阴真经   |        2 |  0.00 |
|  5 | 易筋经     |        2 |  0.00 |
|  6 | 葵花宝典   |        3 |  0.00 |
|  7 | 乾坤大挪移 |        3 |  0.00 |
|  8 | 太极拳     |        4 |  0.00 |
|  9 | 天罡北斗阵 |        4 |  0.00 |
| 10 | 吸星大法   |     NULL |  0.00 |
+----+------------+----------+-------+
# 更新新增字段的值
update book set price=60 where id=1;
update book set price=30 where id=2;
update book set price=70 where id=3;
update book set price=40 where id=4;
update book set price=80 where id=5;
update book set price=40 where id=6;
update book set price=50 where id=7;
update book set price=80 where id=8;
update book set price=30 where id=9;
update book set price=40 where id=10;

  2、查询操作

# 示例1:
# 以内连接的方式查询book和press表,并且book表中的price字段值必须大于50,即找出单价大于50元的书籍以及书籍的出版社名称
mysql> select book.name,press.name from book inner join press on book.press_id =press.id where price > 50;
+----------+------------+
| name     | name       |
+----------+------------+
| 独孤九剑 | 华山出版社 |
| 九阳神功 | 少林出版社 |
| 易筋经   | 少林出版社 |
| 太极拳   | 武当出版社 |
+----------+------------+
#示例2:
# 以内连接的方式查询book和press表,并且以price字段的降序方式显示书籍名称、价格和出版社名称。
mysql> select book.name,book.price,press.name from book inner join press on book
.press_id = press.id order by price desc;
+------------+-------+------------+
| name       | price | name       |
+------------+-------+------------+
| 太极拳     | 80.00 | 武当出版社 |
| 易筋经     | 80.00 | 少林出版社 |
| 九阳神功   | 70.00 | 少林出版社 |
| 独孤九剑   | 60.00 | 华山出版社 |
| 乾坤大挪移 | 50.00 | 明教出版社 |
| 九阴真经   | 40.00 | 少林出版社 |
| 葵花宝典   | 40.00 | 明教出版社 |
| 华山剑法   | 30.00 | 华山出版社 |
| 天罡北斗阵 | 30.00 | 武当出版社 |
+------------+-------+-----------

四、子查询

#1:子查询是将一个查询语句嵌套在另一个查询语句中。
#2:内层查询语句的查询结果,可以为外层查询语句提供查询条件。
#3:子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
#4:还可以包含比较运算符:= 、 !=、> 、<等

  1、带in关键字的子查询

# 1、查询书籍平均价格在45元以上的出版社的id和名称
# 子查询
select id,name from presswhere id in(select press_id from book group by press_id having avg(price) > 45);# 连表查询
select press.id,press.name from press inner join book on press.id = book.press_id group by book.press_id having avg(book.price) > 45;# 2、查看少林出版社的所有书籍名称
# 子查询
select name from book where press_id in(select id from press where name = "少林出版社");# 连表查询
select book.name from book inner join press on book.press_id = press.id where press.name = '少林出版社';# 3、查询出版书籍数大于2的出版社名称
# 子查询
select name from presswhere id in(select press_id from book group by press_id having count(press_id) > 2);# 连表查询
select press.name from press inner join book on press.id = book.press_id group by book.press_id having count(book.id) > 2;

  2、带比较运算符的子查询

# 比较运算符:=、!=、>、>=、<、<=
# 查询大于所有书籍平均价格的书名与单价
select name,price from bookwhere price >(select avg(price) from book);# 查询大于出版社里平均价格的书名与单价
select name,price from book t1inner join (select press_id,avg(price) avg_price from book group by press_id) t2on t1.press_id = t2.press_idwhere t1.price > t2.avg_price;

  3、带exists关键字的子查询

# EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。
# 而是返回一个真假值。True或False
# 当返回True时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询# press表中存在name="少林出版社",Ture
mysql> select * from book->  where exists->  (select * from press where name="少林出版社");
+----+------------+----------+-------+
| id | name       | press_id | price |
+----+------------+----------+-------+
|  1 | 独孤九剑   |        1 | 60.00 |
|  2 | 华山剑法   |        1 | 30.00 |
|  3 | 九阳神功   |        2 | 70.00 |
|  4 | 九阴真经   |        2 | 40.00 |
|  5 | 易筋经     |        2 | 80.00 |
|  6 | 葵花宝典   |        3 | 40.00 |
|  7 | 乾坤大挪移 |        3 | 50.00 |
|  8 | 太极拳     |        4 | 80.00 |
|  9 | 天罡北斗阵 |        4 | 30.00 |
| 10 | 吸星大法   |     NULL | 40.00 |
+----+------------+----------+-------+

# press表中存在name="峨眉出版社",False
mysql> select * from book->  where exists->  (select * from press where name="峨眉出版社");
Empty set (0.00 sec)

五、综合练习(作业)

  1、准备数据

    表结构:

# 1、创建表
# 创建班级表
create table class(
cid int primary key auto_increment,
caption varchar(32) not null
);# 创建学生表
create table student(
sid int primary key auto_increment,
gender char(1) not null,
class_id int not null,
sname varchar(32) not null,
foreign key(class_id) references class(cid) on delete cascade on update cascade
);# 创建老师表
create table teacher(
tid int primary key auto_increment,
tname varchar(32) not null
);# 创建课程表
create table course(
cid int primary key auto_increment,
cname varchar(32) not null,
teacher_id int not null,
foreign key(teacher_id) references teacher(tid) on delete cascade on update cascade
);# 创建成绩表
create table score(
sid int primary key auto_increment,
student_id int not null,
course_id int not null,
num int not null,
foreign key(student_id) references student(sid) on delete cascade on update cascade,
foreign key(course_id) references course(cid) on delete cascade on update cascade
);# 2、插入记录
# 班级表插入记录
insert into class values
('1', '三年二班'),
('2', '三年三班'),
('3', '一年二班'),
('4', '二年一班');# 学生表插入记录
insert into student values
('1', '男', '1', '理解'),
('2', '女', '1', '钢蛋'),
('3', '男', '1', '张三'),
('4', '男', '1', '张一'),
('5', '女', '1', '张二'),
('6', '男', '1', '张四'),
('7', '女', '2', '铁锤'),
('8', '男', '2', '李三'),
('9', '男', '2', '李一'),
('10', '女', '2', '李二'),
('11', '男', '2', '李四'),
('12', '女', '3', '如花'),
('13', '男', '3', '刘三'),
('14', '男', '3', '刘一'),
('15', '女', '3', '刘二'),
('16', '男', '3', '刘四');# 老师表插入记录
insert into teacher values
('1', '张磊'),
('2', '李平'),
('3', '刘海燕'),
('4', '朱云海'),
('5', '李春秋');# 课程表插入记录
insert into course values
('1', '生物', '1'),
('2', '物理', '2'),
('3', '体育', '3'),
('4', '美术', '2');# 成绩表插入记录
insert into score values
('1', '1', '1', '10'),
('2', '1', '2', '9'),
('3', '1', '3', '76'),
('5', '1', '4', '66'),
('6', '2', '1', '8'),
('8', '2', '3', '68'),
('9', '2', '4', '99'),
('10', '3', '1', '77'),
('11', '3', '2', '66'),
('12', '3', '3', '87'),
('13', '3', '4', '99'),
('14', '4', '1', '79'),
('15', '4', '2', '11'),
('16', '4', '3', '67'),
('17', '4', '4', '100'),
('18', '5', '1', '79'),
('19', '5', '2', '11'),
('20', '5', '3', '67'),
('21', '5', '4', '100'),
('22', '6', '1', '9'),
('23', '6', '2', '100'),
('24', '6', '3', '67'),
('25', '6', '4', '100'),
('26', '7', '1', '9'),
('27', '7', '2', '100'),
('28', '7', '3', '67'),
('29', '7', '4', '88'),
('30', '8', '1', '9'),
('31', '8', '2', '100'),
('32', '8', '3', '67'),
('33', '8', '4', '88'),
('34', '9', '1', '91'),
('35', '9', '2', '88'),
('36', '9', '3', '67'),
('37', '9', '4', '22'),
('38', '10', '1', '90'),
('39', '10', '2', '77'),
('40', '10', '3', '43'),
('41', '10', '4', '87'),
('42', '11', '1', '90'),
('43', '11', '2', '77'),
('44', '11', '3', '43'),
('45', '11', '4', '87'),
('46', '12', '1', '90'),
('47', '12', '2', '77'),
('48', '12', '3', '43'),
('49', '12', '4', '87'),
('52', '13', '3', '87');

  2、练习题目

1、查询所有的课程的名称以及对应的任课老师姓名2、查询学生表中男女生各有多少人3、查询物理成绩等于100的学生的姓名4、查询平均成绩大于八十分的同学的姓名和平均成绩5、查询所有学生的学号,姓名,选课数,总成绩6、 查询姓李老师的个数7、 查询没有报李平老师课的学生姓名8、 查询物理课程的分数比生物课程的分数高的学生的学号9、 查询没有同时选修物理课程和体育课程的学生姓名10、查询挂科超过两门(包括两门)的学生姓名和班级11、查询选修了所有课程的学生姓名12、查询李平老师教的课程的所有成绩记录13、查询全部学生都选修了的课程号和课程名14、查询每门课程被选修的次数15、查询只选修了一门课程的学生学号和姓名16、查询所有学生考出的成绩并按从高到低排序(成绩去重)17、查询平均成绩大于85的学生姓名和平均成绩18、查询生物成绩不及格的学生姓名和对应生物分数19、查询在所有选修了李平老师课程的学生中,这些课程(李平老师的课程,不是所有课程)平均成绩最高的学生姓名20、查询每门课程成绩最好的课程id、学生姓名和分数
21、查询不同课程但成绩相同的课程号、学生号、成绩 

22、查询没学过“李平”老师课程的学生姓名以及选修的课程名称 

23、查询所有选修了学号为2的同学选修过的一门或者多门课程的同学学号和姓名 

24、任课最多的老师中学生单科成绩最高的课程id、学生姓名和分数

六、pymysql模块

  1、介绍

    之前我们都是通过MySQL自带的命令行客户端工具mysql来操作数据库,那如何在python程序中操作数据库呢?这就需要用到了pymysql模块,该模块本质就是一个套接字客户端软件,使用前需要事先安装一下。

pip3 install pymysql

  2、基本使用

import pymysqluser = input("user>: ").strip()
pwd = input("password>: ").strip()# 建立连接
conn = pymysql.connect(host='127.0.0.1',  # 如果是远程的数据库,输入远程IP port=3306,user='root',password='root123',db='db1',charset='utf8'
)# 注意:如果连接远程报1130错误,是远程连接权限问题引起的。
# 解决方法:# 允许任何IP地址(下面的 % 就是任何的意思)的电脑使用root用户和密码来访问这个MySQL Server 。# grant all on *.* to 'root'@'%' identified by 'root123';# 及时生效需执行# flush privileges;# 拿到游标
cursor = conn.cursor()# 执行SQL语句
sql = 'select * from userinfo where username = "%s" and password = "%s";' % (user, pwd)
rows = cursor.execute(sql)cursor.close()  # 关闭游标
conn.close()  # 关闭连接# 进行判断
if rows:print("登录成功!")
else:print("登录失败!")

  3、SQL注入

    这是数据库的userinfo表的数据。

    如图输入:用户名" -- xxxx,不用输入密码也能登录成功。

    有没有绕过用户名和密码的方法,也能SQL注入成功呢?答案是有,请看下图。

    为了解决上面的问题,请参考如下代码。

import pymysqluser = input("user>: ").strip()
pwd = input("password>: ").strip()# 建立连接
conn = pymysql.connect(host='127.0.0.1',  # 如果是远程的数据库,输入远程IP port=3306,user='root',password='root123',db='db1',charset='utf8'
)# 拿到游标
cursor = conn.cursor()# 执行SQL语句
# 去掉里面%s的双引号,不用自己字符串拼接。
sql = 'select * from userinfo where username = %s and password = %s;'
# pymysql模块自动帮我们解决sql注入的问题,只要我们将参数传入execute方法里,如下所示。
rows = cursor.execute(sql, (user, pwd))cursor.close()  # 关闭游标
conn.close()  # 关闭连接# 进行判断
if rows:print("登录成功!")
else:print("登录失败!")

  4、增、删、改(conn.commit())

import pymysql# 建立连接
conn = pymysql.connect(host='127.0.0.1',  # 如果是远程的数据库,输入远程IP port=3306,user='root',password='root123',db='db1',charset='utf8'
)# 拿到游标
cursor = conn.cursor
# 执行SQL语句
# 增
# sql = 'insert into userinfo(username, password) values(%s, %s)'# 删
# sql = 'delete from userinfo where username = %s and password = %s'# 改
sql = 'update userinfo set password = %s where username = %s'# 操作一条记录,用execute方法
# rows = cursor.execute(sql, (456, "alex"))# 操作多条记录,用executemany方法
rows = cursor.executemany(sql, [(222, "egon"), (333, "michael")])print(rows)  # 被影响的行数conn.commit()  # 注意一定要commit,提交同步到数据库。cursor.close()  # 关闭游标
conn.close()  # 关闭连接

  5、查(fetchone、fetchmany、fetchall)

import pymysql# 建立连接
conn = pymysql.connect(host='127.0.0.1',  # 如果是远程的数据库,输入远程IP port=3306,user='root',password='root123',db='db1',charset='utf8'
)# 拿到游标
# 这样取默认是元组的形式。如果字段比较多,不方便取值,我们可以通过设置游标,以字典的形式取值
# cursor = conn.cursor()
cursor = conn.cursor(pymysql.cursors.DictCursor)# 执行SQL语句
sql = 'select * from userinfo;'
rows = cursor.execute(sql)print(rows)  # 被影响的行数# 取一条记录
# cursor.scroll(2, mode='absolute')  # 相对绝对位置移动
print(cursor.fetchone())  # 取出一条记录,默认是从第一条取。上面设置后,这条记录id应为3# cursor.scroll(1, mode='relative')  # 相对当前位置移动,往后移动一条。
print(cursor.fetchone())  # 取出一条记录,上面设置后,这条记录id应为5
# print(cursor.fetchone())  # 超出范围不会报错,会显示None# 取多条记录
# print(cursor.fetchmany(2))# 取全部记录
# print(cursor.fetchall())cursor.close()  # 关闭游标
conn.close()  # 关闭连接

  6、新增时获取最后一条数据的自增ID

import pymysql# 建立连接
conn = pymysql.connect(host='127.0.0.1',  # 如果是远程的数据库,输入远程IP port=3306,user='root',password='root123',db='db1',charset='utf8'
)# 拿到游标
cursor = conn.cursor()# 执行SQL语句
# 增
sql = 'insert into userinfo(username, password) values(%s, %s)'# 操作一条记录,用execute方法
rows = cursor.execute(sql, ("bobo", 123))print(cursor.lastrowid)  # 在插入语句后查看,当前插入的第一条自增id号print(rows)  # 被影响的行数conn.commit()  # 注意一定要commit,提交同步到数据库。cursor.close()  # 关闭游标
conn.close()  # 关闭连接

转载于:https://www.cnblogs.com/Michael--chen/p/10795054.html

03-MySQL多表操作相关推荐

  1. 关于MySQL分表操作的研究

    关于MySQL分表操作的研究 一般来说,当我们的数据库的数据超过了100w记录的时候就应该考虑分表或者分区了,这次我来详细说说分表的一些方法.首先,我们需要想好到底分多少个表,前提当然是满足应用.这里 ...

  2. MYSQL数据库表操作pdf

    <MYSQL数据库表操作pdf> 下载地址: 网盘下载 转载于:https://www.cnblogs.com/long12365/p/9731023.html

  3. 数据库 MySQL 之 表操作、存储引擎

    数据库 MySQL 之 表操作.存储引擎 浏览目录 创建(复制) 删除 修改 查询 存储引擎介绍 一.创建(复制) 1.语法: 1 2 3 4 5 CREATE TABLE 表名(     字段名1 ...

  4. 【MySQL多表操作练习】

    多表操作练习 > > > MySQL基础 > > > MySQL的多表操作查询 > > > MySQL多表操作练习 > > > ...

  5. mysql多表操作语句_MYSQL数据库语句之多表操作(三)

    多表操作 join查询(join按照功能分可以分为3类): cross join(交叉连接):获取多个表中的交叉关系. inner join(内连接):获取2个表中字段匹配关系的记录. 外连接 lef ...

  6. qt mysql怎么选表_Qt的Mysql数据库表操作(1)

    Qt中的QSqlDatabase.QSqlQueryModel.QSqlRecord.QSqlTableModel等类为我们提供了快速开发数据库的方式,支持多种数据库连接,例如oracle,db2,M ...

  7. mysql怎么多表备份_学习MySQL多表操作和备份处理

    [IT168 服务器学院]前面我们熟悉了数据库和数据库表的基本操作,现在我们再来看看如何操作多个表. 多表操作 在一个数据库中,可能存在多个表,这些表都是相互关联的.我们继续使用前面的例子.前面建立的 ...

  8. 【MySQL】表操作和库操作

    文章目录 概念 库操作 1.创建数据库 2.删除数据库 3.选择数据库 4.显示数据库列表 表操作 1.创建数据表CREATE 2.删除数据表DROP 3.插入数据INSERT 4.更新数据UPDAT ...

  9. mysql数据表操作_MySQL数据表基本操作实例详解

    本文实例讲述了MySQL数据表基本操作.分享给大家供大家参考,具体如下: 数据表的基本操作 1.主键约束要求主键列的数据唯一,并且不允许为空.主键能够唯一地识别表中的一条记录,可以结合外键来定义不同数 ...

  10. MySQL多表操作的外键约束

    目录 一.多表关系 一对一关系 一对多/多对一关系 多对多关系 二.外键约束 特点 创建外键约束 方式1-在创建表时设置外键约束 方式2-在创建表时设置外键约束 在外键约束下的操作 1.数据插入 2. ...

最新文章

  1. 网格自适应_ANSYS自适应网格分析:2D矩形板的稳态热分析
  2. java接口是类型吗_JAVA中,接口到底是不是类
  3. 华为手机如何关闭通知栏推送消息_如果华为手机升级EMUI10后,电池耗电很快!要记得调整这3个设置...
  4. java中log4j的详解(转)
  5. Laravel-admin hasMany表单关联提交报错字段 无详细信息错误说明
  6. 卡巴斯基:风险无国界 网络安全从业者要与小网民保持一致
  7. 计算机网络之数据链路层:18、数据链路层设备
  8. 互站卖的分发美化版可以封装双端APP
  9. 从激活windows10家庭中文版到企业版再到开启Hyper-V
  10. [论文阅读] Annotation-Efficient Cell Counting
  11. dnf上海2服务器维护,DNF上海2出现大面积盗号并迅速蔓延请注意
  12. [转载] Python List index方法
  13. c++实现双向链表的常用功能
  14. UltraVNC源码编译运行
  15. 【Linux】Centos设置Python的软链接
  16. 在Windows下批量修改文件后缀(ren命令-rename)
  17. Java教程:Java使用POI将图片Base64编码写入到Excel表格当中
  18. swt 做界面时部分要点
  19. Percona 数据库
  20. python --深入浅出Apriori关联分析算法Apriori关联...

热门文章

  1. 记一次Linux系统内存占用较高得排查
  2. Winserver2012R2 部署密钥恢复代理
  3. Linux中读写权限
  4. Mongoose源码剖析:Introduction and Installation
  5. 这样的例子能说明if,else的效率比单单的if组合高
  6. querySelector querySelectorAll
  7. 技术以外的功夫 ----作者:李天平
  8. 同是程序员,不小心发现优点在于工作上10来年都保持【积极主动】的心态
  9. 46. AngularJS所有版本下载
  10. chcapter 2 量子力学介绍