1. 程式人生 > 實用技巧 >常用資源(不定期更新)

常用資源(不定期更新)

1.檢視

概述:檢視就相當於一個臨時表,但是隻定義了對應關係,用這個檢視的時候,就會自行執行視圖裡定義好的sql語句,檢視是隻能去查原表的資料,不能去修改原表裡面的資料的;

檢視的增刪改查:

1.建立檢視:

語法:CREATE VIEW 檢視名稱 AS SQL語句

示例:

CREATE VIEW v1 AS 
SELECT nid, name FROM user
WHERE nid > 3;

2.刪除檢視:

語法:DROP 檢視名稱

3.修改檢視

語法:ALTER VIEW 檢視名稱 AS sQL語句

示例:

ALTER VIEW v1 AS 
SELECT sex, birthday FROM user
WHERE nid > 1

4.使用檢視:

示例:

select nid, name from v1;

2.觸發器

概述:對某個表進行【增/刪/改】操作的前後如果希望觸發某個特定的行為時,可以使用觸發器,觸發器用於定製使用者對錶的行進行【增/刪/改】前後的行為。

觸發器的建立

# 插入前
CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
BEGIN
    ...
END

# 插入後
CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
BEGIN
    ...
END

# 刪除前
CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW
BEGIN
    ...
END

# 刪除後
CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW
BEGIN
    ...
END

# 更新前
CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW
BEGIN
    ...
END

# 更新後
CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW
BEGIN
    ...
END

示例1:

delimiter //
CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
BEGIN

IF NEW. NAME == 'alex' THEN
    INSERT INTO tb2 (NAME)
VALUES
    ('aa')
END
END//
delimiter ;

示例2:

delimiter //
CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
BEGIN

IF NEW. NAME == 'alex' THEN
    INSERT INTO tb2 (NAME)
VALUES
    ('aa')
END
END//
delimiter ;

注意:delimiter // 把預設以“;”作為結束符改為了以//作為結束符,NEW表示即將插入的資料行,OLD表示即將被刪除的資料行

觸發器的刪除

語法:DROP TRIGGER 觸發器的名稱;

使用觸發器

觸發器無法由使用者直接呼叫,而知由於對錶的【增/刪/改】操作被動引發的

3.儲存過程

概述:儲存過程是一個SQL語句集合,當主動去呼叫儲存過程時,其中內部的SQL語句會按照邏輯執行

建立儲存過程

1.無引數的儲存過程

示例:

-- 建立儲存過程

delimiter //
create procedure p1()
BEGIN
    select * from t1;
END//
delimiter ;



-- 執行儲存過程

call p1()

2.有引數的儲存過程

對於儲存過程,可以接收三類引數:

  • in:僅用於傳入引數用
  • out:僅用於返回值用
  • inout:既可以傳入又可以當作返回值

建立有引數的儲存過程示例:

-- 建立儲存過程
delimiter \\
create procedure p1(
    in i1 int,
    in i2 int,
    inout i3 int,
    out r1 int
)
BEGIN
    DECLARE temp1 int;
    DECLARE temp2 int default 0;
    
    set temp1 = 1;

    set r1 = i1 + i2 + temp1 + temp2;
    
    set i3 = i3 + 100;

end\\
delimiter ;

-- 執行儲存過程
set @t1 =4;
set @t2 = 0;
CALL p1 (1, 2 ,@t1, @t2);
SELECT @t1,@t2;

事務型儲存過程示例:

