MYSQL数据库应用详解

常用工具


  1. window : mysql workbench、 navicat、sqlyog、heidisql、mysql front
  2. linux : mysql workbeanch 、navicat
  3. linux : mysql workbeanch 、navicat

架构演变


  1. 架构1.0 - 单机单库
    • 数据量太大、超过一台服务器承受范围
    • 读写操作量大,超出一台 服务器承受
    • 一台服务器挂了,应用也会挂掉(可用性差
  2. 架构 2.0 - 主从架构
    • 读写分离
    • 保证服务的可用
    • 数据量太大超过一台服务器
    • 写操作太大超出一台服务器的性能
  3. 架构 3.0 - 分库分表
    • 写操作太大超出一台服务器的性能
    • 数据如何路由是一个关键问题,一般采用范围拆分,list拆分,hash拆分
    • 如何保持数据一致性是一个难题
  4. 架构 4.0 - 云数据库
    • 使用Saas服务,服务提供商负责解决可配置性,可扩展性,多用户存储 接哦古涉及 等难点问题

SQL基本使用


SQL约束
约束 约束表达式 备注
主键 primary key
非空 not null
唯一 unique
默认 default
外键 foreign key
常用关键字
关键字 含义 备注
distinct 去除重复项
like 模糊查询(% 任意多个字符 , _ 一个任意字符)
in 非连续范围内
between … and … 一个连续的范围内
count(*) 统计总行数
max() 求最大值
min() 求最小值
sum(列) 求和
avg(列) 求平均数
group by 将查询结果按照1个或者多个字段进行分组,字段值相同的一组
group by + having 分组后查询指定条件输出的查询结果
having 只能用于group by
order by 排序 (asc升序 desc降序)
SQL 增删改查
# 连接数据库
mysql -u"用户名" -p
$pwd

# 数据库退出
quit

# 查看数据库
show databases;

# 查看数据库版本
select version()

# 显示时间
select now();

# 创建数据
create database `python01` charset="utf-8";

# 展示数据库创建语句
show create database "database03"

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

# 使用数据库
use "数据库名称";

# 删除数据库
drop database "数据库名称";

# **数据库表的操作**
# 查看当前数据库中所有表
show tables;

# 创建表
# auto_increment表示自动增长
# not null 表示不能为空
# primary key 表示主键
# create table 数据库名称(字段 类型 约束 [字段 类型 约束]);
create table demo(id int,name varchar(20));

# 查看表结构
desc "表名";

# 创建 students 表(id、name、age、high、gender、cls_id)
create table students(
	id int not null primary key auto_increment,
	name varchar(30),
	age tinyint unsigned default 0,
	high decimal(5,2),
	gender enum('男','女','中性','保密') default '保密',
	cls_id int unsigned
	);

# 表中插入数据
insert into student values(0,"老王",18,175.88,"男",1);
select * from student;

# 查看表的创建语句
show create table students

# 修改表 - 添加字段
# alter table 表名 add 列名 类型;
alter table students add birthday datetime;

# 修改表- 修改字段 : 不重名命名 - 修改字段类型 + 约束
# alter table 表名 modify 列名 类型及约束
alter table students modify birthday date dafault '1997-01-01'

# 修改表- 修改字段 : 重名命名 - 改变字段的名称
# alter table 表名 change 原名 新名 类型及约束;
alter table students change birthday birth date dafault '1997-01-01'

# 修改表 - 删除字段
# alter table 表名 drop 列名;
alter table students drop high;

# 删除表
drop table "表名";
drop database "数据库";
drop table "数据表";


**# 新增**

# 全列插入   insert [into] 表名 values(...)
# 主键字段 - 可以用 0 null default 来占位
# 向 classes 表中插入一个班级
insert into class values(0,"python")   # 0 是 id位置 用 0 表示自增 

# 枚举类型的插入 1-男   2-女
insert into students values(0,'tony',18,1,1,'1997/01/01');

# 部分插入
# insert into 表名(列1,...) values(值1,...)
insert into students(name,gender) values("小乔",2);

# 多行插入
insert into students(name,gender) values("小乔",2)("周瑜",1)("孙策",1);

**#修改**
# update 表名 set 列1=值1,列2=值2...where 条件;
update students set age=18;   # 全表修改
update students set age=28 where name = "tony";   # 条件筛选修改

# 物理删除
# delete from 表名 where 条件
delete from students where name = 'tony';

# 逻辑删除 - 用一个字段表示此条数据已经不能在再用  例如 :is_delete字段
alter table students add is_delete int default 0 ;
updata students set is_delete = 1 where id = 6**# 基本查询**
# select 去重选项 字段列表[as 字段名] from 数据表 where [group by 子句] [having 子句] [order by 子句 ] [order by 子句] [limit子句];
# 查询全部
select * from students;
# 去除重复字段查询
select distinct name from students;
# 查询指定列
select id,name from students;
# 可以使用 as 为列或表指定别名 
select id, cls_id as "班级" from students;
select student.name as "姓名" from students;

#数据库数据查询

# 从 第10行开始获取20行数据,
# 分页(从start开始,获取count条数据)
select * from students limit 10,20; 

# join查询连接查询
select * from table1 inner join table2 on table1.firstid = table2.secondid;
select * from table1 left join table2 on table1.firstid = table2.secondid;
select * from table1 right join table2 on table1.firstid = table2.secondid;

# 子查询
select * from students where height = (select max(height) from students);

# 创建数据表
create table student(sid int(4) not null primary key,sname varchar(36),gid int(4) not null);
# 添加外键
alter table tablesname add constraint prinaryname foreign key(id) references table2(idname)
# 删除外键
alter table tablename1 drop foreign key prinaryname1;


**# 比较运算符**
>	# 大于
<	# 小于
>=	#大于等于
<=	#小于等于
!=	/ <>	# 不等于


**# 逻辑运算符**
and	# 和
or	# 或者
not	# 非/取反


**# 模糊查询**
# like
# %  替换1个或者多个
# _ 替换1个


# 查询姓名中 以 "李" 开始的名字
select * from students where name like '李%';
# 查询姓名中 带有 "李" 开始的名字
select * from students where name like '%李%';
# 查询有2个字的名字
select * from students where name like '__';
# 查询至少有2个字的名字
select * from students where name like '__%';

# where 子句(条件)范围查询 
# in 表示在一个非连续的范围内
select * from students where id in(1,3,8);
select * from students where id not in(1,3,8);

# between...and... 表示在一个连续的范围内
select * from students where id between 3 and 8;
# id 3-8 男生
select * from students where id between 3 and 8 and gender=1;
select * from students where id not between 3 and 8 and gender=1;

# 判断为空 is null
# 非空  is not null
# 查询 cls_id 为空的数据
select * from students where cls_is is null;


**# 聚合函数**
# 总数  count()
# 查询学生总数
select cout(*) from students;
# 查询男性有多少人
select cout(*) as "男性人数" from students where gender = 1;

# 最大值/最小值  max / min
select max(age) from students;
# 查询男性 ID的最大值
select max(id) from students where gender=1;
# 查询女性的最高身高
select max(height) from students where gender = 2;

# 求和 sum()
# 查询男生的年龄和
select sum(age) from students where gender =1;

# 平均值 avg()  默认保留4位
# 查询未删除女生的ID的平均值
select avg(id) from students where gender=2 and is_delete=0;

# 四舍五入 round(123.23,1) 保留 1 位小数
# 计算所以人的平均年龄,保留2位小数
select round(ave(age),2) from students;

# 分组 group by 
# 按照性别分组,查询所有的性别
select gender from students group by gender;

# 计算男生和女生的人数
select gender as "性别"count(*) from students where gender = 1;
select gender as "性别"count(*) from students where gender = 2;

select gender as "性别"count(*) from students group by gender;

# 男女同学最大年龄
select gender as "性别"max(age) from students group by gender;

# group_concat() 查看组内信息 ( 把所有内容写在同一个格子里)
# 查询同种性别中的姓名
select gender as "性别"max(age),group_concat(name) from students group by gender;
# 查询组内年龄,姓名(name + age) 写在同一框格中
select gender as "性别",group_concat(name,age) as "组内姓名" from students group by gender;

# having  分组之后的筛选
# 查询男生女生总数大于2s
select gender as "性别",count(*) from students group by gender having count(*) > 2;
# 查询男生 女生 总数大于 2 的姓名
select count(*),group_concat(name) from students group by gender having count(*) > 2;
# 查询平均年龄超过18岁的性别,以及姓名 having age(age) > 18
select gender,group_concat(name),avg(age) from studernt group by gender having avg(age) > 18;

# 数据库排序 order by / asc 从小到大排列,即升序,默认 / desc 降序
# 查询年龄在 18-26 岁之间的男同学 ,按照年龄从小到大排序
select * from students where age between 18 and 26 group by gender having gender =1 order by age;
select * from students where age between 18 and 26 and gender =1 order by age;

# 查询年龄在 18-34 岁之间的女同学,身高从高到矮排序
select * from students where age bewteen 18 and 34 and gender =2 order by height desc;

# order by 多个字段
# 查询年龄在18-28之间,女性,身高从高到矮,如果身高相同 按年龄从小到大排列
select * from students where age bewteen 18 and 28 and gender = 2 order by height descc,age asc;
# 按年龄从小到大,身高从高到矮
select * from students order by age asc,height desc;


# 分页 limint start count
# 限制查询出来的结果
select * from students limit 2;		# 查询前两条数据
select * from students limit(3,5);	 # 从3位置开始 查询5条数据

# 数据库的连接查询
inner join ...on  # 内连接
select * from students inner join classes on students.cls_id = class.id;
# 按照要求显示姓名、班级
select students.name,classed.name from students inner join classes on students.cls_id = class.od;
left join ...on  # 左连接
light join ...on  # 右连接

**# 子查询**
# 查询最高的男生的信息
select * from students where height = (select max(height) from students where gender =1 );
# 查询高于平均身高的信息
select * from students where height > (selecct avg(height) from students);

# 自关联 - 省市区三级联动
select * from provinces as p inner join cities as c on p.'provinceid' = c.'provineid' having p.province ="吉林省"

视图 增删改查
# 视图创建
create view v_stu_score as (select * from table1);
# 视图查看(查看表时会显示所有视图)
show tables;
# 使用视图((v_stu_score 视图名))
select * from v_stu_score;
# 删除视图
drop view v_stu_sco;

SQL 索引
  1. 定义 : 索引是一种特殊的文件(InnoDB 数据表上的索引是表空间的一个组成部分),包含着对数据表里所有记录的引用指针
  2. 效率 :300 万左右数据量,可以提高一倍的查询效率
  3. 索引建立 :
    • 主键自动建立索引
    • 频繁作为查询条件的字段因该建立索引
    • 查询中与 其他表关联的字段,外键关系建立索引
    • 在高并发的情况下创建复合索引
    • 查询中排序的字段、排序字段若通过索引去访问大大提升排序速度(建立索引的顺序跟排序的顺序保持一致)
# 查看索引
show index from "表名"# 创建索引
create [unique] index "索引名称" on "表名(字段名称(长度))"
create index idx_name on students(name(30));  # 单值索引
# 删除索引
drop index "索引名称" on "表名"; 

SQL 事务

事务:就是一系列的操作,一旦出现问题则进行回滚

#事务开启
begin "或" start transaction
# 事务提交
commit;
# 回滚事务
rollback;
SQL 权限控制
# 查看user表结构
desc user;
# 查看所有用户
select host,user,authentication_string from user;
# 创建账号& 授权
grant 权限列表 on 数据库 to '用户名'@'访问主机' identified by '密码';
# 退出root登陆
quit
存储引擎
  • 存储引擎 Innodb : 最大程度的支持并发

    使用表空间进行数据存储 (on/off)

    系统表空间会产生I/O瓶颈,刷新数据的时候是顺序进行的,所以会产生 I/O 瓶颈,独立空间可以同时向多个文件刷新数据

    支持外键、支持事务、行级锁最大程度支持并发,缓存索引、缓存真实数据、表空间大

    # 查看存储引擎
    show engines;
    show variables like 'innodb_file_per_table' # 查看是否独立表空间
    set global innodb_file_per_table = off    # 关闭独立表空间
    
  • 存储引擎 MyISAM : 适合非事务应用,只读类应用

    支持表数据压缩(linux),压缩后只能读,不能写

    不支持外键,不支持事务

    表级锁,不适合高并发

    只缓存索引,不缓存真实数据

    表空间较小

    myisampack -b -f myIsam.MYI 
    # 表损坏修复
    reapir table "表名";
    
  • 存储引擎 CSV : 文本存储表的内容

    .CSM 文件存储表的元数据,如表的状态、数据量等

    .frm 文件存储表结构信息

    适合做数据交换的中间表

    不支持主键,不支持自增长,所有列不能为空

  • 存储引擎 Memory : 内存型

    支持 hash(用于等值查找)、btree索引(范围查找)

    所有字段长度固定

    不支持 BLOB 和 text 等大字段

    使用表级锁

    重启后数据会小时

服务架构说明

  1. 网络链路层
    • 能够与mysql服务器建立链接的客户端(java、C、python、.net)
  2. 服务层(msyql server)
    • 包含系统管理和控制工具、链接池、SQL接口、解析器、查询优化器、缓存
    • 链接池 : 负责存储和管理客户端的数据路链接,一个线程负责管理链接
    • 系统管理和控制工具 :备份恢复、安全管理、集群管理
    • SQL接口 :接口客户端发送过来的sql命令,并返回查询结果。
    • 解析器 :负责将请求的 SQL 解析生成一个 解析树,然后根据mysql规则进行检查树是否合法。
    • 查询优化器 :当解析树 通过解析器语法检查后,交给优化器及逆行转化成执行计划,然后与存储引擎交互
    • 缓存 : 小缓存组成(表缓存、记录缓存、权限缓存、引擎缓存)、如果查询缓存名中,则执行查询缓存
  3. 引擎层
    • 存储引擎层 :负责数据的存储和提取
  4. 系统文件层
    • 负责数据库的数据和日志存储在文件系统中,并完成与存储引擎的交互
    • 日志文件、数据文件、配置文件、pid文件、socket文件
  5. 日志文件
    • error log 日志 : 错误日志 ( show variables like %log_err%)
    • 慢查询日志 :记录一般查询语句 ( show variables like %general% )
    • 二进制日志 (binary log):记录对数据库的执行更改记录语句发生时间,执行时长,用于数据库恢复 和主从复制。( show binary logs )
    • 慢查询日志 (Slow query log)
  6. 配置文件
    • 用于存放 mysql所有配置信息文件、比如my.cnf、my.ini等
  7. 数据文件
    • db.opt 文件 : 记录这个库默认使用的字符集和校验规则
    • frm 文件 :存储 与相关的元数据信息,包括表结构的定义信息,每一张表都会有 一个frm文件
    • MYD文件 :MySAM存储引擎专用,存放MySAM表的 数据,每一张表都会有一个 .myd文件
    • MYI文件 :MySAM存储引擎专用,存放MySAM表 的索引相关的信息,每一张表都会有一个 .myi文件
    • ibd 文件和IBDATA文件 : 存放InnoDB的数据文件(包括引擎)。InnoDB存储引擎有两种表空间方式 :独立表空间,共享表空间 独享表空间使用.ibd文件夹存放数据,且每一张InnoDB表对应一个.ibd表对应一个 .ibd文件。共享表空间 使用.ibdata文件,所有表共享使用一个(或 多个、自行设置).ibdata文件
    • ibdata1 文件 :系统表空间数据文件,存储表 元数据,Undo日志等
    • ib_logfile0、ib_logfile1文件、Redo log日志文件
    • pid文件 :进程文件,存放自己的进程id
    • socket文件 :客户端可用不 通过TCP/IP 网络而 直接使用socket链接数据库

日志说明


undo log

数据库事务开始前,将要需修改的记录存放在Undo日志里,当事务回滚时,数据崩溃时,可以利用Undo日志,撤销未提交事务 对数据库产生影响

Undo Log 产生和销毁 : Undo Log在事务开始前产生,事务在提交时,并不会立刻删除undo log , innodb会将该事务对那个的undo log放入到 删除列表中,后面会通过后台线程 purge thread进行回收处理。Undo Log 属于逻辑日志,记录一个变化 过程,发生一个动作会记录一个相反的 updata

Undo Log 存储 :采用段的方式进行管理和记录

Redo Log

以恢复操作为目的,在数据库发生意外时重新操作

在事务中修改任何数据,将最新的数据 备份存储的位置

随着事务操作执行,就 会生成,在事务提交时 会产生写入Log Buffer,而 不是将事务 提交立刻写入磁盘文件

随着事务的提交就立刻写入磁盘文件

Redo log工作原理

  • 实现事物的持久性而出现的产物。防止发生故障时,尚有脏页没有写入到 IBD文件中,重启mysql服务时,根据Redo log 进行重做,从而达到事物未吸入磁盘数据的持久化特性
  • 写入机制 :以顺序循环的方式写入文件,写满是则回溯到第一个文件,进行覆盖写
  • redo log 相关配置参数 :show variables like ‘%innodb_log%’;

Bin log 日志

redo log 属于 innodb引擎所特有的日志,而 mysql server也有自己的日志,叫做binary log(二进制文件) 简称 bin log

记录数据表结构变更及表数据修改的二进制日志

以事件形式记录,包含语句所执行的消耗时间

应用场景 : 主从同步(开启 bin log,传递给从库)、数据恢复

文件记录模式 row模式(对每一行进行记录,批量操作是日志量巨大)

statment 模式(每条记录的sql都会就在master的 binlog中,在sql中含有变量时,比如last inset id 等时,不可靠)

mixed 模式(正常用sql,识别用 row模式)

# binlog 状态查询(开启状态)
show variables like 'log_bin';

# 开启bin log 文件 需要修改 my.cnf 或my.ini配置文件,在增加 log_bin = mysql_bin_log,重启mysql服务
# log-bin = ON
# log-bin-basename=mysqlbinlog
binlog-format=ROW
log-bin = mysqlbinlog

# 使用show binlog events命令
show binary logs; // 展示 bin log 文件
show master status// 现在使用的 bin log文件
show binlog events; // 包含哪些事件
show binlog events in ‘mysqlbinlog.000001;

# 系统cmd下查看 binlog文件
mysqlbinlog “文件名”
mysqlbinlog “文件名” > 'test.sql'

# 使用 binlog恢复数据
# 按指定时间恢复
mysqlbinlog -- start -datetime =  -- stop-datetime=“2020-11-10 18:00:00” mysqlbinlog.00002 | mysql -uroot -p1234
# 按事件位置号恢复
mysqlbinlog -- start -position=154  stop-position=957 mysqlbinlog.00002 | mysql -uroot -p1234


# 删除binlog文件
purge binary logs to 'mysqlbinlog.00001';  // 删除指定文件
purge binary logs before '2020-11-10 18:00:00'; //删除指定时间之前的文件
reset master; // 清除所有文件

MYSQL主从配置


master 将改变记录到二进制日志。这些记录过程叫做二进制日志事件,binary log events.

slave 将 master 的binary log events 拷贝到它的中继日志

slave 重做中继器日志中的事件,将改变应用到自己的数据库中,mysql复制是异步的且串行

# 主机配置文件 - my.ini 
# 开启二进制日志
# log-bin = 自己本地的路径/mydqlbin 
log-bin = mysql-bin
# 指定主服务器ID
server-id =1
# 需要从新启动服务

# 从机配置文件 - mysqld.cnf
server-id = 2  # 不要和主服务器ID重复
log-bin = /自己本地的路径/mysql-bin.log
service mysql restart  # 重启服务

# MySQL8.0主从配置 对从机进行授权
# 192.168.0.183 为从机IP
# 用户名 repl    密码 : 123
CREATE USER 'repl'@'192.168.0.183' IDENTIFIED WITH mysql_native_password BY '123';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.0.183';

show master status;
# 展示 :( file:mysql-bin.000004   Position : 680 )

# 对从机进行配置
# 主机IP地址
change master to master_host = '192.168.0.161',
# 主机用户名
master_user = 'juran',
# 密码
master_password = '123',
master_log_file = 'binlog.000004',
master_log_pos= 908;

数据库的分区


定义 :根据某个区间值,特定值 或 hash函数执行数据的聚合,让那个数据根据规则分布在不同的分区中

类型 :Range分区、List分区、Hash分区

注意事项 :避免跨分区查询、最好在where从句中包含分区值,具有唯一索引的表,主键或唯一索引必须是分区键的一部分

partition	# 分区
# 查看数据库支持项
show plugins;

# 数据库分区特点
# 逻辑上为一个表,在物理上存储在多个文件中
create table `login_log`(
	login_id int(10) unsigned not null comment '登录用户id',
	login_time timestamp not null default current_timestamp,
	login_ip int(10) unsigned not null comment '登录ip'
	)engine=innodb default charset=utf8 
	partition by hash(login_id) partitions 4;   # 将这个表划分4个分区


# 删除分区(表中的数据也会删除)
alter table login_log_list drop partition p0;

 # 分区的数据迁移(p1分区数据迁移到table arch_login_log_list )
 alter table login_log_list exchange partition p1 with table arch_login_log_list;

Range分区

根据键值的范围,将数据存储到表的不同分区中

分区需要连续,但是不能重叠,分区不包含上限值,包含下限值

常用分区 日期,时间,可以定期按分区记性清理历史数据

# 建立Range分区
create table `login_log_range`(
	login_id int(10) unsigned not null comment '登录用户ID',
	login_time timestamp not null default CURRENT_TIMESTAMP,
	login_ip int(10) unsigned not null comment '登录ip'
	)engine=innodb
	partition by range(login_id)(
	partition p0 values less than(10000), # 实际范围0-9999
	partition p1 values less than(20000), # 实际范围10000-19999
	partition p2 values less than(30000),
	partition p3 values less than maxvalue # 存储大于30000的数据
);
Hash 分区

根据 mod (分区键、分区值)把数据行存储到表的而不同分区内

数据可以平均分布在各个分区

Hash分区的键值必须是 INT 类型的值,或者通过函数可以转化为 INT类型

# 建立Hash分区表
create table `login_log`(
	login_id int(10) unsigned not null comment '登录用户ID',
	login_time timestamp not null default CURRENT_TIMESTAMP,
	login_ip int(10) unsigned not null comment '登录ip'
	)engine=innodb default charset=utf8 
	partition by hash(login_id) partitions 4;

# 时间类型用函数转化为整数
create table `login_log`(
	login_id int(10) unsigned not null comment '登录用户ID',
	login_time timestamp not null default CURRENT_TIMESTAMP,
	login_ip int(10) unsigned not null comment '登录ip'
	)engine=innodb default charset=utf8 
	partition by hash(UNIX_TIMESTAMP(login_time))partitions 4;
List 分区

按分区键值取值的列表进行分区

同范围分区一样,各分区的列表值不能重复

每一行数据必须能找到对应的分区列表,否则数据插入失败

create table `login_log_list`(
	login_id int(10) unsigned not null comment '登录用户ID',
	login_time timestamp not null default CURRENT_TIMESTAMP,
	login_ip int(10) unsigned not null comment '登录ip',
	login_type int(10) not null
	)engine=innodb
	partition by list(login_type)(
	partition p0 values in(1,3,5,7,9),
	partition p1 values in(2,4,6,8)
	);

交互框架


Pymysql

import pymysql
# pymysql.connect()  此对象为pymysql连接数据库的类

# 创建Connection连接对象实例
conn = pymysql.connect(host='localhost', port=3306, user='root', password='mysql', database='python1', charset='utf8')
# 创建游标
cursor = conn.cursor()
# 数据查询
sql = "select id,name from students where id = 7"  
# 数据更新
sql = 'update students set name="刘邦" where id=6'
# 数据删除
sql = 'delete from students where id=6'
# 载入查询语句, 返回的是执行成功的条数,可以用于判断是否执行成功
cursor.execute(sql)
# 接收查询结果、就要一条
result = cursor.fetchone()
# 关闭游标
cursor.close()
# 关闭连接
conn.close() 
 
# 数据更新/或数据新增时
conn.commit()   # 提交
# 事务的回滚  
conn.rollback()

# 查看所有数据 
cursor.fetchall()
cursor.fetchone()
cursor.fetchmany(2)

SQLAlchemy

框架定义 : 一个数据库 ORM框架

原生开发模式

from sqlalchemy import create_engine   # 引擎

# 连接数据库
HOSTNAME = '127.0.0.1'    # IP
PORT = '3306'			# 端口
DATABASE = 'demo0417'	# 数据库名称
USERNAME = 'root'		# 用户名
PASSWORD = 'root'		# 密码

# 驱动 方式 1  —  用 pymysql 连接
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)

