Mysql之pymysql

==============摘自https://www.cnblogs.com/yuanchenqi/articles/6437362.html================html

1、pymysqlpython

pymsql是Python中操做MySQL的模塊,其使用方法和py2的MySQLdb幾乎相同。mysql

一、安裝pymysqlsql

pip install pymysql

 

二、執行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()

 

2、事務安全

事務指邏輯上的一組操做,組成這組操做的的各個單元,要不所有成功,要不所有不成功;性能優化

一、數據庫開啓事務命令服務器

--        start transaction 開啓事務
--        Rollback 回滾事務,即撤銷指定的sql語句(只能回退insert delete update語句),回滾到上一次commit的位置
--        Commit 提交事務,提交未存儲的事務
-- 
--        savepoint 保留點 ,事務處理中設置的臨時佔位符 你能夠對它發佈回退(與整個事務回退不一樣) 

 

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中調用數據庫啓動事務的方式session

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()

 

三、事務的特性數據結構

(1)、原子性(Atomicity):原子性是指事務是一個不可分割的工做單位,事務中的操做要麼都發生,要麼都不發生。

(2)、一致性(Consistency):事務先後數據的完整性必須保持一致。在事務執行以前數據庫是符合數據完整性約束的,不管事務是否執行成功,事務結束後的數據庫中的數據也應該是符合完整性約束的。在某一時間點,若是數據庫中的全部記錄都能保證知足當前數據庫中的全部約束,則能夠說當前的數據庫是符合數據完整性約束的。
好比刪部門表前應該刪掉關聯員工(已經創建外鍵),若是數據庫服務器發生錯誤,有一個員工沒刪掉,那麼此時員工的部門表已經刪除,那麼就不符合完整性約束了,因此這樣的數據庫也就性能太差啦!

(3)、隔離性(Isolation):事務的隔離性是指多個用戶併發訪問數據庫時,一個用戶的事務不能被其它用戶的事務所幹擾,多個併發事務之間數據要相互隔離。

(4)、持久性(Durability):持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,接下來即便數據庫發生故障也不該該對其有任何影響。

四、隔離性

將數據庫設計爲串行化程的數據庫,讓一張表在同一時間內只能有一個線程來操做。若是將數據庫設計爲這樣,那數據庫的效率過低了。因此數據庫的設計這沒有直接將數據庫設計爲串行化,而是爲數據庫提供多個隔離級別選項,使數據庫的使用者能夠根據使用狀況本身定義到底須要什麼樣的隔離級別。

不考慮隔離性可能出現的問題:

(1)、髒讀

--一個事務讀取到了另外一個事務未提交的數據,這是特別危險的,要盡力防止。
        a 1000
        b 1000
        a:
            start transactionupdate 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

 

(2)、不可重複讀

--在一個事務內讀取表中的某一行數據,屢次讀取結果不一樣。(一個事務讀取到了另外一個事務已經提交
-- 的數據--增長記錄、刪除記錄、修改記錄),在某寫狀況下並非問題,在另外一些狀況下就是問題。

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

 

(3)、虛讀

是指在一個事務內讀取到了別的事務插入的數據,致使先後讀取不一致。(一個事務讀取到了另外一個事務已經提交的數據---增長記錄、刪除記錄),在某寫狀況下並非問題,在另外一些狀況下就是問題。

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

 

(4)、4個隔離級別

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中設置數據庫的隔離級別語句:

 select @@tx_isolation; 

3、索引

一、什麼是索引

索引在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
相關文章
相關標籤/搜索