Python—MySQL


数据库管理系统-DBMS(Database Management System)

     数据库管理系统(DBMS) 是一种操纵和管理数据库的大型软件,用于建立、使用和维护数据库,简称DBMS。
     它对数据库进行统一的管理和控制,以保证数据库的安全性和完整性。 用户通过DBMS访问数据库中的数据,数据库管理员也通过DBMS进行数据库的维护工作。它可使多个应用程序和用户用不同的方法在同时或不同时刻去建立,修改和询问数据库。
     种类:SqlServer, Oracle, sqlite, access, MySQL…


一、安装MySQL

window:https://dev.mysql.com/downloads/mysql/

下载-解压-加入环境变量

mysqld --initialize-insecure    # 初始化用户 id:root 没密码

使用方法1(手动运行):

mysqld    # 运行服务端
mysql -u root -p    # 运行客户端

使用方法2(默认开机运行mysql):

mysqld path --install    # 给windows安装mysql服务
mysqld path --remove    # 给windows移除mysql服务
# 若已加入环境变量:
mysqld --install
mysqld --remove

# Install/Remove of the Service Denied! 如果出现这个错误以管理员身份打开命令提示符(win10:右键开始-A)

启动/停止mysql服务:

net start mysql    # 在windows服务中启动mysql
net stop mysql    # 在windows服务中停止mysql
# 或者在任务管理器中启动/停止服务
# 如果报错,请用管理员身份打开命令提示符

二、MySQL数据库

1、概念

	数据库: database
	表: table
	行

2、默认数据库

	mysql: 用户权限相关
	test: 用户测试
	infomation_schema: MySQL本身构架相关

3、授权

用户管理特殊命令

    创建用户/修改密码:

create user 'name'@'IP_address' identified by 'password';   # 创建用户
drop user 'name'@'IP_address';    # 删除用户
rename user 'name'@'IP_address' to name@IP_address;    # 修改用户
alter user 'name'@'ip_address' identified by password;    # 新版修改密码
# set password for 'name'@'IP_address' = Password('new password');   # 旧版修改密码

用户登陆

mysql -u name -h 127.0.0.1 -p
# 输入密码
mysql -u root -p    # 没有-h 默认为localhost

赋予权限

show grants for 'name'@'IP'    # 查看权限
grant 权限 on 数据库.表 to 'name'@'IP'    # 授权
revoke 权限 on 数据库.表 from 'name'@'IP'    # 取消权限

"""
权限:
all privileges    除grant外的所有权限
usage             无访问权限
alter             alter table
alter routine     alter procedure/drop procedure
create            create table
create routine    create procedure
create temporary  create temporary tables
create user       create user/drop user/rename user/revoke all privileges
create view       create view
delete            delete
drop              drop table
execute           call/存储
file              select into oufile/load data infile
grant option      grant/revoke
index             index
insert            insert
lock tables       lock table
process           show full processlist
select            select
show databases    show databases
show view         show view
update            update
reload            flush
shutdown          mysqladmin shutdown
super             change master/kill/logs/purge/master/set global
replication client    服务器位置访问
replication slave    
"""

授权中使用通配符

create user 'name'@'192.168.1.%' identified by 'password';    # 表示name在192.168.1.下所有子网都可以登陆

三、数据表基础

1. 数据库操作

show databases;              # 显示所有数据库名称
create database db_name;     # 创建数据库
create database db_name default charset utf8 collate utf8_general_ci;   # 创建数据库设置编码
use db_name;                 # 进入数据库
drop database db_name;       # 删除数据库

2. 数据表操作

创建表

  1. 表 名 \color{red}{表名}
  2. 列 名 \color{red}{列名}
  3. 类 型 \color{red}{类型}
'''数值:'''
# 整数
bit [(n)]	# 二进制位,n表示二进制位的长度(1-64),默认为1
tinyint[(n)][unsigned][zerofill]	# 符号0 ~ 2^8-1
int [(n)] [unsigned] [zerofill]		# 有符号 -2^31 ~ 2^31-1, 无符号 0 ~ 2^32-1
bigint [(n)] [unsigned] [zerofill]  
# 小数
decimal		# 精确小数
	nid decimal(5, 10) # 保留10位小数,多出的四舍五入,少了用0补足