# 驱动 方式 2  —  用 mysqlconnector 连接
pip install mysqlconnector
DB_URI = 'mysql+mysqlconnector://{}:{}@{}:{}/{}'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)

# 创建数据库引擎
engine = create_engine(DB_URI)

# 创建连接
with engine.connect() as conn:
	# 执行SQL语句,原生的SQL写法
	result = conn.execute("select * from users")
	print(result.fetchone())  # 一条数据,返回一个元组
	print(result.fetchall())  # 多条数据

SQLAlchemy 常用数据类型

Integer	# 整形。
Float	# 浮点类型。
Boolean	# 传递True/False进去。
DECIMAL	# 定点类型。
enum	# 枚举类型。
Date	# 传递datetime.date()进去。
DateTime	# 传递datetime.datetime()进去。
Time	# 传递datetime.time()进去。
String	# 字符类型,使⽤时需要指定⻓度,区别于Text类型。
Text	# ⽂本类型。
LONGTEXT	# ⻓⽂本类型。

Column常⽤参数

default	# 默认值。
nullable	# 是否可空。
primary_key	# 是否为主键。
unique	# 是否唯⼀。
autoincrement	# 是否⾃动增⻓。
sqlalchemy	# 常⽤数据类型
Column	# 常⽤参数
onupdate	# 更新的时候执⾏的函数。
name	# 该属性在数据库中的字段映射

