1. 程式人生 > 其它 >MySQL索引&檢視&儲存過程

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,不能重複,)
        欄位名 型別 PRIMARY KEY, );
  • 修改表結構 新增主鍵索引
    • ALTER TABLE 表名 ADD PRIMARY KEY ( 列名 )

4) 為demo1 表新增主鍵索引

ALTER TABLE demo01 ADD PRIMARY KEY (did);

1.2.2 唯一索引(UNIQUE)

  特點: 索引列的所有值都只能出現一次, 必須唯一.

  唯一索引可以保證資料記錄的唯一性。事實上,在許多場合,人們建立唯一索引的目的往往不是為了
提高訪問速度,而只是為了避免資料出現重複。

1) 語法格式

  • 建立表的時候直接新增主鍵索引
    • CREATE TABLE
      表名( 列名 型別(長度), -- 新增唯一索引 UNIQUE [索引名稱] (列名) );
  • 使用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檔案地址