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;        #多页查询时
 
 
 
 
 

day05 mysql pymysql的使用 (前端+flask+pymysql的使用) 索引 解释执行 慢日志 分页性能方案的更多相关文章

  1. flask + pymysql操作Mysql数据库

    安装flask-sqlalchemy.pymysql模块 pip install flask-sqlalchemy pymysql ### Flask-SQLAlchemy的介绍 1. ORM:Obj ...

  2. Mysql(六):数据备份、pymysql模块

    一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具 下载链接:https://pan.baidu.com/s/1bpo5mqj 掌握: #1. 测试+链接 ...

  3. Mysql存储之原生语句操作(pymysql)

    Mysql存储之原生语句操作(pymysql) 关系型数据库是基于关系模型的数据库,而关系模型是通过二维表时实现的,于是构成了行列的表结构. 表可以看作是某个实体的集合,而实体之间存在联系,这个就需要 ...

  4. mysql七:数据备份、pymysql模块

    阅读目录 一 IDE工具介绍 二 MySQL数据备份 三 pymysql模块 一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具 下载链接:https:/ ...

  5. mysql六:数据备份、pymysql模块

    一 IDE工具介绍 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具 掌握: #1. 测试+链接数据库 #2. 新建库 #3. 新建表,新增字段+类型+约束 #4. 设计表 ...

  6. MySQL多表查询,Navicat使用,pymysql模块,sql注入问题

    一.多表查询 #建表 create table dep( id int, name varchar(20) ); create table emp( id int primary key auto_i ...

  7. mysql数据库: 用户管理、pymysql使用、navicat插件使用

    一.用户管理 二.pymysql增删改查 三.sql注入攻击 一.用户管理 数据安全非常重要 不可能随便分配root账户 应该按照不同开发岗位分配不同的账户和权限 mysql中 将于用户相关的数据放在 ...

  8. Mysql数据多表查询及pymysql的使用

    Exists关键字表示存在,在使用exists关键字时,内增查询语句不返回查询记录,而是返回一个真假值,True或者False,返回True外层语句才会进行查询:返回False时,外层查询语句不会进行 ...

  9. Django 3.0 中连接mysql 8.0,可以不使用pymysql ,升级Mysqlclient即可

    python 中,连接mysql一般都推荐用pymysql ,而且在django中,网上的教程都是这么连接mysql的. import pymysql pymysql.install_as_MySQL ...

随机推荐

  1. rpcbind服务没法开启问题

    昨天下午有部分生产机器无法启动nfs服务:报错很是奇怪.于是一路顺藤摸瓜发现是rpcbind没能正常启动导致的nfs没能起来. 后来总结了两种办法:主要是ipv6的问题所导致的. 措施一: 报错内容 ...

  2. apache的commons-fileupload中FileItem类和ServletFileUpload

    FileItem类的常用方法      1.boolean  isFormField().isFormField方法用来判断FileItem对象里面封装的数据是一个普通文本表单字段,还是一个文件表单字 ...

  3. 一、hibernate环境搭建

    hibernate环境搭建 下载hibernate hibernate的jar 连接数据库的jar 解压hibernate,解压后目录结构 documentation :对应hibernate开发文档 ...

  4. Javascript基础二(程序的三大结构)

    程序的三大结构: 顺序结构,选择结构,循环结构 程序的单分支结构-if语句:       当条件判断为真true时,执行花括号内的语句,如果条件为假false,跳过花括号内的语句       if(条 ...

  5. spark on yarn提交任务时报ClosedChannelException解决方案

    spark2.1出来了,想玩玩就搭了个原生的apache集群,但在standalone模式下没有任何问题,基于apache hadoop 2.7.3使用spark on yarn一直报这个错.(Jav ...

  6. php随机生成数字加字母的字符串

    function getRandomString($len, $chars=null) { if (is_null($chars)) { $chars = "ABCDEFGHIJKLMNOP ...

  7. Linux下安装PHP的curl扩展

    先安装依赖包: yum install curl curl-devel 找到PHP的安装包,cd 进入安装包 cd php-5.6.25/ext/curl phpize 如果报找不到phpize就补全 ...

  8. hive建模方法

    转自:https://www.jianshu.com/p/8378b80e4b21 概述数据仓库这个概念是由 Bill Inmon 所提出的,其功能是将组织通过联机事务处理(OLTP)所积累的大量的资 ...

  9. 一:unittest框架配合selenium工具之CSS_selector定位。

    做了自动化测试这么久了,一直没有梳理到元素定位这一块的内容,其重要性不言而喻.趁着周末有时间,梳理一下. 1,通过id定位 driver.find_element_by_css_selector(&q ...

  10. 搭建hadoop集群 单机版

    二.在Ubuntu下创建hadoop用户组和用户         这里考虑的是以后涉及到hadoop应用时,专门用该用户操作.用户组名和用户名都设为:hadoop.可以理解为该hadoop用户是属于一 ...