ORM 框架使用

通过类的方式进行操作数据库,底层转化为 select 原生语句

"""
class Users(object):    
	name = "lcl"
	pass

user = Users(1,"lcl")
user.add()
	
类 :class   一张表
属性 :name   表字段
对象 : 一条记录
"""
from sqlalchemy import create_engine
# 导入ORM的类
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column,Integer,String

HOSTNAME = '127.0.0.1'    # IP
PORT = '3306'			# 端口
DATABASE = 'demo0417'	# 数据库名称
USERNAME = 'root'		# 用户名
PASSWORD = 'root'		# 密码

DB_URI = 'mysql+mysqlconnector://{}:{}@{}:{}/{}'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)

engine = create_engine(DB_URI)

# 实例化ORM的类 所有模型 继承自 declarative_base
Base = declarative_base(engine)

# 使用 ORM 操作数据库, 继承 Base = declarative_base(engine) 的基类
class Students(Base):
	# 定义表的名字
	__tablename = "students"
	# 创建一些字段 通过 Column 进行创建
	id = Column(Interger, primary_key = True,autoincrement = True)   # 数据类型、主键、自增
	name = Column(String(50),nullable = False )   # 字符串类型、不能为空
	gender = Column(Interger,default = 1 ,comment = "1 为 男,2为女") 