delimiter \\
    create PROCEDURE p1(
        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; 
        DELETE from tb1;
        insert into tb2(name)values('seven');
      COMMIT; 
     
      -- SUCCESS 
      set p_return_code = 0; 
     
      END\\
delimiter ;

刪除儲存過程

drop procedure 儲存過程名稱

4.函式

MySQL中的內建函式

  • INSTR(str, len):返回字串str從開始的len位置的子序列字元
  • LEFT(str, len):返回字串str從開始的len位置的子序列字元
  • LOWER(str):變小寫
  • UPPER(str):變大寫
  • ...

自定義函式

1.定義一個函式:

delimiter \\
create function f1(
    i1 int,
    i2 int)
returns int
BEGIN
    declare num int;
    set num = i1 + i2;
    return(num);
END \\
delimiter ;

-- 執行函式:
f1(1, 3);

2.刪除函式:

drop function 函式名稱

5.事務

概述:事務用於將某些操作的多個SQL作為原子性操作,一旦有某一個出現錯誤,即可回滾到原來的狀態,從而保證資料庫資料完整性

6.索引

概述:索引是資料庫中專門用於幫助使用者快速查詢資料的一種資料結構,類似於字典中的目錄,查詢字典內容時可以根據目錄查詢找到資料的存放位置,然後直接獲取即可

MySQL中常見索引有:

1.普通索引:僅有一個功能,那就是加快查詢

  • create index 索引名 ob 表名(列名)

2.唯一索引:加速查詢和唯一約束(可為null)

  • create unique index 索引名 on 表名(列名)

3.主鍵索引:加速查詢和唯一約束(不可為null)

  • alter table 表名 add primary key(列名);

4.聯合索引:將n個列組合成一個索引

  • create index 索引名 on 表名(列名1,列名2。。。);

聯合索引需要注意的點:

  • 聯合索引的最左匹配原則,即最左優先,以最左邊的為起點任何連續的索引都能匹配上。同時遇到範圍查詢(>、<、between、like)就會停止匹配。
  • 多欄位的聯合索引在查詢單個欄位時是否可以用到索引:如下面的聯合索引的語法所示,如果你查詢單個欄位時,查詢的是列名1和列名2或者查詢列名1的話,就能命中索引,如果只查詢列名2就中不了索引

索引相關命令

查看錶結構:

desc 表名

檢視生成表的sql

show create table 表名

檢視執行時間:

set profilling = 1;
SQL語句...
show profiles

檢視執行計劃:

explain select * from tb2;

執行計劃裡面type屬性的值代表的意思

type
查詢時的訪問方式,效能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
ALL 全表掃描,對於資料表從頭到尾找一遍
select * from tb1;
特別的:如果有limit限制,則找到之後就不在繼續向下掃描
select * from tb1 where email = '[email protected]'
select * from tb1 where email = '[email protected]' limit 1;
雖然上述兩個語句都會進行全表掃描,第二句使用了limit,則找到一個後就不再繼續掃描。

INDEX           全索引掃描,對索引從頭到尾找一遍
                select nid from tb1;

RANGE          對索引列進行範圍查詢
                select *  from tb1 where name < 'alex';
                PS:
                    between and
                    in
                    >   >=  <   <=  操作
                    注意:!= 和 > 符號


INDEX_MERGE     合併索引,使用多個單列索引搜尋
                select *  from tb1 where name = 'alex' or nid in (11,22,33);

REF             根據索引查詢一個或多個值
                select *  from tb1 where name = 'seven';

EQ_REF          連線時使用primary key 或 unique型別
                select tb2.nid,tb1.name from tb2 left join tb1 on tb2.nid = tb1.nid;



CONST           常量
                表最多有一個匹配行,因為僅有一行,在這行的列值可被優化器剩餘部分認為是常數,const表很快,因為它們只讀取一次。
                select nid from tb1 where nid = 2 ;

SYSTEM          系統
                表僅有一行(=系統表)。這是const聯接型別的一個特例。
                select * from (select nid from tb1 where nid = 1) as A;

7.動態執行sql語句

示例:

delimiter \\
DROP PROCEDURE IF EXISTS proc_sql \\
CREATE PROCEDURE proc_sql ()
BEGIN
    declare p1 int;
    set p1 = 11;
    set @p1 = p1;

    PREPARE prod FROM 'select * from tb2 where nid > ?';
    EXECUTE prod USING @p1;
    DEALLOCATE prepare prod; 

END\\
delimiter ;

8.如何優化SQL語句

  • 列型別儘量定義成數值型別,且長度儘可能短,如主鍵和外來鍵,型別欄位等等

  • 建立單列索引

  • 根據需要建立多列聯合索引

當單個列過濾之後還有很多資料,那麼索引的效率將會比較低,即列的區分度較低,那麼如果在多個列上建立索引,那麼多個列的區分度就大多了,將會有顯著的效率提高。

  • 根據業務場景建立覆蓋索引

只查詢業務需要的欄位,如果這些欄位被索引覆蓋,將極大的提高查詢效率

  • 多表連線的欄位上需要建立索引這樣可以極大的提高表連線的效率

  • where條件欄位上需要建立索引

  • 排序欄位上需要建立索引

  • 分組欄位上需要建立索引

  • where條件上不要使用運算函式,以免索引失效