zoukankan      html  css  js  c++  java
  • 数据库进阶

    • python关于mysql的API-----pymysql模块

    • 事务

    • 索引

    一、pymsql模块

    pymsql是python中操作MYSQL的模块

    1、模块的安装

    pip install pymysql / 也可以用pycharm自带的编译器内置安装

    2、执行sql语句

     1 # _*_ encoding:utf-8 _*_
     2 __author__ = 'listen'
     3 __date__ = '2018/12/13 21:51'
     4 import pymysql
     5 conn=pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='',db='s3')
     6 # cursor=conn.cursor()  #默认   元组形式
     7 cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)  #取数据字典的形式  知道取出来的东西是什么了
     8 # sql="""CREATE TABLE test(
     9 # id int primary key auto_increment,
    10 # name varchar(25),
    11 # age int
    12 # )
    13 
    14 # """
    15 # cursor.execute(sql)
    16 #添加数据
    17 # row_affected=cursor.execute('create table hello(id int primary key ,name varchar(20))')
    18 # row_affected=cursor.execute("insert into hello(id,name) values (1,'alex'),(2,'listen'),(3,'chunlv'),(4,'jia'),(5,'jian')")
    19 # row_affcted=cursor.execute('update hello set name="cheng" where id=5 ')
    20 
    21 #查询数据
    22 row_affected=cursor.execute('select * from hello')
    23 # print(row_affected)   #5   打印的是5
    24 one=cursor.fetchone()  #取一行数据
    25 # many=cursor.fetchmany(3)  #取多行,可以自定义参数
    26 # all=cursor.fetchall()  #所有的
    27 print(one)  #(1, 'alex')
    28 # print(many)  #((2, 'listen'), (3, 'chunlv'), (4, 'jia'))
    29 # print(all)  #((5, 'cheng'),)   若前面有取数据接着把后面所有数据取出来,若前面没做什么操作,直接把所有数据取出来((1, 'alex'), (2, 'listen'), (3, 'chunlv'), (4, 'jia'), (5, 'cheng'))
    30 
    31 #scroll  光标的位置移动
    32 print(cursor.fetchone())
    33 # cursor.scroll(1,mode='relative')  #正数是向下取,负数向上取  取相对位置
    34 # cursor.scroll(-1,mode='relative')
    35 cursor.scroll(1,mode='absolute')  #取绝对位置
    36 print(cursor.fetchone())
    37 
    38 conn.commit()  #针对于数据的提交  创建表不需要commit数据库中就会创建一个表 插入一条数据是必须提交了才会放到数据库里面去
    39 cursor.close()
    40 conn.close()

    二、事务

    事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部失败。

    转账实例

    数据库开启事务的命令:

    start transaction  开启事务

    Rollback  回滚事务,即撤销指定sql的语句(只能回退insert、update、delete语句),回滚到上一次commit的位置

    commit 提交事务,提交未存储的事务

    savepoint保留点,事务处理中设置的临时占位符,可以对它发布回退(与整个事务回退不同),回退到自己没出错的地方,不用全部回退(设置一个savepoint可以实现)。

    1、保留点的实例:

     

    2、python中调用数据库启动事务的方式

     1 # _*_ encoding:utf-8 _*_
     2 __author__ = 'listen'
     3 __date__ = '2018/12/15 10:07'
     4 import pymysql
     5 conn=pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='',db='s3')
     6 cursor=conn.cursor()
     7 # sql="""create table bank(id int primary key auto_increment,
     8 #                            name varchar(25),
     9 #                            money double
    10 # )
    11 # """
    12 # cursor.execute(sql)
    13 # insertsql = "insert into bank(name,money) values ('listen',6000)"
    14 # insertsql1 = "insert into bank(name,money) values ('jia',6000)"
    15 # cursor.execute(insertsql1)
    16 try:
    17     insertsql2="update bank set money=money-2000 where name='listen' "
    18     insertsql3="update bank set money=money+2000 where name='jia' "
    19     cursor=conn.cursor()
    20     cursor.execute(insertsql2)
    21     raise Exception  #要么全部成功  要么全部失败  回滚
    22     cursor.execute(insertsql3)
    23     cursor.close()
    24     conn.commit()
    25 except Exception as e:
    26     conn.rollback()
    27     conn.commit()
    28 
    29 
    30 #针对于数据的提交  创建表不需要commit数据库中就会创建一个表 插入一条数据是必须提交了才会放到数据库里面去
    31 cursor.close()
    32 conn.close()

    事务的特性

    1、原子性

    原子是一个不可分割的单位,正如事务是一个不可分割的工作单位,事务中的操作要不都发生,要不都不发生。

    2、一致性

    事务前后的数据完整性必须保持一执。在事务执行之前的数据库是符合数据完整性约束的,无论事务是否执行成功,事务结束后的数据库中的数据也应该符合完整性约束的。在某一时间点,如果数据库中所有的记录都能保证满足当前数据库中的所有约束,则可以睡当前的数据库是符合数据库完整性约束的。

    比如说:删除部门表事前应该删掉关联的员工(建立外键),如果数据库服务器发生错误,有一个员工没有删掉,那么此员工的部门表已经删除,那么就不符合完整性约束,这样性能的数据库就low爆了。

    3、隔离性

    事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间的数据库要相互隔离。

    4、持久性

    持久性是指一个事务一旦被提交,它对数据库中的数据的改变就是持久性的,接下来即使数据库发生故障也比应该对其产生任何影响。

    针对3、隔离性详解:

    将数据库设计为串行化程的数据库,让一张表在同一个时间内只能有一个线程来操作。如果将数据库设计为这样,效率太低了。所以数据库的设计者没有直接将数据设计为串行化,而为数据库提供多个隔离级别选项,使数据库的使用者可以根据使用情况自定义需要什么隔离级别。

    不考虑隔离性可能出现的问题:

    脏读:

    一个事务的数据读到了另一个事务未提交的数据,这是特别危险的,要尽力防止。

     1 --一个事务读取到了另一个事务未提交的数据,这是特别危险的,要尽力防止。
     2         a 1000
     3         b 1000
     4         a:
     5             start transaction;
     6             update set money=money+100 where name=b;
     7         b:
     8             start transaction;
     9             select * from account where name=b;--1100
    10             commit;
    11         a:
    12             rollback;
    13         b:  start transaction;
    14             select * from account where name=b;--1000

    不可重复读

     1 --在一个事务内读取表中的某一行数据,多次读取结果不同。(一个事务读取到了另一个事务已经提交
     2 -- 的数据--增加记录、删除记录、修改记录),在某写情况下并不是问题,在另一些情况下就是问题。
     3 
     4 a:
     5 start transaction;
     6 select 活期账户 from account where name=b;--1000    活期账户:1000
     7 select 定期账户 from account where name=b;--1000   定期账户:1000
     8 select 固定资产 from account where name=b;--1000   固定资产:1000
     9 ------------------------------
    10 b:
    11 start transaction;
    12 update set money=0 where name=b;
    13 commit;
    14 ------------------------------
    15 select 活期+定期+固定 from account where name=b; --2000 总资产: 2000

    虚读

     1 是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。(一个事务读取到了另一个事务已经提交的数据---增加记录、删除记录),在某写情况下并不是问题,在另一些情况下就是问题。
     2 
     3 b 1000
     4 c 2000
     5 d 3000
     6 a:
     7 start transaction
     8 select sum(money) from account;---3000       3000
     9 -------------------
    10 d:start transaction;
    11 insert into account values(d,3000);
    12 commit;
    13 -------------------
    14 select count(*)from account;---3                         3
    15 3000/3 = 1000                                            1000

    四个隔离级别:

    Serializable:可避免脏读、不可重复读、虚读情况的发生。(串行化)
    Repeatable read:可避免脏读、不可重复读情况的发生。(可重复读)不可以避免虚读
    Read committed:可避免脏读情况发生(读已提交)
    Read uncommitted:最低级别,以上情况均无法保证。(读未提交)

    安全性考虑:Serializable>Repeatable read>Read committed>Read uncommitted
    数据库效率:Read uncommitted>Read committed>Repeatable read>Serializable

    一般情况下,我们会使用Repeatable read、Read committed mysql数据库默认的数据库隔离级别Repeatable read

    mysql在pycharm中设置数据库的隔离级别语句:

     1 set [global/session] transaction isolation level xxxx 

    如果使用global则修改的是数据库的默认隔离级别,所有新开的窗口的隔离级别继承自这个默认隔离级别;如果使用session修改,则修改的是当前客户端的隔离级别,和数据库默认隔离级别无关。当前的客户端是什么隔离级别,就能防止什么隔离级别问题,和其他客户端是什么隔离级别无关。

    mysql中设置数据库的隔离级别语句(终端):

    select @@tx_isolation;

    三、索引

    1、索引简介

    索引在mysql中也叫做‘键’,是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,尤其是档表的数据量越来越大时,索引对于性能的影响就非常重要了。

    索引优化应该是对于查询性能最有效的手段了。

    索引能够轻易将查询性能提高好几个数量级。

    索引相当于字典的音序表,如果查新某个字,如果不使用音序表,则需要从几百页中查询。

    索引特点:创建与维护索引会消耗很多时间与磁盘空间,但查询速度大大会提高。

    2、索引语法

    1 create table 表名(
    2 字段1 数据类型[完整性约束条件],
    3 字段2 数据类型[完整性约束条件],
    4 [UNIQUE | FULLTEXT |SPATIAL] INDEX | KEY 
    5 [索引名] (字段名 数据类型) [asc|desc ]
    6 )
     1 # _*_ encoding:utf-8 _*_
     2 __author__ = 'listen'
     3 __date__ = '2018/12/16 10:27'
     4 --语法:
     5 -- create table 表名(
     6 -- 字段1 数据类型[完整性约束条件],
     7 -- 字段2 数据类型[完整性约束条件],
     8 -- [UNIQUE | FULLTEXT |SPATIAL] INDEX | KEY 
     9 -- [索引名] (字段名 [数据类型]) [asc|desc ]
    10 -- )
    11 -------------------------------------------------------------------
    12 
    13 --创建普通索引示例:
    14 
    15     CREATE TABLE emp1 (
    16         id INT,
    17         name VARCHAR(30) ,
    18         resume VARCHAR(50),
    19         INDEX index_emp_name (name)
    20     --KEY index_dept_name (dept_name)
    21         );
    22 
    23 
    24 
    25 --创建唯一索引示例:
    26 
    27     CREATE TABLE emp2 (
    28         id INT,
    29         name VARCHAR(30) ,
    30         bank_num CHAR(18) UNIQUE ,
    31         resume VARCHAR(50),
    32         UNIQUE INDEX index_emp_name (name)
    33         );
    34 
    35 --创建全文索引示例:
    36 
    37     CREATE TABLE emp3 (
    38         id INT,
    39         name VARCHAR(30) ,
    40         resume VARCHAR(50),
    41         FULLTEXT INDEX index_resume (resume)
    42         );
    43 
    44 --创建多列索引示例:
    45 
    46     CREATE TABLE emp4 (
    47         id INT,
    48         name VARCHAR(30) ,
    49         resume VARCHAR(50),
    50         INDEX index_name_resume (name, resume)
    51         );
    52 
    53 
    54 
    55 ---------------------------------
    56 
    57 ---添加索引
    58 
    59     ---CREATE在已存在的表上创建索引
    60       CREATE  [UNIQUE | FULLTEXT | SPATIAL ]  INDEX  索引名
    61               ON 表名 (字段名[(长度)]  [ASC |DESC]) ;
    62     
    63     ---ALTER TABLE在已存在的表上创建索引
    64     
    65       ALTER TABLE 表名 ADD  [UNIQUE | FULLTEXT | SPATIAL ] INDEX
    66                     索引名 (字段名[(长度)]  [ASC |DESC]) ;
    67     
    68     
    69     
    70      CREATE INDEX index_emp_name on emp1(name);
    71      ALTER TABLE emp2 ADD UNIQUE INDEX index_bank_num(band_num);
    72 
    73 
    74 -- 删除索引
    75     
    76     语法:DROP INDEX 索引名 on 表名
    77     
    78     DROP INDEX index_emp_name on emp1;
    79     DROP INDEX bank_num on emp2;

    3、索引效率测试

    delimiter可以修改终端的结束符从;变为你想变得 

     1 --创建表
     2 create table Indexdb.t1(id int,name varchar(20));
     3 
     4 
     5 --存储过程
     6 
     7 delimiter $$
     8 create procedure autoinsert() 
     9 BEGIN
    10 declare i int default 1;
    11 while(i<500000)do
    12 insert into Indexdb.t1 values(i,'yuan');
    13 set i=i+1;
    14 end while;
    15 END$$
    16 
    17 delimiter ;
    18 
    19 --调用函数
    20 call autoinsert();
    21 
    22 -- 花费时间比较:
    23 -- 创建索引前
    24    select * from Indexdb.t1 where id=300000;--0.32s
    25 -- 添加索引 
    26    create index index_id on Indexdb.t1(id);
    27 -- 创建索引后
    28    select * from Indexdb.t1 where id=300000;--0.00s

  • 相关阅读:
    与客服聊天功能测试点
    京东优惠券如何测试
    Linux笔试题
    线程与线程池原理
    PyCharm 介绍、安装、入门使用
    银行APP测试用户体验性方面
    python的闭包
    列表解析2
    深入函数
    再谈装饰器@@@
  • 原文地址:https://www.cnblogs.com/shijia-listen/p/10125890.html
Copyright © 2011-2022 走看看