# 模型映射到数据库中
Base.metadata.create_all()

ORM 增删改查

from sqlalchemy import create_engine
from sqlalchemy.declarative import declarative_base
from sqlalchemy import Column,Integer,String
from sqlalchemy.orm import sessionmaker

HOSTNAME = '127.0.0.1'    # IP
PORT = '3306'			# 端口
DATABASE = 'demo0417'	# 数据库名称
USERNAME = 'root'		# 用户名
PASSWORD = 'root'		# 密码

DB_URI = 'mysql+mysqlconnector://{}:{}@{}:{}/{}'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)
engine = create_engine(DB_URI)
Base = declarative_base(engine)

class Article(Base):
	# 定义表的名字
	__tablename = "article"
	# 创建一些字段 通过 Column 进行创建
	id = Column(Interger, primary_key = True,autoincrement = True)   # 数据类型、主键、自增
	name = Column(String(50),nullable = False )   # 字符串类型、不能为空
	
# 模型映射到数据库中
Base.metadata.create_all()
# 数据在内存中
article = Article(name = 'lcl') 
# 将数据保存到数据库中
# 实例化 sessionmaker 类
# 类的实例化   __call__ 将类变成方法 去 调用
Session = sessionmaker( bind = engine )
session = Session()
# 数据添加 - 数据尚未提交
session.add(article)
# 数据提交
session.commit()