float:
double:
'''字符串:'''
# 定长
char	#
	# 长度以设置为准,浪费空间,但是查询速度相对较快
# 变长
varchar 
	# 节省空间,但是查找速度相对较慢
text
mediumtext
longtext
'''二进制数据:'''
TinyBlob、Blob、MediumBlob、LongBlob
	# 上传文件
	# Blob, 强制二进制方式
	# varchar(65), "D:\program" 将上传的文件保存到文件
	# 一般将文件路径保存到数据库,从数据库中取到路径操作文件
'''时间:'''
date
	# YYYY-MM-DD
time
	# HH:MM:SS
year
	# YYYY
datetime
	# YYYY-MM-DD HH:MM:SS
timestamp
	# YYYYMMDD HHMMSS
'''枚举enum'''
Enum week:
	x = 1001
	y = 1002
	z = 1003
print(Enum.x)	# 1001

create table shirts(
					nid int primary key,
					size enum('small', 'medium', 'large') not null
);
	# insert 插入时size 列只能从enum中选择一个
'''集合set'''
create table shirts(
			color set('blue', 'red', 'orange', 'green')
);
# insert插入时color列可以从set中选择1或多个
  1. 是 否 可 以 为 空 \color{red}{是否可以为空} :NULL/not NULL
  2. 默 认 值 \color{red}{默认值} :default 0
  3. 自 增 列 \color{red}{自增列} :auto_increment (自增列必须是键-索引)
  4. e n g i n e = i n n o d b \color{red}{engine=innodb} engine=innodb
  5. 默 认 编 码 \color{red}{默认编码} :default charset=utf8
 '创建表'     # 表名   列名 类型 是否可以为空 自增列 主键
create table tb_name(nid int,
					name varchar(20));
create table tb_name(nid int NULL default 0, 
					 name varchar(20) not NULL, 
					sex varchar(20) not NULL)engine=innodb default charset=utf8;
'设置自增列' # 自增列数据会随着数据插入自增,保证此列数据不重复
create table tb_name(nid int not NULL auto_increment primary key,
					 name varchar(20) NULL)engine=innodb default charset=utf8;
  1. 主 键 − 索 引 ( 加 速 查 找 ) \color{red}{主键-索引(加速查找)} ():primary key(一张表只能有一个主键,唯一不能重复,not NULL, 一般情况将自增列设置为主键)
         唯 一 列 − 约 束 \color{red}{唯一列-约束} :数据唯一但是可以为null
    可 以 多 列 组 合 成 唯 一 列 或 主 键 列 \color{blue}{可以多列组合成唯一列或主键列}
create table tb_name(nid int not NULL auto_increment,
                     name varchar(20) NULL,
                     gender varchar(20),
                     primary key(nid, name)
)engine=innodb default charset=utf8;
  1. 外 键 \color{red}{外键} :两张表建立约束, 一对多
	# 创建表1 -- 学号 名字 年龄 班级id
create table student1(nid int not null auto_increment primary key,
                      name varchar(20) not null,
                      age int not null,
                      class_nid int not null)engine=innodb default charset=utf8;
# 创建表2 -- 班级id 班级名称
create table class(nid int not null auto_increment primary key,
                    c_name varchar(20) not null)engine=innodb default charset=utf8;
'''创建表后添加表关联'''
alter table student1 add constraint fk_s_c foreign key student1(class_nid) references class(c_name);
'''此时添加表1数据中class_nid如果没有在表2中的nid,语句会报错'''


'''创建表时直接建立关联'''
# 先创建表1 -- 班级id 班级名称(代码如上)
# 创建表2
create table student1(nid int not NULL primary key,
                    name varchar(20) not null,
                    age int not null,
                    class_nid int not null,
                    constraint fk_s_c foreign key (class_nid) references class(nid)
)engine=innodb default charset=utf8;

表操作

