1. 程式人生 > >day40 python MySQL【四】 之 【索引】【視圖】【觸發器】【存儲過程】【函數】

day40 python MySQL【四】 之 【索引】【視圖】【觸發器】【存儲過程】【函數】

cin 數量 存儲 自動 條件語句 ima doc 有序 lan

1.索引

  索引相當於圖書的目錄,可以幫助用戶快速的找到需要的內容.

  數據庫利用各種各樣的快速定位技術,能夠大大提高查詢效率。特別是當數據量非常大,查詢涉及多個表時,使用索引往往能使查詢速度加快成千上萬倍.

  索引好處:可以提高查詢效率,而且是數據量越大效果越明顯.

  索引缺點:添加數據和刪除數據效率低

  索引類型:

  1.HASH :hash就是一種(key=>value)形式的鍵值對,允許多個key對應相同的value,但不允許一個key對應多個value,為某一列或幾列建立hash索引,就會利用這一列或幾列的值通過一定的算法計算出一個hash值,對應一行或幾行數據.

hash索引可以一次定位,不需要像樹形索引那樣逐層查找,因此具有極高的效率.

  假設創建如下一個表:
    CREATE TABLE testhash (
     fname VARCHAR(50) NOT NULL,
    lname VARCHAR(50) NOT NULL,
    KEY USING HASH(fname)
    ) ENGINE=MEMORY;
  包含的數據如下:
    

  假設索引使用hash函數f( ),如下:

f(‘Arjen‘) = 2323

f(‘Baron‘) = 7437

f(‘Peter‘) = 8784

f(‘Vadim‘) = 2458

  此時,索引的結構大概如下:

   

Slots是有序的,但是記錄不是有序的。當你執行
  mysql> SELECT lname FROM testhash WHERE fname=‘Peter‘;
MySQL會計算’Peter’的hash值,然後通過它來查詢索引的行指針。因為f(‘Peter‘) = 8784,MySQL會在索引中查找8784,得到指向記錄3的指針。
因為索引自己僅僅存儲很短的值,所以,索引非常緊湊。Hash值不取決於列的數據類型,一個TINYINT列的索引與一個長字符串列的索引一樣大。

  2.BTREE: 就是一種將索引值按一定的算法,存入一個樹形的數據結構中. 如二叉樹一樣

  

 

  索引分類:

    1. 普通索引

    2.唯一索引

    3.主鍵索引

    4.組合索引

    5. FULLTEXT:全文索引

     目前只有MyISAM引擎支持。而且只有 CHAR、VARCHAR ,TEXT 列上可以創建全文索引.

    FULLTEXT索引是按照分詞原理建立索引的。西文中,大部分為字母文字,分詞可以很方便的按照空格進行分割。但很明顯,中文不能按照這種方式進行分詞。那又怎麽辦呢?這個向大家介紹一個Mysql的中文分詞插件Mysqlcft,有了它,就可以對中文進行分詞,想了解的同學請移步Mysqlcft,當然還有其他的分詞插件可以使用。

1.創建 普通索引

1 CREATE index aaa on ren(p_name)
2 添加普通索引
3 註意:index :表示索引 aaa:表示索引的別名, on:表示給哪個表添加索引  ren:表名稱,(添加索引的字段,多個字段以","間隔)

2.創建 唯一索引

1 CREATE UNIQUE index age on ren(p_age)
2 添加唯一索引
3 註意:unique index :表示唯一索引 aaa:表示索引的別名, on:表示給哪個表添加索引  ren:表名稱,(添加索引的字段,多個字段以","間隔)

3.創建 主鍵索引

1 alter table 表名 add primary key(id);
2 添加之間索引
3 註意:主鍵索引只能有一個

4.創建 組合索引

1 create index id_name on ren (id,name)
2 添加組合索引
3 註意: 如上創建組合索引之後,查詢:
4 id and name-- 使用索引
5 id                -- 使用索引
6 name           -- 不使用索引