print(article.name)
print(article.id)

# 一次添加多条数据
session.add_all([article,article1])
session.commit()

ORM 增删改查-方法封装

from sqlalchemy import create_engine
from sqlalchemy.declarative import declarative_base
from sqlalchemy import Column,Integer,String
from sqlalchemy.orm import sessionmaker

HOSTNAME = '127.0.0.1'    # IP
PORT = '3306'			# 端口
DATABASE = 'demo0417'	# 数据库名称
USERNAME = 'root'		# 用户名
PASSWORD = 'root'		# 密码

DB_URI = 'mysql+mysqlconnector://{}:{}@{}:{}/{}'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)
engine = create_engine(DB_URI)
Base = declarative_base(engine)

class Article(Base):
    __tablename__ = 'art'

    id = Column(Integer, primary_key=True, autoincrement=True)
    title = Column(String(50), nullable=False)
    content = Column(String(50))
    author = Column(String(50))

    def __str__(self):   
        return "Article(title:{},content:{},author:{})".format(self.title, self.content, self.author)

# 模型映射到数据库中
Base.metadata.create_all()

# 写入数据
def add_data():
    article = Article(title='Python', content='人生苦短,我用Python', author='龟叔')
    session.add(article)
    session.commit()

# 数据的查询
def search_data():
    data = session.query(Article).all()		# all 查询所有
    for item in data:
        print(item)
        print(item.title)
        print(item.content)
    # print(data)

    # 条件 filter 方法 1  返回的是列表
    data = session.query(Article).filter(Article.title=='Python').all()
    for item in data:
        print(item)

	# filter_by 方法  返回的是列表
    data = session.query(Article).filter_by(title='JAVA').all()
    for item in data:
        print(item)
    print(data)


    # 查询第一条
    data = session.query(Article).first()
    print(data)

    # get 方法 传的ID 不存在 返回None
    data = session.query(Article).get(1)   # 查询 ID 为 1 
    data = session.query(Article).get(2)   # 查询 ID 为 2 
    print(data)


# ORM 修改
def update_data():
    # 查询出要修改的这条记录
    article = session.query(Article).first()
    article.title = 'lgcoder'
    print(article.title)

    # session.rollback()   回滚
    # print(article.title)
    session.commit()


# ORM 删除
def delete_data():
    # 查询出要修改的这条记录
    article = session.query(Article).first()
    # 误操作
    # is_delete 1 未删除  0 删除
    # 修改操作  is_delete 1=>0
    session.delete(article)
    session.commit()

query 可用参数

"""
1.  模型对象。指定查找这个模型中所有的对象。
2.  模型中的属性。可以指定只查找某个模型的其中⼏个属性。
3.  聚合函数。
func.count:统计⾏的数量。
func.avg:求平均值。
func.max:求最⼤值。
func.min:求最⼩值。
func.sum:求和
"""
from sqlalchemy import function

# 总条数
result = session.query(func.count(Article.id)).first()
# 求平均值
result = session.query(func.avg(Article.price)).first()

过滤条件

# 这些过滤条件都是只能通过filter⽅法实现的

