MySQL索引&檢視&儲存過程
MySQL索引&檢視&儲存過程
1. MySQL 索引
1.1 什麼是索引
在資料庫表中,對欄位建立索引可以大大提高查詢速度。通過善用這些索引,可以令MySQL的查詢和
執行更加高效。
如果合理的設計且使用索引的MySQL是一輛蘭博基尼的話,那麼沒有設計和使用索引的MySQL就是
一個人力三輪車。拿漢語字典的目錄頁(索引)打比方,我們可以按拼音、筆畫、偏旁部首等排序的目
錄(索引)快速查詢到需要的字
1.2 常見索引分類
MySql將一個表的索引都儲存在同一個索引檔案中, 如果對中資料進行增刪改操作,MySql都會自動的更新索引.
1.2.1 主鍵索引 (PRIMARY KEY)
特點: 主鍵是一種唯一性索引,每個表只能有一個主鍵,用於標識資料表中的某一條記錄。
一個表可以沒有主鍵,但最多隻能有一個主鍵,並且主鍵值不能包含NULL。
1) 建立db4資料庫
CREATE DATABASE db4 CHARACTER SET utf8;
2) 建立 demo01表
CREATE TABLE demo01( did INT, dname VARCHAR(20), hobby VARCHAR(30) );
3) 語法格式
- 建立表的時候直接新增主鍵索引 (最常用)
-
CREATE TABLE 表名( -- 新增主鍵 (主鍵是唯一性索引,不能為null,不能重複,)
-
- 修改表結構 新增主鍵索引
-
ALTER TABLE 表名 ADD PRIMARY KEY ( 列名 )
-
4) 為demo1 表新增主鍵索引
ALTER TABLE demo01 ADD PRIMARY KEY (did);
1.2.2 唯一索引(UNIQUE)
特點: 索引列的所有值都只能出現一次, 必須唯一.
唯一索引可以保證資料記錄的唯一性。事實上,在許多場合,人們建立唯一索引的目的往往不是為了
提高訪問速度,而只是為了避免資料出現重複。
1) 語法格式
- 建立表的時候直接新增主鍵索引
-
CREATE TABLE
-
- 使用create語句建立: 在已有的表上建立索引
-
create unique index 索引名 on 表名(列名(長度))
-
- 修改表結構新增索引
-
ALTER TABLE 表名 ADD UNIQUE ( 列名 )
-
2) 為 hobby欄位新增唯一索引
create unique index ind_hobby on demo01(hobby)
3) 向表中插入資料
INSERT INTO demo01 VALUES(1,'張三','DBJ'); # 報錯Duplicate entry 'DBJ' for key 'hobby' # 唯一索引保證了資料的唯一性,索引的效率也提升了 INSERT INTO demo01 VALUES(2,'李四','DBJ');
1.2.3 普通索引 (INDEX)
普通索引(由關鍵字KEY或INDEX定義的索引)的唯一任務是加快對資料的訪問速度。因此,應該只
為那些最經常出現在查詢條件(WHERE column=)或排序條件(ORDERBY column)中的資料列建立索引。
1) 語法格式
使用create index 語句建立: 在已有的表上建立索引
create index 索引名 on 表名(列名[長度])
修改表結構新增索引
ALTER TABLE 表名 ADD INDEX 索引名 (列名)
2) 給 dname欄位新增索引
# 給dname欄位新增索引 alter table demo01 add index dname_indx(dname);
1.2.4 刪除索引
- 由於索引會佔用一定的磁碟空間,因此,為了避免影響資料庫的效能,應該及時刪除不再使用的索引
1) 語法格式
ALTER TABLE table_name DROP INDEX index_name;
2) 刪除 demo01 表中名為 dname_indx 的普通索引。
ALTER TABLE demo01 DROP INDEX dname_indx;
1.3 索引效能測試
1.3.1 匯入資料表
1) 選中 db4資料庫 右鍵 匯入SQL指令碼
2) 找到軟體資料夾下的 測試索引.sql檔案, 點選執行
3) 查詢 test_index 表中的總記錄數
SELECT COUNT(*) FROM test_index;
表中有 500萬條資料
1.3.2 測試
1) 在沒有新增索引的情況下, 使用 dname 欄位進行查詢
#未新增索引,進行分組查詢 SELECT * FROM test_index GROUP BY dname;
2) 耗時
3) 為 dname欄位 新增索引
#新增索引 ALTER TABLE test_index ADD INDEX dname_indx(dname);
- 注意: 一般我們都是在建立表的時候 就確定需要新增索引的欄位
4) 執行分組查詢
SELECT * FROM test_index GROUP BY dname;
1.4 索引的優缺點總結
新增索引首先應考慮在 where 及 order by 涉及的列上建立索引。
- 索引的優點
- 1. 大大的提高查詢速度
- 2. 可以顯著的減少查詢中分組和排序的時間。
- 索引的缺點
- 1. 建立索引和維護索引需要時間,而且資料量越大時間越長
- 2. 當對錶中的資料進行增加,修改,刪除的時候,索引也要同時進行維護,降低了資料的維護速度
2. MySQL 檢視
2.1 什麼是檢視
- 1. 檢視是一種虛擬表。
- 2. 檢視建立在已有表的基礎上, 檢視賴以建立的這些表稱為基表。
- 3. 向檢視提供資料內容的語句為 SELECT 語句, 可以將檢視理解為儲存起來的 SELECT 語句.
- 4. 檢視向用戶提供基表資料的另一種表現形式
2.2 檢視的作用
- 許可權控制時可以使用
- 比如,某幾個列可以執行使用者查詢,其他列不允許,可以開通檢視 查詢特定的列, 起到許可權控制的作用
- 簡化複雜的多表查詢
- 檢視 本身就是一條查詢SQL,我們可以將一次複雜的查詢 構建成一張檢視, 使用者只要查詢檢視就可以獲取想要得到的資訊(不需要再編寫複雜的SQL)
- 檢視主要就是為了簡化多表的查詢
2.3 檢視的使用
2.3.1 建立檢視
1) 語法格式
create view 檢視名 [column_list] as select語句; view: 表示檢視 column_list: 可選引數,表示屬性清單,指定檢視中各個屬性的名稱,預設情況下,與SELECT語句中查詢 的屬性相同 as : 表示檢視要執行的操作 select語句: 向檢視提供資料內容
2) 建立一張檢視
#1. 先編寫查詢語句 #查詢所有商品 和 商品的對應分類資訊 SELECT * FROM products p LEFT JOIN category c ON p.`category_id` = c.`cid`; #2.基於上面的查詢語句,建立一張檢視 CREATE VIEW products_category_view AS SELECT * FROM products p LEFT JOIN category c ON p.`category_id` = c.`cid`;
3) 查詢檢視 ,當做一張只讀的表操作就可以
SELECT * FROM products_category_view;
2.3.2 通過檢視進行查詢
1) 需求: 查詢各個分類下的商品平均價格
#通過 多表查詢 SELECT cname AS '分類名稱', AVG(p.`price`) AS '平均價格' FROM products p LEFT JOIN category c ON p.`category_id` = c.`cid` GROUP BY c.`cname`; # 通過檢視查詢 可以省略連表的操作 SELECT cname AS '分類名稱', AVG(price) AS '平均價格' FROM products_category_view GROUP BY cname;
2) 需求: 查詢鞋服分類下最貴的商品的全部資訊
#通過連表查詢 #1.先求出鞋服分類下的最高商品價格 SELECT MAX(price) AS maxPrice FROM products p LEFT JOIN category c ON p.`category_id` = c.`cid` WHERE c.`cname` = '鞋服' #2.將上面的查詢 作為條件使用 SELECT * FROM products p LEFT JOIN category c ON p.`category_id` = c.`cid` WHERE c.`cname` = '鞋服' AND p.`price` = (SELECT MAX(price) AS maxPrice FROM products p LEFT JOIN category c ON p.`category_id` = c.`cid` WHERE c.`cname` = '鞋服');
#通過檢視查詢 SELECT * FROM products_category_view pcv WHERE pcv.`cname` = '鞋服' AND pcv.`price` = (SELECT MAX(price) FROM products_category_view WHERE cname = '鞋服')
2.4 檢視與表的區別
- 檢視是建立在表的基礎上,表儲存資料庫中的資料,而檢視只是做一個數據的展示
- 通過檢視不能改變表中資料(一般情況下檢視中的資料都是表中的列 經過計算得到的結果,不允許更新)
- 刪除檢視,表不受影響,而刪除表,檢視不再起作用
3. MySQL 儲存過程(瞭解)
3.1 什麼是儲存過程
- MySQL 5.0 版本開始支援儲存過程。
- 儲存過程(Stored Procedure)是一種在資料庫中儲存複雜程式,以便外部程式呼叫的一種資料庫物件。儲存過程是為了完成特定功能的SQL語句集,經編譯建立並儲存在資料庫中,使用者可通過指定儲存過程的名字並給定引數(需要時)來呼叫執行。
- 簡單理解: 儲存過程其實就是一堆 SQL 語句的合併。中間加入了一些邏輯控制。
3.2 儲存過程的優缺點
- 優點:
- 儲存過程一旦除錯完成後,就可以穩定執行,(前提是,業務需求要相對穩定,沒有變化)
- 儲存過程減少業務系統與資料庫的互動,降低耦合,資料庫互動更加快捷(應用伺服器,與資料庫伺服器不在同一個地區)
- 缺點:
- 在網際網路行業中,大量使用MySQL,MySQL的儲存過程與Oracle的相比較弱,所以較少使用,並且網際網路行業需求變化較快也是原因之一
- 儘量在簡單的邏輯中使用,儲存過程移植十分困難,資料庫叢集環境,保證各個庫之間儲存過程變更一致也十分困難。
- 阿里的程式碼規範裡也提出了禁止使用儲存過程,儲存過程維護起來的確麻煩;
3.3 儲存過程的建立方式
3.3.1 方式1
1) 資料準備
建立商品表 與 訂單表
# 商品表 CREATE TABLE goods( gid INT, NAME VARCHAR(20), num INT -- 庫存 ); #訂單表 CREATE TABLE orders( oid INT, gid INT, price INT -- 訂單價格 ); # 向商品表中新增3條資料 INSERT INTO goods VALUES(1,'奶茶',20); INSERT INTO goods VALUES(2,'綠茶',100); INSERT INTO goods VALUES(3,'花茶',25);
2) 建立簡單的儲存過程
語法格式
DELIMITER $$ -- 宣告語句結束符,可以自定義 一般使用$$ CREATE PROCEDURE 過程名稱() -- 宣告儲存過程 BEGIN -- 開始編寫儲存過程 -- 要執行的操作 END $$ -- 儲存過程結束
需求: 編寫儲存過程, 查詢所有商品資料
DELIMITER $$ CREATE PROCEDURE goods_proc() BEGIN select * from goods; END $$
3) 呼叫儲存過程
語法格式
call 儲存過程名
-- 呼叫儲存過程 查詢goods表所有資料 call goods_proc;
3.3.2 方式2
1) IN 輸入引數:表示呼叫者向儲存過程傳入值
CREATE PROCEDURE 儲存過程名稱(IN 引數名 引數型別)
2) 建立接收引數的儲存過程
需求: 接收一個商品id, 根據id刪除資料
DELIMITER $$ CREATE PROCEDURE goods_proc02(IN goods_id INT) BEGIN DELETE FROM goods WHERE gid = goods_id ; END $$
3) 呼叫儲存過程 傳遞引數
# 刪除 id為2的商品 CALL goods_proc02(2);
3.3.3 方式3
1) 變數賦值
SET @變數名=值
2) OUT 輸出引數:表示儲存過程向呼叫者傳出值
OUT 變數名 資料型別
3) 建立儲存過程
需求: 向訂單表 插入一條資料, 返回1,表示插入成功
# 建立儲存過程 接收引數插入資料, 並返回受影響的行數 DELIMITER $$ CREATE PROCEDURE orders_proc(IN o_oid INT , IN o_gid INT ,IN o_price INT, OUT out_num INT) BEGIN -- 執行插入操作 INSERT INTO orders VALUES(o_oid,o_gid,o_price); -- 設定 num的值為 1 SET @out_num = 1; -- 返回 out_num的值 SELECT @out_num; END $$
4) 呼叫儲存過程
# 呼叫儲存過程插入資料,獲取返回值 CALL orders_proc(1,2,30,@out_num);
4. MySQL觸發器(瞭解)
4.1 什麼是觸發器
觸發器(trigger)是MySQL提供給程式設計師和資料分析員來保證資料完整性的一種方法,它是與表事
件相關的特殊的儲存過程,它的執行不是由程式呼叫,也不是手工啟動,而是由事件來觸發,比如當對
一個表進行操作(insert,delete, update)時就會啟用它執行。——百度百科
簡單理解: 當我們執行一條sql語句的時候,這條sql語句的執行會自動去觸發執行其他的sql語句。
4.2 觸發器建立的四個要素
- 1. 監視地點(table)
- 2. 監視事件(insert/update/delete)
- 3. 觸發時間(before/after)
- 4. 觸發事件(insert/update/delete)
4.3 建立觸發器
1) 語法格式
delimiter $ -- 將Mysql的結束符號從 ; 改為 $,避免執行出現錯誤 CREATE TRIGGER Trigger_Name -- 觸發器名,在一個數據庫中觸發器名是唯一的 before/after(insert/update/delete) -- 觸發的時機 和 監視的事件 on table_Name -- 觸發器所在的表 for each row -- 固定寫法 叫做行觸發器, 每一行受影響,觸發事件都執行 begin -- begin和end之間寫觸發事件 end $ -- 結束標記
2) 向商品中新增一條資料
# 向商品中新增一條資料 INSERT INTO goods VALUES(1,'book',40);
3) 需求: 在下訂單的時候,對應的商品的庫存量要相應的減少,賣出商品之後減少庫存量。
編寫觸發器
-- 1.修改結束標識 DELIMITER $ -- 2.建立觸發器 CREATE TRIGGER t1 -- 3.指定觸發的時機,和要監聽的表 AFTER INSERT ON orders -- 4.行觸發器 固定寫法 FOR EACH ROW -- 4.觸發後具體要執行的事件 BEGIN -- 訂單+1 庫存-1 UPDATE goods SET num = num -1 WHERE gid = 1; END$
4) 查詢 goods表中的資料
5) 向訂單表中新增一條資料
INSERT INTO orders VALUES(1,1,25);
6) goods表中的資料隨之 -1
5. DCL(資料控制語言)
MySql預設使用的都是 root 使用者,超級管理員,擁有全部的許可權。除了root使用者以外,我們還可以通
過DCL語言來定義一些許可權較小的使用者, 分配不同的許可權來管理和維護資料庫。
5.1 建立使用者
語法格式
CREATE USER '使用者名稱'@'主機名' IDENTIFIED BY '密碼';
1) 建立 admin1 使用者,只能在 localhost 這個伺服器登入 mysql 伺服器,密碼為 123456
CREATE USER 'admin1'@'localhost' IDENTIFIED BY '123456';
- 建立的使用者在名字為 mysql的 資料庫中的 user表中
2) 建立 admin2 使用者可以在任何電腦上登入 mysql 伺服器,密碼為 123456
CREATE USER 'admin2'@'%' IDENTIFIED BY '123456';
- % 表示 使用者可以在任意電腦登入 mysql伺服器.
5.2 使用者授權
建立好的使用者,需要進行授權
語法格式
GRANT 許可權 1, 許可權 2... ON 資料庫名.表名 TO '使用者名稱'@'主機名';
1) 給 admin1 使用者分配對 db4 資料庫中 products 表的 操作許可權:查詢
GRANT SELECT ON db4.products TO 'admin1'@'localhost';
2) 給 admin2 使用者分配所有許可權,對所有資料庫的所有表
GRANT ALL ON *.* TO 'admin2'@'%';
3) 使用admin1使用者登入資料庫 測試許可權
4) 發現數據庫列表中 只有db4, 表只有 products.
5) 執行查詢操作
-- 查詢account表 SELECT * FROM products;
6) 執行插入操作,發現不允許執行,沒有許可權
-- 向 products 表中插入資料 -- 不允許執行 INSERT INTO products VALUES('p010','小鳥伏特加',1000,1,NULL);
5.3 檢視許可權
語法格式
SHOW GRANTS FOR '使用者名稱'@'主機名';
1) 檢視root使用者許可權
-- 檢視root使用者的許可權 SHOW GRANTS FOR 'root'@'localhost';
- GRANT ALL PRIVILEGES 是表示所有許可權
5.4 刪除使用者
語法格式
DROP USER '使用者名稱'@'主機名';
1) 刪除 admin1 使用者
-- 刪除 admin1 使用者 DROP USER 'admin1'@'localhost';
5.5 查詢使用者
選擇名為 mysql的資料庫, 直接查詢 user表即可
-- 查詢使用者 SELECT * FROM USER;
6. 資料庫備份&還原
備份的應用場景 在伺服器進行資料傳輸、資料儲存和資料交換,就有可能產生資料故障。比如發生
意外停機或儲存介質損壞。 這時,如果沒有采取資料備份和資料恢復手段與措施,就會導致資料的丟
失,造成的損失是無法彌補與估量的。
6.1 SQLYog 資料備份
1) 選中要備份的資料庫,右鍵 備份匯出 ---->選擇 備份資料庫
2) 指定檔案位置,選擇匯出即可
6.2 SQLYog 資料恢復
1) 先刪除 db2 資料庫
DROP DATABASE db2;
2) 匯入 之前備份的 SQL 檔案
6.3 命令列備份
進入到Mysql安裝目錄的 bin目錄下, 開啟DOS命令列.
1) 語法格式
mysqldump -u 使用者名稱 -p 密碼 資料庫 > 檔案路徑
2) 執行備份, 備份db2中的資料 到 H盤的 db2.sql 檔案中
mysqldump -uroot -p123456 db2 > H:/db2.sql
6.4 命令列恢復
1) 先刪除 db2 資料庫
2) 恢復資料 還原 db2 資料庫中的資料
- 注意:還原的時候需要先建立一個 db2資料庫
source sql檔案地址