python關於mysql的API--pymysql模塊
pymsql是Python中操作MySQL的模塊,其使用方法和py2的MySQLdb幾乎相同。
模塊安裝
執行sql語句
import pymysql
#添加數據
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='yyy')
cursor = conn.cursor()
# sql = """CREATE TABLE EMPLOYEE (
# FIRST_NAME CHAR(20) NOT NULL,
# LAST_NAME CHAR(20),
# AGE INT,
# SEX CHAR(1),
# INCOME FLOAT )"""
#
# cursor.execute(sql)
#row_affected = cursor.execute("create table t1(id INT ,name VARCHAR(20))")
#row_affected=cursor.execute("INSERT INTO t1(id,name) values (1,'alvin'),(2,'xialv')")
#cursor.execute("update t1 set name = 'silv2' where id=2")
#查詢數據
row_affected=cursor.execute("select * from t1")
one=cursor.fetchone()
# many=cursor.fetchmany(2)
# all=cursor.fetchall()
#scroll
#cursor.scroll(-1,mode='relative') # 相對當前位置移動
#cursor.scroll(2,mode='absolute') # 相對絕對位置移動
#更改獲取數據結果的數據類型,默認是元組,可以改為字典等:conn.cursor(cursor=pymysql.cursors.DictCursor)
conn.commit()
cursor.close()
conn.close()
事務
事務命令
事務指邏輯上的一組操作,組成這組操作的各個單元,要不全部成功,要不全部不成功。
數據庫開啟事務命令
-- start transaction 開啟事務
-- Rollback 回滾事務,即撤銷指定的sql語句(只能回退insert delete update語句),回滾到上一次commit的位置
-- Commit 提交事務,提交未存儲的事務
--
-- savepoint 保留點 ,事務處理中設置的臨時占位符 你可以對它發布回退(與整個事務回退不同)
轉賬實例:
UPDATE account set balance=balance-5000 WHERE name=”yuan”;
UPDATE account set balance=balance+5000 WHERE name=”xialv”;
create table test2(id int PRIMARY KEY auto_increment,name VARCHAR(20)) engine=innodb;
INSERT INTO test2(name) VALUE ("alvin"),
("yuan"),
("xialv");
start transaction;
insert into test2 (name)values('silv');
select * from test2;
commit;
-- 保留點
start transaction;
insert into test2 (name)values('wu');
savepoint insert_wu;
select * from test2;
delete from test2 where id=4;
savepoint delete1;
select * from test2;
delete from test2 where id=1;
savepoint delete2;
select * from test2;
rollback to delete1;
select * from test2;
savepoint
python中調用數據庫啟動事務的方式
import pymysql
#添加數據
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='yyy')
cursor = conn.cursor()
try:
insertSQL0="INSERT INTO ACCOUNT2 (name,balance) VALUES ('oldboy',4000)"
insertSQL1="UPDATE account2 set balance=balance-30 WHERE name='yuan'"
insertSQL2="UPDATE account2 set balance=balance+30 WHERE name='xialv'"
cursor = conn.cursor()
cursor.execute(insertSQL0)
conn.commit()
cursor.execute(insertSQL1)
raise Exception
cursor.execute(insertSQL2)
cursor.close()
conn.commit()
except Exception as e:
conn.rollback()
conn.commit()
cursor.close()
conn.close()
View Code
事務特性
<1> 原子性(Atomicity):原子性是指事務是一個不可分割的工作單位,事務中的操作要么都發生,要么都不發生。
<2> 一致性(Consistency):事務前后數據的完整性必須保持一致。在事務執行之前數據庫是符合數據完整性約束的,無論事務是否執行成功,事務結束后的數據庫中的數據也應該是符合完整性約束的。在某一時間點,如果數據庫中的所有記錄都能保證滿足當前數據庫中的所有約束,則可以說當前的數據庫是符合數據完整性約束的。
比如刪部門表前應該刪掉關聯員工(已經建立外鍵),如果數據庫服務器發生錯誤,有一個員工沒刪掉,那么此時員工的部門表已經刪除,那么就不符合完整性約束了,所以這樣的數據庫也就性能太差啦!
<3>隔離性(Isolation):事務的隔離性是指多個用戶並發訪問數據庫時,一個用戶的事務不能被其它用戶的事務所干擾,多個並發事務之間數據要相互隔離。
<4>持久性(Durability):持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,接下來即使數據庫發生故障也不應該對其有任何影響。
三、隔離性:
將數據庫設計為串行化程的數據庫,讓一張表在同一時間內只能有一個線程來操作。如果將數據庫設計為這樣,那數據庫的效率太低了。所以數據庫的設計這沒有直接將數據庫設計為串行化,而是為數據庫提供多個隔離級別選項,使數據庫的使用者可以根據使用情況自己定義到底需要什么樣的隔離級別。
不考慮隔離性可能出現的問題:
臟讀
--一個事務讀取到了另一個事務未提交的數據,這是特別危險的,要盡力防止。
a 1000
b 1000
a:
start transaction;
update set money=money+100 where name=b;
b:
start transaction;
select * from account where name=b;--1100
commit;
a:
rollback;
b: start transaction;
select * from account where name=b;--1000
View Code
不可重復讀
--在一個事務內讀取表中的某一行數據,多次讀取結果不同。(一個事務讀取到了另一個事務已經提交
-- 的數據--增加記錄、刪除記錄、修改記錄),在某寫情況下並不是問題,在另一些情況下就是問題。
a:
start transaction;
select 活期賬戶 from account where name=b;--1000 活期賬戶:1000
select 定期賬戶 from account where name=b;--1000 定期賬戶:1000
select 固定資產 from account where name=b;--1000 固定資產:1000
------------------------------
b:
start transaction;
update set money=0 where name=b;
commit;
------------------------------
select 活期+定期+固定 from account where name=b; --2000 總資產: 2000
View Code
虛讀
是指在一個事務內讀取到了別的事務插入的數據,導致前后讀取不一致。(一個事務讀取到了另一個事務已經提交的數據---增加記錄、刪除記錄),在某寫情況下並不是問題,在另一些情況下就是問題。
b 1000
c 2000
d 3000
a:
start transaction
select sum(money) from account;---3000 3000
-------------------
d:start transaction;
insert into account values(d,3000);
commit;
-------------------
select count(*)from account;---3 3
3000/3 = 1000 1000
View Code
四個隔離級別:
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中設置數據庫的隔離級別語句:
set [global/session] transaction isolation level xxxx;
如果使用global則修改的是數據庫的默認隔離級別,所有新開的窗口的隔離級別繼承自這個默認隔離級別如果使用session修改,則修改的是當前客戶端的隔離級別,和數據庫默認隔離級別無關。當前的客戶端是什么隔離級別,就能防止什么隔離級別問題,和其他客戶端是什么隔離級別無關。
mysql中設置數據庫的隔離級別語句:
索引
一 索引簡介
索引在MySQL中也叫做“鍵”,是存儲引擎用於快速找到記錄的一種數據結構。索引對於良好的性能非常關鍵,尤其是當表中的數據量越來越大時,索引對於性能的影響愈發重要。
索引優化應該是對查詢性能優化最有效的手段了。
索引能夠輕易將查詢性能提高好幾個數量級。
索引相當於字典的音序表,如果要查某個字,如果不使用音序表,則需要從幾百頁中逐頁去查。
索引特點:創建與維護索引會消耗很多時間與磁盤空間,但查詢速度大大提高!
二 索引語法
--創建表時
--語法:
CREATE TABLE 表名 (
字段名1 數據類型 [完整性約束條件…],
字段名2 數據類型 [完整性約束條件…],
[UNIQUE | FULLTEXT | SPATIAL ] INDEX | KEY
[索引名] (字段名[(長度)] [ASC |DESC])
);
--------------------------------
--創建普通索引示例:
CREATE TABLE emp1 (
id INT,
name VARCHAR(30) ,
resume VARCHAR(50),
INDEX index_emp_name (name)
--KEY index_dept_name (dept_name)
);
--創建唯一索引示例:
CREATE TABLE emp2 (
id INT,
name VARCHAR(30) ,
bank_num CHAR(18) UNIQUE ,
resume VARCHAR(50),
UNIQUE INDEX index_emp_name (name)
);
--創建全文索引示例:
CREATE TABLE emp3 (
id INT,
name VARCHAR(30) ,
resume VARCHAR(50),
FULLTEXT INDEX index_resume (resume)
);
--創建多列索引示例:
CREATE TABLE emp4 (
id INT,
name VARCHAR(30) ,
resume VARCHAR(50),
INDEX index_name_resume (name, resume)
);
---------------------------------
---添加索引
---CREATE在已存在的表上創建索引
CREATE [UNIQUE | FULLTEXT | SPATIAL ] INDEX 索引名
ON 表名 (字段名[(長度)] [ASC |DESC]) ;
---ALTER TABLE在已存在的表上創建索引
ALTER TABLE 表名 ADD [UNIQUE | FULLTEXT | SPATIAL ] INDEX
索引名 (字段名[(長度)] [ASC |DESC]) ;
CREATE INDEX index_emp_name on emp1(name);
ALTER TABLE emp2 ADD UNIQUE INDEX index_bank_num(band_num);
-- 刪除索引
語法:DROP INDEX 索引名 on 表名
DROP INDEX index_emp_name on emp1;
DROP INDEX bank_num on emp2;
三 索引測試實驗
--創建表
create table Indexdb.t1(id int,name varchar(20));
--存儲過程
delimiter $$
create procedure autoinsert()
BEGIN
declare i int default 1;
while(i<500000)do
insert into Indexdb.t1 values(i,'yuan');
set i=i+1;
end while;
END$$
delimiter ;
--調用函數
call autoinsert();
-- 花費時間比較:
-- 創建索引前
select * from Indexdb.t1 where id=300000;--0.32s
-- 添加索引
create index index_id on Indexdb.t1(id);
-- 創建索引后
select * from Indexdb.t1 where id=300000;--0.00s