show tables;             # 显示所有表
desc tb_name;            # 显示表描述
drop table tb_name;      # 删除表
delete from tb_name;     # 清空表内容
truncate table tb1;      # 清空表内容,自增回到原点
select * from tb_name;   # 查看表内容
'''修改列'''
alter table 表名 add 列名 类型;                # 添加列
alter table 表名 drop column 列名;             # 删除列
alter table 表名 modify column 列名 类型;      # 修改类型
alter table 表名 change 原列名 新列名 类型;     # 修改列名和类型
'''修改主键'''
alter table 表名 add primary key(*列名);        # 添加主键
alter table 表名 drop primary key;              # 删除主键
alter table 表名 modify 列名 int, drop primary key;    # 删除主键
'''修改外键'''
alter table 从表 add constraint fk_1_2 foreign key 从表(字段) references 主表(字段);
alter table 表名 drop foreign key 外键名称;
'''修改默认值'''
alter table 表名 alter 列名 set default 1000;
alter table 表名 alter 列名 drop default;

3. 数据行操作

insert into tb_name(name, age) values('wolf', 25);
# 增加多行
insert into tb_name(name, age) values('wolf', 25), ('name2', 18), ('name3', 20);
# 从一个表复制到另外一个表
insert into 表1(列,列,列) select 列,列,列 from 表2		# 两个表对应列必须数据类型一样或者可转换

delete from 表 where 列=value;
delete from 表 where nid>3;
> < = != and or

udpate 表 set name='wolfx',age=22 where name='wolf' and age>25;

select * from;
select * from 表 where nid>5;
select nid, name from;

其它*

1. 条件

select * from 表 where nid > 4 and name != 'wolf' and age > 18;
							    age not in (27, 28, 29);
							    age in ( 12, 15, 18);
							    age in (select age from);
							    age between 21 and 29;

2. 通配符 -模糊匹配

select * from 表 where name like 'wolf%';	# 以wolf开头的多个字符
								 '%lf_'; 	# 以wolf开头的一个字符

3. 分页

select * from 表 limit 7;		# 表前7行
					   7, 11;	# 表7 ~ 18行, 从第7行开始的11行
					   11 offset 7;	# 表7 ~ 18行

4. 排序

select * from 表 order by nid asc;	# 按nid排序,顺序
							  desc  # 按nid排序,逆序
select * from 表 order by nid asc, name desc;	# 先按nid顺序,相同的再按name逆序

5. 分组

# 按nid分组
select nid from 表 group by nid;	
# 按名字分组后取出最高成绩
select name, max(score) from 表 group by name;	
# 按名字分组后计算总成绩,最低分数,计数各id数量,并给表头重命名
select name, sum(score) as a_score, count(id) as c_id, min(score) from 表 group by name;	
# 对于使用聚合条件取到的数据,要使用having进行匹配,不能用where
select name, sum(score) as a_score from 表 group by name having a_score > 650;	

6. 组合

select nid from1 union select nid from2;	# union 联合显示2张表的数据,默认去重
select nid from1 union all select nid from2;	# union all 不去重

7. 连表**

select * from1,2;		# 将表2所有数据与表1每行数据对应显示
select * from1,2 where 表1.=2.;	# 显示表1某列与表2某列对应相等时的数据
select * from1 left join 表2 on 表1.=2.;		# 主表在前
# 可以连接多个表
select * from1 left join 表2 on 表1.=2.列 
left join 表3 on 表1.=3.列 
left join 表4 on 表2.=4.;
select * from2 inner join 表1 on 表1.=2.;	# 在left join基础上去掉Null数据
# 优先用left join ,效率更高

8. 临时表**

select 表1.nid, tb2.name from (select nid from2) as tb2 left join 表3 on 表1.nid > 18;

9. 去重distinct

# 查询哪些学生有得分记录,可能有多门选课,去掉重复项
select distinct student_id from score;

10. avg

# 计算分组之后某列数据各组的平均值
select avg(num) from score group by student_id having avg(num)>60;

11. 试图view

# 将临时表创建为试图,下次调用时直接调用v_name作为临时表名字即可,mysql会自动解析v_name的sql语句
create view v_name as 
	select 表1.,2.from1 left join 表2 on 表1.=2.;
# 直接调用v_name
select v_name.from v_name;

12. 存储过程

# 存储过程(写在客户端,类似一个函数,在客户端中直接调用)
delimiter //		# 将;终止符修改为//
create procedure p_name()
begin
	select * from;
end //
delimiter;		# 将//终止符改回;

# 取出存储结果
call p_name()

4. 报错处理

ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'xxxxx' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

