常用資源(不定期更新)
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條件上不要使用運算函式,以免索引失效