day05 mysql pymysql
一.pymysql的操作
commit(): 在数据库里增删改的时候,必须要进行提交,否则插入的数据不生效
1.增, 删, 改
#coding=utf-8
#Version:python3.5.0
#Tools:Pycharm 2017.3.2
__date__ = '2019/12/12 13:37'
__author__ = 'wt'
import pymysql
username = input('请输入用户名: ')
pwd = input('请输入密码: ')
conn = pymysql.connect(host='127.0.0.1',
user='root',
password="",
database='db2',
port=3306,
charset='utf8',)
cur = conn.cursor()
sql = 'insert into userinfo(name,password) values(%s,%s)'
print(sql)
rst = cur.execute(sql,[username,pwd])
print(rst)
conn.commit() #增 删 改一定要记得提交到服务器
cur.close()
conn.close()
if rst:
print('登录成功')
else:
print('登录失败')
2.查 fetchone() fetchmany() fetchall() (fetch 取回)
#coding=utf-8
#Version:python3.5.0
#Tools:Pycharm 2017.3.2
__date__ = '2019/12/12 13:37'
__author__ = 'wt'
import pymysql
conn = pymysql.connect(host='127.0.0.1',
user='root',
password="",
database='db2',
port=3306,
charset='utf8',)
# cur = conn.cursor()
cur = conn.cursor(cursor=pymysql.cursors.DictCursor) #可以把下面fetch查出的结果变成字典
sql = 'select * from userinfo'
print(sql)
rst = cur.execute(sql) #执行查询语句后, 查看记录的数据
print(rst)
print(cur.fetchone()) #查一条 默认结果是元组 #想要字典的形式,创建游标的时候设置参数即可
print(cur.fetchone()) #查下一条 若没有了, 返回None
print(cur.fetchmany(1)) #查多个,元组里面套元组, 当超过个数就是获取所有
print(cur.fetchall()) #获取所有
#看完了, 我想回去看? 移动光标(是行指针)
cur.scroll(-3,mode='relative') #相对移动,正值向前移动,负值向后移动
print(cur.fetchone())
cur.scroll(4,mode='absolute') #绝对移动,绝对于起始位置,正值是开始向前移动,负值报错
print(cur.fetchone())
cur.close()
conn.close()
if rst:
print('登录成功')
else:
print('登录失败')
二.前端 + flask + pymysql的使用
server.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# Date: 2019/12/5
import json
import pymysql
from flask import Flask
from flask import request
from flask import Response
# 建立mysql连接
conn = pymysql.connect(
host='localhost',
user='root',
password="",
database='db2',
port=3306,
charset='utf8'
)
#创建游标
cur = conn.cursor(cursor=pymysql.cursors.DictCursor)
#创建实例化请求对象
app = Flask(__name__)
# 定义路由
@app.route("/")
# 路由对应的函数处理
def index():
# 响应数据
resp = Response("<h2>首页</h2>")
# 允许所有跨域访问
resp.headers["Access-Control-Allow-Origin"] = "*"
return resp
# MTV 数据模板视图
@app.route("/course")
def courses():
sql = 'SELECT * FROM userinfo'
cur.execute(sql)
results = cur.fetchall()
# 返回json序列化的数据
resp = Response(json.dumps({
"msg": results
}))
resp.headers["Access-Control-Allow-Origin"] = "*"
return resp
# 前端发送post请求
# 定义路由
@app.route("/create", methods=["post", ])
def create():
print(request.form.get('name'))
# 读取user.json中的原始的数据
with open("user.json", "r") as f:
# 将数据反序列化
data = json.loads(f.read())
# 将新数据添加到原始的数据中
data.append({"name": request.form.get('name')})
# 将此时最新的数据再次写入文件中
with open("user.json", "w") as f:
f.write(json.dumps(data))
# 再次返回最新的数据 响应回前端
resp = Response(json.dumps(data))
resp.headers["Access-Control-Allow-Origin"] = "*"
return resp
if __name__ == '__main__':
app.run(host="localhost", port=8800, )
index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="user">
<input type="text" name="user">
<input type="button" value="提交">
<table>
<tr class="filed">
<td>id</td>
<td>name</td>
<td>pwd</td>
</tr>
<tr class="item">
<td></td>
<td></td>
<td></td>
</tr>
<tr class="item">
<td></td>
<td></td>
<td></td>
</tr>
<tr class="item">
<td></td>
<td></td>
<td></td>
</tr>
<tr class="item">
<td></td>
<td></td>
<td></td>
</tr>
</table>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script>
$.ajax({
url:'http://localhost:8800/course',
type:'get',
dataType:'json',
success:function (data) {
console.log(data.msg);
data.msg.forEach(function (ele,index) {
console.log(ele.id,ele.name,ele.password)
//未完待续
});
},
error:function () {
}
});
$('input[type=button]').click(function () {
$.ajax({
url:"http://127.0.0.1:8800/create",
type:'post',
data:{
name:$('input[type=text]').val()
},
success:function (data) {
console.log(data);
}
})
})
</script>
</body>
</html>
user.json
[{"name": "wukong"}, {"name": "bajie"}, {"name": "zabbix"}, {"name": "zabbix"}]
三.mysql的索引
索引的介绍: 针对大量数据
数据库中专门用于帮助用户快速查找数据的一种数据结构,类似于字典中的目录,查找字典内容时可根据目录查找到数据的存放位置,然后直接获取
索引的作用:
约束和加速查找
常见的几种索引
普通索引
唯一索引
主键索引
组合索引(联合索引)
组合主键索引
组合唯一索引
组合普通索引
索引的分类:
hash索引:查询单条快,范围查找慢
btree索引: b+树,层数越多,数据量指数越增长(我们就用它,因为innodb默认支持它)
准备大表,插入百万数据
#创建索引测试表
drop table if exists big_data;
create table big_data(
id int primary key not null auto_increment,
name varchar(16) default null,
age int(11),
email varchar(64) default null
)engine=myisam default charset=utf8; #注意myisam存储引擎不产生引擎事务,数据插入速度极快, 为方便快速插入千万条测试数据,等我们插完数据,再把存储类型修改为innodb
#创建存储过程, 插入数据
delimiter $$ #声明存储过程的结束符号为$$ (delimiter 分隔符)
create procedure `insert_data_p`(num int) #(procedure 程序)
begin
declare n int default 1; #(declare 声明)
while n <= num do
insert into big_data(name,age,email) values(concat('bajie',n),rand()*50,concat('bajie',n,'@163.com'));
set n=n+1;
end while;
END$$ #$$结束
delimiter ; #重新声明分号为结束符号
#调用存储过程,插入500万条数据
call insert_data_p(5000000); #(105.28 sec)
#查看存储过程
show create procedure insert_data_p\G
#修改回我们的InnoDB
alter table big_data engine=innodb; #(21.91sec)
没有索引时,测试查询
mysql> select * from big_data where name = 'bajie1111111';
+---------+--------------+------+----------------------+
| id | name | age | email |
+---------+--------------+------+----------------------+
| 1111111 | bajie1111111 | 41 | bajie1111111@163.com |
+---------+--------------+------+----------------------+
1 row in set (1.71 sec)
mysql> select * from big_data where email = 'bajie2222222@163.com';
+---------+--------------+------+----------------------+
| id | name | age | email |
+---------+--------------+------+----------------------+
| 2222222 | bajie2222222 | 47 | bajie2222222@163.com |
+---------+--------------+------+----------------------+
1 row in set (1.77 sec)
创建索引(给某个字段创建索引)
1.普通索引
index:
作用: 仅有一个加速查询
创建索引:
创建表时,指定索引字段
create table t1(
id int not null auto_increment primary key,
name varchar(32) not null,
email varchar(64) not null,
index ix_name(name)
);
给已有表,创建索引字段
create index ix_name on big_data(name); #affected (25.93 sec)
有索引时,测试查询
mysql> select * from big_data where name = 'bajie1111111'; #有索引的字段查询快
+---------+--------------+------+----------------------+
| id | name | age | email |
+---------+--------------+------+----------------------+
| 1111111 | bajie1111111 | 41 | bajie1111111@163.com |
+---------+--------------+------+----------------------+
1 row in set (0.00 sec)
mysql> select * from big_data where email = 'bajie2222222@163.com'; #无索引的字段查询慢
+---------+--------------+------+----------------------+
| id | name | age | email |
+---------+--------------+------+----------------------+
| 2222222 | bajie2222222 | 47 | bajie2222222@163.com |
+---------+--------------+------+----------------------+
1 row in set (1.77 sec)
删除索引
drop index ix_name on big_data;
查看索引
show index from big_data;
2.主键索引
primary key:
把主键看成索引进行查询,速度快
主键的创建:
创建表的时候加的主键, 就等同于主键索引
create table t1(
id int not null auto_increment,
name varchar(32) not null,
email varchar(64) not null,
primary key(id)
);
创建表后, 加主键索引
alter table big_data add primary key(name);
删除主键
> alter table department drop primary key;
> alter table department modify id int(10), drop primary key;
有主键时,测试查询
> select * from big_data where id = '3333333';
+---------+--------------+------+----------------------+
| id | name | age | email |
+---------+--------------+------+----------------------+
| 3333333 | bajie3333333 | 17 | bajie3333333@163.com |
+---------+--------------+------+----------------------+
1 row in set (0.00 sec)
3.唯一索引
unique index:
两个功能: 加速查找和唯一约束(可含null)
创建唯一索引:
创建表时,创建唯一索引
create table t1(
id int not null auto_increment,
name varchar(32) not null,
email varchar(64) not null,
primary key(id),
unique index ix_name(name)
);
创建表后,创建唯一索引
create unique index un_index on big_data(email); #affected (28.47 sec) #哪个索引查起来更快: 主键 > 唯一 > 普通
有唯一索引时,测试查询
mysql> select * from big_data where email = 'bajie2222222@163.com';
+---------+--------------+------+----------------------+
| id | name | age | email |
+---------+--------------+------+----------------------+
| 2222222 | bajie2222222 | 47 | bajie2222222@163.com |
+---------+--------------+------+----------------------+
1 row in set (0.00 sec)
删除唯一索引
drop index un_index on big_data; #和删普通索引一样
4.组合索引
组合索引是将n个列组合成一个索引
应用场景: 当频繁地使用n列来进行查询, 如 where name='bajie' and email='bajie@123.com'
创建组合索引
create index index_name_email on big_data(name,email);
有组合索引时,测试查询(遵循最左前缀匹配)
select * from big_data where name='bajie666666' and email='bajie666666@163.com'; #如果同时使用name和email查询时(顺序无要求),使用索引
+--------+-------------+------+---------------------+
| id | name | age | email |
+--------+-------------+------+---------------------+
| 666666 | bajie666666 | 28 | bajie666666@163.com |
+--------+-------------+------+---------------------+
1 row in set (0.00 sec)
select * from big_data where email='bajie666666@163.com'; #单独使用email查询时, 不使用索引
+--------+-------------+------+---------------------+
| id | name | age | email |
+--------+-------------+------+---------------------+
| 666666 | bajie666666 | 28 | bajie666666@163.com |
+--------+-------------+------+---------------------+
1 row in set (1.74 sec)
select * from big_data where name='bajie666666'; #单独使用name查询时, 使用索引
+--------+-------------+------+---------------------+
| id | name | age | email |
+--------+-------------+------+---------------------+
| 666666 | bajie666666 | 28 | bajie666666@163.com |
+--------+-------------+------+---------------------+
1 row in set (0.00 sec)
索引覆盖: 直接索引查询: 如果要select的字段,正好在索引表中,就会更快
select name from big_data where name='bajie666666'; #例如name字段是索引字段, 刚好select的字段就是name字段
索引合并: 多个单列的索引字段查询
select * from big_data where name='bajie666666' and id=666666;
性能分析:
当使用多个条件进行查询时, 组合索引 > 索引合并
5.对于索引
创建索引
命中索引
正确使用索引:
=
不正确使用索引:
like '%xx'
or: 都是索引时除外
类型不一致: name = 7777; 本来是字符串类型,但是给了个数值类型
!= :主键除外
> < :主键除外
order by :主键除外
使用函数: where reverse(name) = 'bajie';
组合索引的最左前缀
6.索引的注意事项
1)避免使用select *
2)count(1)或count(列)代替count(*)
3)创建表时: 尽量使用char代替varchar
4)表的字段顺序: 固定长度的字段优先
5)当经常使用多个条件查询时: 组合索引代替多个单列索引
6)尽量使用短索引: create index ix_title on t1(title(8)); 只适用于特殊的数据类型 text类型
7)使用连接join来代替子查询
8)连表时注意条件类型需一致
9)索引散列(重复少)不适用于(没必要)建索引,例如: 性别
四.解释执行(sql语句优化)
explain + sql查询: 用于显示sql执行的信息,根据参考信息可进行sql语句优化
explain select * from big_data where id != 676666 and name='bajie666';
+----+-------------+----------+------------+------+--------------------------+------------------+---------+-------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------+------------+------+--------------------------+------------------+---------+-------+------+----------+-----------------------+
| 1 | SIMPLE | big_data | NULL | ref | PRIMARY,index_name_email | index_name_email | 51 | const | 1 | 78.56 | Using index condition |
+----+-------------+----------+------------+------+--------------------------+------------------+---------+-------+------+----------+-----------------------+
参数说明:
select_type:
simple: 简单查询
primary: 最外层查询 (primary 初级的,主要的)
subquery: 映射为子查询
derived: 子查询 (derived 派生的)
union: 联合
union result: 使用联合的结果
table:
正在访问的表名
partitions:
分区
type:
查询时的访问(select)方式: 性能 all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
all: 全表扫描,特别的: 如果使用了limit限制,则找到之后就不在继续向下扫描
index: 全索引扫描
range: 对索引的列进行范围查找: between...and... in >等
index_merge: 索引合并: 使用多个单列索引搜索
ref: 根据索引查找一个或多个值
eq_ref: 连接时使用: primary key 或 unique类型
const: 常量: 表最多有一个匹配行, 因为仅有一行, 在这行的列值可被优化器剩余部分认为是常数,const表很快,因为他们只读取一次
system: 系统: 表仅有一行
possible_keys:
可能使用的索引
key:
真实使用的
key_len:
mysql中使用索引的字节长度
rows:
预估行数值: mysql估计为了找到所需的行而要读取的行数
extra:
该列包含mysql解决查询的详细信息
using index: 使用了覆盖索引, 直接访问索引表,避免访问表.要和index访问类型区分开
using where: 不是所带where都显示这个, 它意味着mysql将在存储引擎检索后再进行过滤: 查询可受益于不同的索引
using temporary: 使用了临时表 (temporary 临时的)
using filesort: 使用了外部索引排序,而不是按索引次序从表里读取行
文件排序算法: 有两种: 都可以在内存或磁盘上完成
五.慢日志记录(sql语句优化)
开启慢查询日志,可以让mysql记录下查询超过指定时间的语句,通过定位分析性能的瓶颈,更好的优化数据库系统的性能
查询是否开启了慢查询日志
show variables like 'slow_query%';
+---------------------+------------------------------------------------------+
| Variable_name | Value |
+---------------------+------------------------------------------------------+
| slow_query_log | OFF |
| slow_query_log_file | D:\mysql-5.7.28-winx64\data\DESKTOP-RA0BO30-slow.log | #这个目录要求mysql有可写权限, 一般设置为在mysql的数据存放目录
+---------------------+------------------------------------------------------+
查询慢查询的超时时间
show variables like 'long%';
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| long_query_time | 10.000000 | #默认超过10秒才记录日志
+-----------------+-----------+
开启慢日志
方式一:
set global slow_query_log=1;
方式二:
[mysqld]
slow_query_log =1
slow_query_log_file=C:\mysql-5.6.40-winx64\data\localhost-slow.log
long_query_time = 1
六.分页性能相关方案
如何取当前表中的前10条记录,每十条取一次
select * from big_data limit 0,10;
select * from big_data limit 10,10;
select * from big_data limit 20,10;
select * from big_data limit 30,10;
...
select * from big_data limit 40000000,10; #越往后查询,需要的时间越长
...
最优的解决方案
select * from big_data where id > 4000000 limit 10; #下一页
select * from big_data where id < 4000000 order by id desc limit 10; #上一页
select * from (select * from big_data where id < 4000000 order by id desc limit 10) as A order by A.id; #上一页
select * from (select * from big_data where id > 4000000 limit 60) as A order by id desc limit 10; #多页查询时
- flask + pymysql操作Mysql数据库
安装flask-sqlalchemy.pymysql模块 pip install flask-sqlalchemy pymysql ### Flask-SQLAlchemy的介绍 1. ORM:Obj ...
- Mysql(六):数据备份、pymysql模块
一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具 下载链接:https://pan.baidu.com/s/1bpo5mqj 掌握: #1. 测试+链接 ...
- Mysql存储之原生语句操作(pymysql)
Mysql存储之原生语句操作(pymysql) 关系型数据库是基于关系模型的数据库,而关系模型是通过二维表时实现的,于是构成了行列的表结构. 表可以看作是某个实体的集合,而实体之间存在联系,这个就需要 ...
- mysql七:数据备份、pymysql模块
阅读目录 一 IDE工具介绍 二 MySQL数据备份 三 pymysql模块 一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具 下载链接:https:/ ...
- mysql六:数据备份、pymysql模块
一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具 掌握: #1. 测试+链接数据库 #2. 新建库 #3. 新建表,新增字段+类型+约束 #4. 设计表 ...
- MySQL多表查询,Navicat使用,pymysql模块,sql注入问题
一.多表查询 #建表 create table dep( id int, name varchar(20) ); create table emp( id int primary key auto_i ...
- mysql数据库: 用户管理、pymysql使用、navicat插件使用
一.用户管理 二.pymysql增删改查 三.sql注入攻击 一.用户管理 数据安全非常重要 不可能随便分配root账户 应该按照不同开发岗位分配不同的账户和权限 mysql中 将于用户相关的数据放在 ...
- Mysql数据多表查询及pymysql的使用
Exists关键字表示存在,在使用exists关键字时,内增查询语句不返回查询记录,而是返回一个真假值,True或者False,返回True外层语句才会进行查询:返回False时,外层查询语句不会进行 ...
- Django 3.0 中连接mysql 8.0,可以不使用pymysql ,升级Mysqlclient即可
python 中,连接mysql一般都推荐用pymysql ,而且在django中,网上的教程都是这么连接mysql的. import pymysql pymysql.install_as_MySQL ...
随机推荐
- rpcbind服务没法开启问题
昨天下午有部分生产机器无法启动nfs服务:报错很是奇怪.于是一路顺藤摸瓜发现是rpcbind没能正常启动导致的nfs没能起来. 后来总结了两种办法:主要是ipv6的问题所导致的. 措施一: 报错内容 ...
- apache的commons-fileupload中FileItem类和ServletFileUpload
FileItem类的常用方法 1.boolean isFormField().isFormField方法用来判断FileItem对象里面封装的数据是一个普通文本表单字段,还是一个文件表单字 ...
- 一、hibernate环境搭建
hibernate环境搭建 下载hibernate hibernate的jar 连接数据库的jar 解压hibernate,解压后目录结构 documentation :对应hibernate开发文档 ...
- Javascript基础二(程序的三大结构)
程序的三大结构: 顺序结构,选择结构,循环结构 程序的单分支结构-if语句: 当条件判断为真true时,执行花括号内的语句,如果条件为假false,跳过花括号内的语句 if(条 ...
- spark on yarn提交任务时报ClosedChannelException解决方案
spark2.1出来了,想玩玩就搭了个原生的apache集群,但在standalone模式下没有任何问题,基于apache hadoop 2.7.3使用spark on yarn一直报这个错.(Jav ...
- php随机生成数字加字母的字符串
function getRandomString($len, $chars=null) { if (is_null($chars)) { $chars = "ABCDEFGHIJKLMNOP ...
- Linux下安装PHP的curl扩展
先安装依赖包: yum install curl curl-devel 找到PHP的安装包,cd 进入安装包 cd php-5.6.25/ext/curl phpize 如果报找不到phpize就补全 ...
- hive建模方法
转自:https://www.jianshu.com/p/8378b80e4b21 概述数据仓库这个概念是由 Bill Inmon 所提出的,其功能是将组织通过联机事务处理(OLTP)所积累的大量的资 ...
- 一:unittest框架配合selenium工具之CSS_selector定位。
做了自动化测试这么久了,一直没有梳理到元素定位这一块的内容,其重要性不言而喻.趁着周末有时间,梳理一下. 1,通过id定位 driver.find_element_by_css_selector(&q ...
- 搭建hadoop集群 单机版
二.在Ubuntu下创建hadoop用户组和用户 这里考虑的是以后涉及到hadoop应用时,专门用该用户操作.用户组名和用户名都设为:hadoop.可以理解为该hadoop用户是属于一 ...