Python之旅.第十章.mysql..

1、視圖python

1、什麼是視圖mysql

   虛擬表:在硬盤中沒有的,經過查詢在內存中拼接的表web

   視圖:經過查詢獲得一張虛擬表,保存下來,下次可直接使用sql

 

2、爲何要用視圖數據庫

   若是要頻繁使用一張虛擬表,能夠不用重複查詢網絡

 

3、如何用視圖數據結構

create view teacher2course as select * from teacher inner join course on teacher.tid = course.teacher_id;框架

 

4、刪除視圖ide

drop view teacher2course;函數

 

5、強調

1、在硬盤中,視圖只有表結構文件(.frm),沒有表數據文件(.idb); 其在後臺對應的是一條sql語句

2、視圖一般是用於查詢,儘可能不要修改視圖中的數據

 

2、觸發器

1、觸發器:在知足對某張表數據的增、刪、改的狀況下,自動觸發的功能稱之爲觸發器

 

2、爲什麼要用觸發器?

   觸發器專門針對咱們對某一張表數據增insert、刪delete、改update的行爲,這類行爲一旦執行就會觸發觸發器的執行,即自動運行另一段sql代碼

 

3、建立觸發器語法

# 針對插入

create trigger tri_after_insert_t1 after insert on 表名 for each row  #after

begin        #begin end sql中用於標誌同一執行級別的代碼;至關於python中的縮進

    sql代碼。。。

end

 

create trigger tri_before_insert_t2 before insert on 表名 for each row  #before

begin

    sql代碼。。。

end

 

# 針對刪除

create trigger tri_after_delete_t1 after delete on 表名 for each row

begin

    sql代碼。。。

end

 

create trigger tri_before_delete_t2 before delete on 表名 for each row

begin

    sql代碼。。。

end

 

# 針對修改

create trigger tri_after_update_t1 after update on 表名 for each row

begin

    sql代碼。。。

end

 

create trigger tri_before_update_t2 before update on 表名 for each row

begin

    sql代碼。。。

end

 

#刪除觸發器

drop trigger tri_after_insert_cmd;

 

4、案例

CREATE TABLE cmd (

    id INT PRIMARY KEY auto_increment,

    USER CHAR (32),

    priv CHAR (10),

    cmd CHAR (64),

    sub_time datetime, #提交時間

    success enum ('yes', 'no') #0表明執行失敗

);

 

CREATE TABLE errlog (

    id INT PRIMARY KEY auto_increment,

    err_cmd CHAR (64),

    err_time datetime

);

 

delimiter $$   #修改sql中的默認分隔符,從;改爲$$

create trigger tri_after_insert_cmd after insert on cmd for each row   #觸發器名稱要儘量詳細如例

begin

    if NEW.success = 'no' then    # NEWmysql對新插入記錄的封裝名; 若是不用mysql的觸發器,能夠在本身的應用程序中加if判斷

        insert into errlog(err_cmd,err_time) values(NEW.cmd,NEW.sub_time);

    end if;    # mysql中固定用法

end $$         # $$表一行語句終結

delimiter ;    # sql中的默認分隔符改回;

 

3、事務(重要)

1、什麼是事務

   開啓一個事務能夠包含一些sql語句,這些sql語句要麼同時成功;要麼一個都別想成功,稱之爲事務的原子性

 

2、事務的做用:轉帳等,屏蔽因網絡傳輸部分失效而帶來的影響

 

3、如何用 (如下爲運行邏輯,非代碼)

create table user(

id int primary key auto_increment,

name char(32),

balance int

);

 

insert into user(name,balance)

values

('wsb',1000),

('egon',1000),

('ysb',1000);

 

try:

    update user set balance=900 where name='wsb'; #買支付100

    update user set balance=1010 where name='egon'; #中介拿走10

    update user set balance=1090 where name='ysb'; #賣家拿到90

except 異常:

    rollback;   #若是異常,回滾到前一個狀態,即balance都爲1000

else:

commit;   #若是無異常,修改數據庫(硬盤上的數據)

 

4、存儲過程(重要)

#mysql中函數是不能單獨使用的,必須放在sql語句中使用;但存儲過程是能夠單獨使用的

1、存儲過程:存儲過程包含了一系列可執行的sql語句,存儲過程存放於MySQL中,經過調用它的名字能夠執行其內部的一堆sql

 

2、三種開發模型

    a、(若是不考慮非技術因素,各方面效率最高的選擇;但考慮到實際狀況,通常不被選擇)

        應用程序:只須要開發應用程序的邏輯

        mysql:編寫好存儲過程,以供應用程序調用

        優勢:開發效率,執行效率都高

        缺點:考慮到人爲因素、跨部門溝通等問題,會致使擴展性差

 

    b、(與c的思路一致,會被使用)

        應用程序:除了開發應用程序的邏輯,還須要編寫原生sql

        mysql

        優勢:比方式1,擴展性高(非技術性的)

        缺點:

            1、開發效率,執行效率都不如方式1

            2、編寫原生sql太過於複雜,並且須要考慮到sql語句的優化問題

 

    c、(考慮到非技術因素,最多見的選擇)

        應用程序:開發應用程序的邏輯,不須要編寫原生sql,基於別人編寫好的框架來處理數據,ORMobject relationship matching

        mysql

        優勢:不用再編寫純生sql,這意味着開發效率比方式2高,同時兼容方式2擴展性高的好處

        缺點:執行效率連方式2都比不過

 

3、建立存儲過程

delimiter $$

create procedure p1(   #建立存儲過程p1

    in m int,    #mysql中參數必須先規定類型和用途(inoutinout

    in n int,

    out res int  #res用於接收返回值

)

begin

    select tname from teacher where tid > m and tid < n;

    set res=0;