2.視圖

視圖是一個虛擬表,其內容由查詢定義。同真實的表一樣,視圖包含一系列帶有名稱的列和行數據。但是,視圖並不在數據庫中以存儲的數據值集形式存在。行和列數據來自定義視圖的查詢所引用的表,並且在引用視圖時動態生成。

  視圖好處:

     a、簡化表之間的聯結(把聯結寫在select中);

     b、適當的利用視圖可以更清晰地表達查詢

     c、過濾不想要的數據(select部分)視圖能夠對機密數據提供安全保護

     d、使用視圖計算字段值,如匯總這樣的值。

  1.創建視圖

1 #create view 視圖名稱  as sql 查詢語句
2 CREATE view ren_view as select p_id,p_name,p_age,p_leader from ren;

  2.使用視圖

1 select * from 視圖名稱;

  3.更新視圖數據

1 update ren_view set p_age =99 where p_id = ‘p004‘;

  4.刪除視圖數據

1 DELETE from ren_view where p_id = ‘p010‘;

  5.刪除視圖

1 drop view ren_view;

3.觸發器-trigger

  觸發器(trigger):監視某種情況,並觸發某種操作。

  觸發器創建語法四要素:1.監視地點(table)

             2.監視事件(insert/update/delete)

             3.觸發時間(after/before)

             4.觸發事件(insert/update/delete)

  1.創建觸發器語法

 1 create trigger triggerName  after/before  insert/update/delete
 2     on 表名 for each row #這句話是固定的
 3 
 4 begin
 5      
 6     #需要執行的sql語句
 7 
 8 end
 9 
10 註意1:after/before: 只能選一個 ,after 表示 後置觸發, before 表示前置觸發
11 註意2:insert/update/delete:只能選一個

創建兩張表

#商品表

create table goods(

id int primary key auto_increment,

name varchar(20),

num int

);

#訂單表

create table order_table(

oid int primary key auto_increment,

gid int,

much int

);

添加3條商品數據

1 insert into g(name,num) values(‘商品1‘,10),(‘商品2‘,10),(‘商品3‘,10);

如果我們在沒使用觸發器之前:假設我們現在賣了3個商品1,我們需要做兩件事

1.往訂單表插入一條記錄

1 insert into o(gid,much) values(1,3);

2.更新商品表商品1的剩余數量

update g set num=num-3 where id=1;

現在,我們來創建一個觸發器:

1 create trigger tg1 after insert on  order_table for each row
2 
3 begin 
4     
5     update goods set num = num -3 where id = 1;
6 
7 end 

這時候我們只要執行:

1 insert into order_table(gid,much) values(1,3);                

會發現商品1的數量變為7了,說明在我們插入一條訂單的時候,

觸發器自動幫我們做了更新操作。

但現在會有一個問題,因為我們觸發器裏面num和id都是寫死的,所以不管我們買哪個商品,最終更新的都是商品1的數量。比如:我們往訂單表再插入一條記錄:

insert into o(gid,much) values(2,3);

執行完後會發現商品1的數量變4了,而商品2的數量沒變,這樣顯然不是我們想要的結果。我們需要改改我們之前創建的觸發器。

我們如何在觸發器引用行的值,也就是說我們要得到我們新插入的訂單記錄中的gid或much的值。

對於insert而言,新插入的行用new來表示,行中的每一列的值用new.列名來表示。

所以現在我們可以這樣來改我們的觸發器:

create trigger tg2 afert insert on order_table for each row
begin 
 
 update goods set num = num-new.much  where id = new.gid;

end 

第二個觸發器創建完畢,我們先把第一個觸發器刪掉

1 drop trigger tg1;

再來測試一下,插入一條訂單記錄:

1 insert into order_table(gid,much) values(2,3)

執行完發現商品2的數量變為7了,現在就對了。

現在還存在兩種情況:

1.當用戶撤銷一個訂單的時候,我們這邊直接刪除一個訂單,我們是不是需要把對應的商品數量再加回去呢?

對於delete而言:原本有一行,後來被刪除,想引用被刪除的這一行,用old來表示,old.列名可以引用被刪除的行的值。

那我們的觸發器就該這樣寫:

create trigger tg3 afert delete  on order_table for each row 
bigen 

    update goods set num = num + old.much where id = old.gid;(註意這邊的變化)
end 

2.當用戶修改一個訂單的數量時,我們觸發器修改怎麽寫?

不寫了,自己寫....

4.存儲過程

  MySQL數據庫在5.0版本後開始支持存儲過程,那麽什麽是存儲過程呢?怎麽創建、查看和刪除存儲過程呢?存儲過程有什麽優點?

 1.概念:什麽是存儲過程:類似於函數(方法),簡單的說存儲過程是為了完成某個數據庫中的特定功能而編寫的語句集合,該語句集包括SQL語句(對數據的增刪改查)、條件語句和循環語句等。

 2. 查看現有的存儲過程

1 show procedure status;

 3 .刪除存儲過程

1 drop procedure 存儲過程名稱;

4. 調用 存儲過程

1 call 存儲過程名稱(參數1  參數1類型,參數2  參數2類型);

5.創建存儲過程

1 1#體會封裝
2 create procedure p1 ()
3 begin 
4    select * from account;  
5   
6 end
1 2#SQL 體會參數
2 create procedure p2(in m int)
3 begin 
4   select * from account where money > m;
5 end
 1 #SQL 體會控制
 2 create procedure p3(in x int,in c char(1))
 3 
 4 begin
 5 
 6     if c =‘d‘ then
 7     
 8         select * from account where money >x;
 9  
10    else 
11     
12          select * from account  where money <x;      
13   end if;
14 end

#體會循環:計算1-100累加的和,並且返回計算結果.
create procedure p4(inout n int) begin DECLARE sum int default 0; -- 設置總和變量,並且指定初始值0 declare i int; -- 聲明變量 set i = 0; -- 通過set為變量設置值       while i<=n DO -- 開始循環 set sum = sum +i; set i = i+1; end while; -- 結束循環

      select sum; -- 提供結果 set n = sum;--將計算結果提供給 輸出變量 n; end; -- 調用: set @n = 100; call p4(@n); select @n;

存儲過程優點
1、存儲過程增強了SQL語言靈活性。存儲過程可以使用控制語句編寫,可以完成復雜的判斷和較復雜的運算,有很強的靈活性;
2、減少網絡流量,降低了網絡負載。存儲過程在數據庫服務器端創建成功後,只需要調用該存儲過程即可,而傳統的做法是每次都將大量的SQL語句通過網絡發送至數據庫服務器端然後再執行;
3、存儲過程只在創造時進行編譯,以後每次執行存儲過程都不需再重新編譯,而一般SQL語句每執行一次就編譯一次,所以使用存儲過程可提高數據庫執行速度。
4、系統管理員通過設定某一存儲過程的權限實現對相應的數據的訪問權限的限制,避免了非授權用戶對數據的訪問,保證了數據的安全。

  

 5.函數 

  MySQL提供的內建函數:

View Code

  更多函數: 官方猛擊這裏

1、自定義函數

CREATE FUNCTION fun1(i1 int,i2 int)

RETURNS INT //設置返回類型

BEGIN

    DECLARE sum int default 0;
    set sum = i1+i2;
    RETURN(sum); //返回結果

end 

2.調用自定義函數

#直接調用自定義函數
select fun1(1,5);

#在sql語句中使用自定義函數
select fun1(參數1,參數2),name from 表名

3.刪除自定義函數

drop FUNCTION fun_name;

day40 python MySQL【四】 之 【索引】【視圖】【觸發器】【存儲過程】【函數】