#  等于 equals
query.filter(User.name == 'ed').all()
# 不等于 not equals
query.filter(User.name != 'ed')
# 模糊查询 like
query.filter(User.name.like('%ed%'))
# 在...中 in
query.filter(User.name.in_(['ed','wendy','jack']))
# 同时,in也可以作⽤于⼀个Query
query.filter(User.name.in_(session.query(User.name).filter(User.name.like ('%ed%'))))
# 不在...中 not in
query.filter(~User.name.in_(['ed','wendy','jack']))
# is null 为空
query.filter(User.name==None)
query.filter(User.name.is_(None))
# 不为空 is not null
query.filter(User.name != None)
query.filter(User.name.isnot(None))
# 条件并列 and
from sqlalchemy import and_
query.filter(and_(User.name=='ed',User.fullname=='Ed Jones'))
# 或者是传递多个参数
query.filter(User.name=='ed',User.fullname=='Ed Jones')
# 或者是通过多次filter操作
query.filter(User.name=='ed').filter(User.fullname=='Ed Jones')
from sqlalchemy import or_ query.filter(or_(User.name=='ed',User.name=='wendy'))

外键&外键约束

# 通过 ForeignKey类来实现,并且可以指定表的外键约束
class Article(Base):
	__tablename__ = 'article'
	id = Column(Integer,primary_key=True,autoincrement=True)
	title = Column(String(50),nullable=False)
	content = Column(Text,nullable=False)
	# 外键 user.id  user 表 中的 id 字段
	uid = Column(Integer,ForeignKey('user.id'))
	def __repr__(self):
		return "" % self.title
		
class User(Base):
	__tablename__ = 'user'
	id = Column(Integer,primary_key=True,autoincrement=True)
	username = Column(String(50),nullable=False)


# 外键查询(原理)
article = session.query(Article).first()
uid = article.uid
user = session.query(User).get(uid)
print(user)
# 外键查询
user = session.query(User).filter(User.id == Article.uid).first()



# 外键约束
RESTRICT:⽗表数据被删除,会阻⽌删除。默认就是这⼀项。
NO ACTION:在MySQL中,同RESTRICTCASCADE:级联删除。
SET NULL:⽗表数据被删除,⼦表数据会设置为NULL

# 通过 ForeignKey类来实现,并且可以指定表的外键约束
class Article(Base):
	__tablename__ = 'article'
	id = Column(Integer,primary_key=True,autoincrement=True)
	title = Column(String(50),nullable=False)
	content = Column(Text,nullable=False)
	# 指定外键关系、执行外键约束删除关系
	uid = Column(Integer,ForeignKey('user.id',ondelete='CASCADE'))


数据表对应关系

# 1对 n 的关系

from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
 
class Article(Base):
	__tablename__ = 'article'
	id = Column(Integer,primary_key=True)
	email_address = Column(String,nullable=False)
	user_id = Column(Integer,ForeignKey('users.id'))
	# 一对多的关系,backref 反向访问属性
	author = relationship('Author',backref="article")
	
	def __repr__(self):
		return "" % self.email_address

class Author(Base):
	__tablename__ = 'author'
	id = Column(Integer,primary_key=True)
	name = Column(String(50))
	fullname = Column(String(50))
	password = Column(String(100))
	# 一对多的关系  relationship,  backref(反向查询)
	article = relationship("Article",backref="author")

# 查询 (文章,作者)
article = session.query(article).first()
print(article.author)

# 添加单条数据
user = Article(username = "lcl")
article = Article(title = "python",context ="xxxxx")
article.author = user
session.add(article)
session.commit()


# 添加多条文章记录
user = User(username = "lcl")
article1 = Article(title="python1",context="xxxx1")
article2 = Article(title="python2",context="xxxx2")

article1.author = user
article2.author = user

session.add(article1)
session.add(article2)
session.commit()




# 1对1 的关系
class User(Base):
	__tablename__ = "user"
	id = Column(Integet,primary_key = True, autoincrement= True)
	username = Column(String(50),nullable = False)
	**# uselist= False 指定关系为 1 vs 1**
	extend = relationship("UserExtend",uselist= False)

class UserExtend(Base):
	__tablename__ = "user_extend"
	id = Column(Integet,primary_key = True, autoincrement= True)
	school = Column(String(50))
	# 外键
	uid = Column(Integer,Foreignkey("user.id"))
	user = relationship("User",backref = "extend")
	


# n 对 n 的关系
# 多对多,班级对老师,老师对班级
# 班级表 —— 中间表(班级表ID + 老师表 ID) —— 老师表
from sqlalchemy import Table
# 中间表定义
techer_class = Table(
	"techer_classes",		# 中间表名
	Base.metadata,
	Column("techer_id",Interger,ForeignKey("techer.id"))   # 中间表字段
	Column("classes_id",Interger,ForeignKey("classes.id"))  # 中间表字段
)

class Teacher(Base):
	__tablename__ = "teacher"
	id = Column(Integet,primary_key = True, autoincrement= True)
	name = Column(String(50))
	# 外键关系、指定中间表
	classes = relationship("Classes",backref = "teachers",secondary= teacher_classes)

class Classes(Base):
	__tablename__ = "classes"
	id = Column(Integet,primary_key = True, autoincrement= True)
	name = Column(String(50))

# 多对多数据的添加
teacher1 = Teacher(name= "lcl")
teacher2 = Teacher(name ="wzh")

classes1 = Classes(name = "初级班")	
classes2 = Classes(name = "进阶班")

teacher1.classes.append(classes1)
teacher1.classes.append(classes2)

teacher2.classes.append(classes1)
teacher2.classes.append(classes2)

session.add(teacher1)
session.add(teacher2)
session.commit()

# 查询老师对应的班级
teacher = session.query(Teacher).first()
print(teacher)
for i in teacher.classes:
	print(i)

# 班级对应的老师
classes = session.query(Classes).first()
for i in classes.techers:
	print(i)

数据库高级查询

# 排序
articles = session.query(Article).order_by(Article.id).all() 	# 升序
articles = session.query(Article).order_by(Article.id.desc()).all()	# 降序
articles = session.query(Article).order_by(-Article.id).all()	# 降序
for article in articles:
	print(articles)

# 默认排序方法  - __mapper_args__  魔术方法
class Article(Base):
	__tablename__ = 'article'
	id = Column(Integer,primary_key=True,autoincrement=True)
	title = Column(String(50),nullable=False)
	
	__mapper_args__ = {
		"order_by" : id
	}
# 定义魔术方法后,查询你中无需 order_by
articles = session.query(Article).all()
for article in articles:
	print(articles)
	


"""
limit : 可以限制每条查询的时候,只查询几条数据
offset : 可以限制查询数据的时候过滤掉前面多少条
切片 : 可以对Query 对象使用切片操作,来获取想要的数据
"""
# limit 限制 —— 前三条数据
articles = session.query(Article).limit(3).all()
for article in articles:
	print(articles)
	
# offset偏移量   查询 3-5条数据
articles = session.query(Article).offset(3).limit(3).all()
for article in articles:
	print(articles)

