博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据库进阶
阅读量:6090 次
发布时间:2019-06-20

本文共 8368 字,大约阅读时间需要 27 分钟。

  • 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 int12 # )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   打印的是524 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 double10 # )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;--110010             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                         315 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 ] INDEX66                     索引名 (字段名[(长度)]  [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 BEGIN10 declare i int default 1;11 while(i<500000)do12 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.32s25 -- 添加索引 26    create index index_id on Indexdb.t1(id);27 -- 创建索引后28    select * from Indexdb.t1 where id=300000;--0.00s

 

转载于:https://www.cnblogs.com/shijia-listen/p/10125890.html

你可能感兴趣的文章
unity将object[]或者string对象转换成枚举enum
查看>>
以太坊系列之六: p2p模块--以太坊源码学习
查看>>
使用scikit-learn解决文本多分类问题(附python演练)
查看>>
2018 年最值得关注的 JavaScript 趋势
查看>>
什么是区块链?超级账本 Brian Behlendorf 从五个方面教你认识
查看>>
Linux中的帮助功能
查看>>
针对Android的Pegasus恶意软件版本和针对iOS的有什么不同?
查看>>
全局探色器
查看>>
Hive Export和Import介绍及操作示例
查看>>
http://mongoexplorer.com/ 一个不错的 mongodb 客户端工具。。。
查看>>
上传jar包到nexus私服
查看>>
Why Namespace? - 每天5分钟玩转 OpenStack(102)
查看>>
Project:如何分析项目中的资源分配情况
查看>>
HDU 4803 Poor Warehouse Keeper (贪心+避开精度)
查看>>
小错误汇总
查看>>
Spring源码系列 — Envoriment组件
查看>>
java正则表达式去除html标签,Java中正则表达式去除html标签
查看>>
使用Cobbler批量部署Linux操作系统
查看>>
zabbix企业应用之服务端与客户端的安装
查看>>
实例讲解遗传算法——基于遗传算法的自动组卷系统【理论篇】
查看>>