end $$

delimiter ;

 

4、如何用存儲過程

a、直接在mysql中調用

set @res=10   #mysql中變量的定義要用@abc的形式

call p1(2,4,@res);

 

select @res;  #查看結果

 

b、在python程序中調用

import pymysql

 

conn=pymysql.connect(

    host='127.0.0.1',

    port=3306,

    user='root',

    password='123',

    charset='utf8',

    database='db42'

)

 

cursor=conn.cursor(pymysql.cursors.DictCursor)

cursor.callproc('p1',(2,4,10)) #@_p1_0=2,@_p1_1=4,@_p1_2=10  #pymysql幫助對傳入變量進行以上變形

print(cursor.fetchall())

cursor.execute('select @_p1_2;')  #查看返回值,確認執行結果

print(cursor.fetchone())

 

cursor.close()

conn.close()

 

5、事務的使用 (事務+存儲過程)

delimiter //

create PROCEDURE p5(

    OUT p_return_code tinyint

)

BEGIN

    DECLARE exit handler for sqlexception  #若是出現錯誤,執行

    BEGIN

        -- ERROR

        set p_return_code = 1;

        rollback;

    END;

 

    DECLARE exit handler for sqlwarning    #若是出現警告,執行

    BEGIN

        -- WARNING

        set p_return_code = 2;

        rollback;

    END;

 

    START TRANSACTION;                     #事務的應用

        update user set balance=900 where id =1;

        update user123 set balance=1010 where id = 2;

        update user set balance=1090 where id =3;

    COMMIT;

 

    -- SUCCESS

    set p_return_code = 0; #0表明執行成功

 

END //

delimiter ;

 

#python中調用存儲過程

import pymysql

 

conn=pymysql.connect(

    host='127.0.0.1',

    port=3306,

    user='root',

    password='123',

    charset='utf8',

    database='db44'

)

 

cursor=conn.cursor(pymysql.cursors.DictCursor)

cursor.callproc('p6',(100,)) #@_p5_0 = 100

cursor.execute('select @_p6_0')

print(cursor.fetchone())

 

cursor.close()

conn.close()

 

5、函數

1、強調:mysql內置的函數只能在sql語句中使用

mysql> select date_format(sub_time,'%Y-%m'),count(id) from blog group by date_format(sub_time,'%Y-%m');

 

2、補充

aselect * from s1 \G   #表字段太多(字段行顯示不全)時,用\G將表豎着顯示出來: row1 哪些字段: 對應的內容,row2。。。

b、視圖、觸發器、事務、存儲過程、函數、流程控制皆是在庫下面創建

 

6、流程控制 ifwhilecase

#case

select

case

when name = 'egon' then

    name

when name = 'alex' then

    concat(name,'_BIGSB')

else

    concat(name,'_SB')

end

 

from emp;

 

7、索引

1、爲何要用索引

   對於一個應用來講,對數據庫的讀寫比例基本上是10:1,即讀多寫少

   並且對於寫來講極少出現性能問題,大多數性能問題都是慢查詢

   提到加速查,就必須用到索引

 

2、什麼是索引

   索引就至關於書的目錄,是mysql中一種專門的數據結構,稱爲keyprimary keyuniqueindex key

   索引的本質原理就是經過不斷地縮小查詢範圍,來下降io次數從而提高查詢性能

   強調:一旦爲表建立了索引,之後的查詢都會先查索引,再根據索引定位的結果去找數據(同一種方式)

 

3、索引的影響(先有數據,後有索引;索引,亦佔硬盤空間)

   a、在表中有大量數據的前提下,建立索引速度會很慢

   b、在索引建立完畢後,對錶的查詢性能會大幅度提高,可是寫性能會下降

 

4B+樹:只有葉子節點才存放真實數據,其餘的(根節點、枝節點)都是虛擬數據

 

   a、一次IO走一個block

   b、淺藍-block塊; 深藍-數據項; -指針

   c、爲下降IO次數-》下降樹的高度-》數據項越小越好(block塊大小必定的狀況下,數據項越小,存放的數據量最多)-》採用佔空間少的作索引(好比id

 

5、索引的最左匹配特性(從左到右一次匹配)

 

6、彙集索引(primary key): 組織數據時就按照此索引組織

   特色:葉子節點存放的一整條數據

 

7、輔助索引(uniqueindex

   特色:若是是按照這個字段建立的索引,那麼葉子節點存放的是:{名字:名字所在那條記錄的主鍵的值}

        innodb的索引存放在表數據裏(.idb

    a、覆蓋索引:只在輔助索引的葉子節點中就已經找到了全部咱們想要的數據

    select name from user where name='egon';

    b、回表操做

    select age from user where name='egon';

 

8、補充: 權限管理

   a、受權

   grant all on *.* to 'egon' @'192.168.12.%' identified by '123';   #all指的是除了grant之外的所有權限

   flush privileges;

   exist

   b、刪除權限

   revoke select on db1.* from 'egon'@'%';

 

9、其餘:

   a、對區別度低的數據不要建索引,且索引不是越多越好

   b、注意範圍問題,或者說條件不明確的問題 (條件中出現這些符號或關鍵字:>>=<<=!= between...and...like

   cmysql中對 a and b and c。。的形式,會先從有索引或區分度高的數據入手開始查詢,以減小查詢範圍

   dmysql中對 a or b or c。。的形式,會從左至右依次查詢

   e、索引列不要參與計算,若是非要運算 a\12=3 ===> a=3\12

   f、聯合索引的原則:

      區別度高、範圍小的放左邊,區別度低、範圍大的放右邊

     email, name, gender, id):能夠搜(email)(email,name, gender)等(含email),不能搜(id)等

相關文章
相關標籤/搜索