# 切片 取 2-4 条
articles = session.query(Article).all()[2,5]
for article in articles:
	print(articles)



# 分组、having、join方法
# group_by 分组、一般和聚合 函数连用
results = session.query(User.gender).group_by(User.gender).all()
results = session.query(User.gender,func.count(User.id)).group_by(User.gender).all()
for result in results
	print(result)


# having ,分组后过滤
results = session.query(User.age,func.count(User.id)).group_by(User.age).having(User.age<18).all()
print(results)


# 子查询
# 查询和 李 相同的城市 和年龄的人
user = session.query(User).filter(User.username =="李").first()
print(user.city)
print(user.age)
result = session.query(User).filter(User.city == user.city,User.age == user.age).all()
for data in result:
	print(data)

sub = session.query(User.city.label("city"),User.age.label("age")).filter(User.username =="李").subquery()
result = session.query(User).filter(User.city == sub.c.city,User.age == sub.c.age).all()

Flask - SQLAlchemy插件

# 插件安装
pip install flask-sqlalchemy

from flask import Flask
from flask sqlachemy import SQLAlchemy
# localhost
HOSTNAME = '127.0.0.1'    # IP
PORT = '3306'			# 端口
DATABASE = 'demo0417'	# 数据库名称
USERNAME = 'root'		# 用户名
PASSWORD = 'root'		# 密码

DB_URI = 'mysql+mysqlconnector://{}:{}@{}:{}/{}'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)

app = Flask(__name__)

# 创建引擎,加载配置文件 SQLALCHEMY_DATABASE_URL
# engine = create_engine(DB_URL)
app.config['SQLALCHEMY_DATABASE_URL'] = DB_URL
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 操作数据库,通过db 操作数据库
db = SQLAlchemy(app)

# 创建模型(继承自 db.Model)
class User(db.Model):
	__tablename__ = 'users'
	id = db.Column(db.Integer,primary_key = True,autoincrement= True)
	name = db.Column(db.String(50))

class Article(db.Model):
	__tablename__ = 'article'
	id = db.Column(db.Integer,primary_key = True,autoincrement= True)
	title = db.Column(db.String(50))
	# 定义外键
	uid = db.Colunm(db.Integer,db.Foreignkey('users.id'))
	# 表关联
	author = db.relationship('User',back='articles')

# 将Model 映射到数据库中
db.create_all()


# 数据添加
user = User(name = 'lcl')
article = Artcile(title = 'python')
article.author = user
db.session.add(article)
db.session.commit()


# 查询数据
user = User.query.all()
print(user)
# 排序
users = User.query.order_by(User.id.desc()).all()
print(users)

@app.route("/")
def index():
	return "首页"
	
if __name__ == '__main__':
	app.run(debug = True)

性能优化


基准测试定义 :测量和评估软件性能指标的活动,用于建立某时刻的性能基准,便于当系统发生软硬件变化时,评估变更带来的影响

对系统设置压力测试,用于评估服务器的处理能力

建立mysql服务性能基线

基准测试工具
  • 工具 : mysqlslap
# 参数命名

mysqlslap --auto-generate-sql 	# 由系统自动生成SQL脚本进行测试

mysqlslap --auto-generate-sql-add-autoincrement 	# 在生成的表中增加自增ID
mysqlslap --auto-generate-sql-load-type 	# 指定测试中使用的查询类型
mysqlslap --auto-generate-sql-write-number 	# 指定初始化数据时生成的数据量
mysqlslap --concurrency 	# 指定并发线程的数量
mysqlslap --engine 	# 指定要测试表的存储引擎,可以用逗号分割多个存储引擎
mysqlslap --no-drop 	# 指定不清理测试数据
mysqlslap --iterations 	# 指定测试运行的次数
mysqlslap --number-of-queries 	# 指定每一个线程执行的查询数量
mysqlslap --debug-info 	# 指定输出额外的内存及CPU统计信息
mysqlslap --number-int-cols 	# 指定测试表中包含的INT类型列的数量
mysqlslap --number-char-cols 	# 指定测试表中包含的varchar类型的数量
mysqlslap --create-schema 	# 指定了用于执行测试的数据库的名字
mysqlslap --query 	# 用于指定自定义SQL的脚本
mysqlslap --only-print 	# 并不运行测试脚本,而是把生成的脚本打印出来

# 测试案例
mysqlslap --concurrency=1,50,100,200 --iterations=3 --number-int-cols=5 --number-char-
cols=5 --auto-generate-sql --auto-generate-sql-add-autoincrement --engine=myisam,innodb
--number-of-queries=10 --create-schema=test

explain 解析语句

定义 :模拟优化器执行 sql 查询语句,分析查询语句的表结构性能瓶颈

解析内容 :

  • 表的读取顺序
  • 数据读取操作的操作类型
  • 哪些索引可以被使用
  • 哪些索引实际被使用
  • 表之间的引用
  • 每张表有多好啊行被优化器查询
explain select * from t1,t2,t3 where t1.id=t2.id and t1.id = t3.id and t1.other_column='';

explian语句解析

  • id— 表的读取加载顺序 (id相同、执行顺序由上而下,id不同、id值越大优先级越高、越先被执行)
  • select_type — 数据读取操作的操作类型(simple 简单的查询、primary 查询中若包含任何负责的子部分、最外层查询则被标记,subquery 在select 或where列表中包含了子查询,union 若第二个select出现在union之后,则被标记为union,union result 从union表获取结果的select)

Sqlmap探测工具

功能定义 : 一种安全探测测试工具,用于发现SQL注入的安全漏洞,长用来进行安全扫描

基本操作
# 程序开启(在文件程序对应目录下)
python sqlmap.py 

# 查看当前数据库版本信息
"""
0:只显示python 的tracebacks 信息、错误信息、关键信息
1:显示普通信息,和警告信息
2:显示调试信息 [debug]
3:显示注入使用的攻击载荷[payload]
4:显示HTTP请求头
5:显示http响应头
6:显示HTTP响应体
"""
python sqlmap.py --version
 
# sqlmap直连数据库(用户名、密码、端口地址、数据库名字)
python3 sqlmap.py -d "mysql://用户名:密码@地址:端口/数据库名字" -f --banner --dbs --users


 # sqlmap 探测定向的url地址