翻译:错误1055(42000):选择列表的表达式#2不在GROUP BY子句中,并且包含非聚合列‘xxxxxx’,该列在功能上不依赖于GROUP BY子句中的列;这与sql_mode=only_full_group_by不兼容

意思是: s e l e c t \color{red}select select中选择显示的列名必须有出现在 g r o u p \color{red}group group b y \color{red}by by后面的


四、Python中使用pymysql

1. 安装pymysql

pip install pymysql

pymysql: 专门用来操作MySQL的python模块

2. 操作

import pymysql


# 创建连接
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='test', charset='utf8')
# 创建游标
# cursor = conn.cursor()	# 查看数据时获取到的数据为元组
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)		# 取数据时将数据改为字典形式
# 执行SQL,并返回影响行数
effected_row = cursor.execute('insert into table values('xxx', xxx)')
# 提交操作
conn.commit()

new_nid = cursor.lastrowid		# 获取最新的一条自增列数据
print(new_nid)

# 关闭游标
cursor.close()
# 关闭连接
conn.close()

3. 注意事项*

  1. 一种错误的插入字符串的方式:
import pymysql


# 创建连接
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='test', charset='utf8')
# 创建游标
cursor = conn.cursor()	

data = input('请输入成绩:')
sql = 'insert into table(name) values('%s')'%data
# 执行SQL,并返回影响行数
effected_row = cursor.execute(sql)

# 提交操作
conn.commit()
# 关闭游标
cursor.close()
# 关闭连接
conn.close()

以上操作会造成 S Q L 注 入 \color{orange}SQL注入 SQL,是 绝 对 不 能 使 用 \color{red}绝对不能使用 使的。

别 人 可 能 不 需 要 密 码 就 能 登 陆 数 据 库 , 并 获 取 数 据 库 内 容 \color{blue}别人可能不需要密码就能登陆数据库,并获取数据库内容


'''用户登陆'''

import pymysql


# 创建连接
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='test', charset='utf8')
# 创建游标
cursor = conn.cursor()

S Q L 注 入 : \color{orange}SQL注入: SQL

sql = "select * from table where user_id='%s' and pwd='%s'"	# 可以取到数据

# 执行SQL,并返回影响行数
effected_row = cursor.execute(sql)

user_id = "xxx' or 1=1 --"
pwd = '000'
sql = sql%(user_id, pwd)
sql = "select * from table where user_id='xxx' or 1=1 --' and pwd='000'"	
# -- 在mysql中为注释语句,会注释后面的条件,1=1为已成立条件
'''输入数据时,在数据中加入绝对成立的条件,和注释符号 -- ,会改变sql语句,从而导致数据库侵入'''

# 提交操作
conn.commit()
# 关闭游标
cursor.close()
# 关闭连接
conn.close()
  1. 正确的参数传递方式:
data = input('请输入成绩:')
# 执行SQL,并返回影响行数
effected_row = cursor.execute('insert into table(name) values(%s)', data)
# 多条参数
effected_row1 = cursor.execute('insert into table(nid, name, age) values(%s, %s, %s)', (1, 'wolf', 25))
# 多列参数
list1 = [(2, 'Peter', 22), 
(3, 'Michale', 21), 
(4, 'Lion', 23)]
effected_row1 = cursor.executemany('insert into table(nid, name, age) values(%s, %s, %s)', list1)

其余SQL操作替换掉SQL语句即可

  1. 查看数据表内容
data = cursor.execute('select * from table')

# res = data.fetchone()		# 取第一条数据
# res = data.fetchmany(4)	# 取4条数据,以一个元组输出,即使是一条数据
res = data.fetchall()
'''取数据时会移动指针'''
print(res)

# 移动指针
cursor.scroll(0, mode='abssolute')	# 指针直接回到多少行,绝对
cursor.scroll(1, mode='relative')	# 指针向下走一行,相对
cursor.scroll(-1, mode='relative')	# 指针向上走一行,相对
''' '''
'''查看数据不需要提交操作'''
# conn.commit()
# 关闭游标
cursor.close()
# 关闭连接
conn.close()

4.Pymysql中执行存储过程

# 执行存储过程 (客户端)
coursor.callproc('p_name')
# 取出数据
res = cursor.fetchall()
print(res)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值