"""
探测分7级(0-6),参数用V标识,级别越高,探测的东西越多,时间越长,默认为V1

- u : 指定单一url地址
- m : 探测多个目标(text文件保存在sqlmap文件中,可以保存多行目标, 目标地址需要和数据库有交互的地址)
- r : 指定httl交互文件,文件中保存请求头信息(request header(view parsed))
- c :从配置文件sqlmap.conf 中读取目标文件(需要先修改target url 地址)
--method :http请求方法(get、post、cookie、user-agent)
"""
python sqlmap.py -u "地址"  --banner   -v2  
python sqlmap.py -u "地址"  -2   --banner

sqlmap -m "文件路径" --banner
 

# 针对post方法提交参数的地址通过提交参数来进行测试
sqlmap -u "url" --data="uname=admin&passwd=amdin&submit=Submit" --banner

# sqlmap中设置cookie参数
#对登陆界面进行探测的时候需要携带  cookie信息  对登陆之后网站进行探测 也需要携带cookie 信息

--cookie "cookie值" # 指定cookie值
--cookie-del  # 删除cookie值
--load-cookies # 在文件中加载cookie
--drop-set-ookie  # 设置set-cookie的值


#sqlmap中设置 user-agent
sqlmap -u "url" --data="uname=admin&passwd=amdin&submit=Submit" --user-agent
# 随机设置请求user-agent
sqlmap -u "url" --data="uname=admin&passwd=amdin&submit=Submit"  -- random -agent


# sqlmap 设置代理(ip代理)
sqlmap -u "url" --data="uname=admin&passwd=amdin&submit=Submit" --proxy "http:// $haproxy ip:prot"
sqlmap -u "url" --data="uname=admin&passwd=amdin&submit=Submit" --proxy-file 
#设置http代理服务器认证信息
sqlmap -u "url" --data="uname=admin&passwd=amdin&submit=Submit" --proxy-cred user:pwd
--ignore-proxy # 忽略系统范围内的代理服务器


# qlmap 设置探测延迟
-- delay 0.5  # 设置延迟0.5秒

# sqlmap 中设置超时
--timeout 10.5 # (超过一段时间请求没有响应,此测试跳过)

# sqlmap 设置超时连接次数
--retries  count   # 默认为3次

# sqlmap 中设置随机参数(每次请求期间随机更改其参数名称(长度和类型根据原始值保持一直))
--randomize "参数名称"

# sqlmap  忽略 错误站点提示 401
--ignore -401  # 继续探测

# 指定网站请求的参数分隔符
--param-del = "分隔符"
常用检索参数
#	获取后端数据库的版本信息     
 -- banner  
 -b
 
#	获取DBMS当前用户      
--current -user

#	获取当前数据库名称
--current -db

#	获取当前主机名       
-- hostname

#	探测当前用户是否是数据库管理员    
--is -dba

#	会先列举用户,在列举用户密码的hash值    
--passwords

#	枚举 DBMS用户  所有用户   
--users

#	列举数据库名    
--dbs

#	枚举数据库表   
--tables      #   数据库名字  
#  指定具体数据库  
-D

#	枚举数据表列  
--columns
-T  # 指定数据库表

#	枚举数据值
-- dump

#	枚举schema 信息 
--schema	# (列举数据库管理系统模式,模式列表包括数据库、表、列、触发器、和他们各自的类型。同样的  可以通过参数 --exclude-sysdbs  排除系统数据库)
-sysbds   # 除去数据库系统表

#	检索数据表数量    
--count  #(如果用户只想知道表数据条数)

#	获取数据信息    
--start     --stop  (--start1 --stop3)  # 返回前三条数据

#	设置条件获取信息    
--where
#	暴力破解表名   
--common -table

#	暴力破解列名
# 1、版本小于5.0的无法查询
# 2、数据库 用户的权限过低 无法读取表名    
--common-columns

#	读取文件  
--file-read   # 路径 读取对应文件内容(此路径为绝对路径)

#	检索所有信息   参数 
-a  
--all   # 返回所有的检索信息
性能优化
# 查询参数
python sqlmap -hh

# 设置持久化http连接(长连接)
--keep-alive
python sqlmap.py -u "地址"  --keep-alive --banner   -v2 

# 设置不接收http body(不接收消息体)
--null -connection
python sqlmap.py -u "地址"  --keep-alive --null-connection --banner   

# 设置多线程 
--thread = 3
python sqlmap.py -u "地址" --thread=3 --banner

# 一键优化(同时添加多个参数)
-o  (--keep-alive --null-connection --threads = 3)
python sqlmap.py -u "地址" -o --banner


#**sqlmap自定义检测级别**

# 设置探测等级 (1-5)
# 大于2时、会对cookie等参数进行测试、大于3时,会使用user-agent 和 referer(跳转) 进行测试
--level = 2
python sqlmap.py -u "地址" -o --banner --level = 2

# 设置风险等级
--risk = 2

# 指定探测参数
python sqlmap.py -u "地址" -p "id,user-agent" --banner

# 跳过某些注入参数
python sqlmap.py  -u "地址" -skip "参数名称"

# 对注入点存在uri中的,在参数后面加 # 进行指定探测参数
python sqlmap.py -u "127.0.0.1/id#/user/"


# sqlmap检索DBMS(指定探测数据库)
sqlmap -u "url" --data="uname=admin&passwd=amdin&submit=Submit" --dbms "数据类型"

# 执行操作系统
sqlmap -u "url" --data="uname=admin&passwd=amdin&submit=Submit" --os 


# 无效值参数的替换(替换原有的、执行替换的部分)
--invalid-bignum
--invalid-logical
sqlmap -u "url" --data="uname=admin&passwd=amdin&submit=Submit and 恶意sql语句" "


# 自定义注入负载位置
--prefix "设置sql注入payload前缀"
sqlmap -u "127.0.0.1/lesson/id=1" --prefix 
--suffix "设置sql注入payload后缀"

# 设置Tamper参数
sqlmap -u "127.0.0.1/lesson/id=1" --tamper "脚本名称"

# 设置DBMS认证
--dbms-cred = username

指定注入参数
 #  参数  --technique
 #	默认情况下所有的方式全部使用一遍
B:Boolean-based blind   # (布尔型注入)
E:Error-based  # (报错型注入)
U:Union query-based   # (可联合查询注入)
S:Stacked queries  # (可多语句查询注入)
T:Time-based blind  # (基于时间延迟注入)
Q:Inline queries  # (嵌套查询注入)


# 设置时间盲注延迟时间(默认5s)
--time-sec

# 设置union联合字段数
--union-cols 12-18

# sqlmap设置union字符
-union-char

# 设置联合查询表
--union-from "表名"  # 指定联合查询的表名

# 探测目标指纹信息
-f
--fingerprint

你可能感兴趣的:(Mysql,mysql,数据库,sql)