1. 程式人生 > >高階特性——mysql必知必會(三)

高階特性——mysql必知必會(三)

檢視

  • 作用:
    1. 重用 sql語句。
    2. 簡化複雜的sql。
    3. 保護資料,給予使用者部分資料的訪問許可權而不是整個表。
    4. 更改資料的格式和表示
  • 檢視不包含資料,是虛擬的表。每次使用檢視時,必須處理查詢的所有檢索,所以複雜檢視和巢狀檢視會大大降低效能。
  • 檢視不能索引,也不能有關聯的觸發器。
  • 檢視通常用於查詢,而不用於行的增刪。

使用

  • CREATE VIEW 建立檢視。DROP VIEW 刪除檢視。
  • CREATE OR REPLACE VIEW 更新檢視。
  • 簡化複雜聯結,可以重用
CREATE VIEW productcustomers AS
SELECT cust_name, cust_contact, prod_id
FROM customers, orders, orderitems
WHERE customers.cust_id = orders.cust_id AND orders.order_num = orderitems.order_num;

SELECT cust_name, cust_contact
FROM productcustomers
WHERE prod_id = 'TNT2';
  • 格式化資料。
CREATE VIEW
vendorlocation AS SELECT CONCAT(RTRIM(vend_name), ' (', RTRIM(vend_country), ')') AS vend_title FROM vendors ORDER BY vend_name;
SELECT vend_title FROM vendorlocation;
  • 過濾不需要的資料。
CREATE VIEW customeremaillist AS
SELECT cust_id, cust_name, cust_email
FROM customers
WHERE cust_email IS NOT NULL
;
SELECT cust_id, cust_name, cust_email FROM customeremaillist;
  • 使用計算欄位處理資料。
CREATE VIEW orderitemsexpanded AS
SELECT order_num, prod_id, quantity, item_price, quantity*item_price AS expanded_price
FROM orderitems;

SELECT order_num, expanded_price FROM orderitemsexpanded;

索引

  • 使用索引可以更快的查詢資料,但是更新一個包含索引的表需要更多時間,因為索引也需要更新。

使用

  • CREATE INDEX 允許使用重複的值。
    CREATE UNIQUE INDEX 兩行不能有相同的索引值。
  • DESC 可以使用在列名後降序索引某列。
CREATE UNIQUE INDEX orderindex
ON orders(order_num DESC, order_date);
SELECT * FROM salaries FORCE INDEX(idx_emp_no)
WHERE emp_no = 10005;
  • 刪除索引。
ALTER TABLE orders DROP INDEX orderindex;

儲存過程

  • 作用:
    1. 封裝操作簡化使用操作,減少錯誤,減少基礎資料的訪問從而提高安全性。
    2. 提高效能。儲存過程比單獨使用sql要快。
    3. 進行較複雜的邏輯操作。

使用

  • CALL 呼叫儲存過程,可以將儲存過程理解為一個函式。
  • mysql變數名以@開始。
  • IN 表示傳入引數, OUT 表示傳出引數。INOUT 表示傳入傳出引數。
  • INTO 表示將值賦予某個變數。
  • DECLARE 宣告變數。
  • COMMENT 對儲存過程說明。
  • IF THEN 進行邏輯操作。
CREATE PROCEDURE ordertotal2(
    IN onumber INT,
    IN taxable boolean,
    OUT ototal DECIMAL(8,2)
) COMMENT 'obtain orer total with tax'
BEGIN
    -- var
    DECLARE total DECIMAL(8,2);
    DECLARE taxrate INT DEFAULT 6;

    SELECT SUM(item_price*quantity) FROM orderitems
    WHERE order_num = onumber
    INTO total;

    IF taxable THEN
        SELECT total*(1+taxrate/100) INTO total;
    END IF;

    SELECT total INTO ototal;
END;

CALL ordertotal2(20005, 0, @total);
SELECT @total;
  • 刪除儲存過程。
DROP PROCEDURE IF EXISTS ordertotal2;
  • 顯示創造儲存過程的語句。
SHOW CREATE PROCEDURE ordertotal;
  • 顯示儲存過程狀態。
SHOW PROCEDURE STATUS LIKE 'ordertotal%';

遊標

  • 對檢索出來的結果集的進行操縱,如下一行、前10行。
  • 遊標只能用於儲存過程

使用

  • DECLARE 建立遊標, OPENCLOSE 開啟關閉遊標。
  • FETCH 遊標訪問結果集的每一行。
  • CONTINUE HANDLER 表示在條件出現時執行程式碼,SQLSTATE ‘02000’ 是未找到條件,即沒有更多行可以訪問。
  • REPEATUNTIL 為迴圈語句。
CREATE PROCEDURE processorders()
BEGIN
    DECLARE done boolean DEFAULT 0 ;
    DECLARE o INT;
    DECLARE t DECIMAL(8,2);

    DECLARE ordernumbers CURSOR
    FOR
    SELECT order_num FROM orders;

    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000'  SET done = 1;

    CREATE TABLE IF NOT EXISTS ordertotals
    (order_num INT, total DECIMAL(8,2));

    OPEN ordernumbers;
    REPEAT
        FETCH ordernumbers INTO o;
        CALL ordertotal2(o, 1, t);
        INSERT INTO ordertotals(order_num, total) VALUES(o, t);
    UNTIL done END REPEAT;
    CLOSE ordernumbers;
END;

CALL processorders;

觸發器

  • 針對關聯的表, 在DELETEINSERTUPDATE 之前或者之後執行操作。是一種特殊的儲存過程
  • 只有支援觸發器,檢視不支援。

使用

  • CREATE TRIGGER 建立觸發器。
  • NEW 訪問操作之後的虛擬表
    OLD 訪問操作之前的虛擬表。
  • 可以使用BEGIN END 執行多條語句。
CREATE TRIGGER neworder AFTER INSERT ON orders
FOR EACH ROW 
SELECT NEW.order_num INTO @t;

CREATE TRIGGER deleteorder BEFORE DELETE ON orders
FOR EACH ROW
BEGIN
    INSERT INTO archive_orders(order_num, order_date, cust_id)
    VALUES(OLD.order_num, OLD.order_date, OLD.cust_id);
END;

CREATE TRIGGER updatevendor BEFORE UPDATE ON vendors
FOR EACH ROW
SET NEW.vend_state = UPPER(NEW.vend_state);
  • 刪除觸發器。
DROP TRIGGER updatevendor;

事務處理

  • 事務處理可以用來維護資料庫的完整性,保證成批的sql操作要麼完全執行,要麼完全不執行
  • START TRANSACTION 標識事務的開始
  • ROLLBACK 用於撤銷sql語句,但是不能撤銷CREATE,DROP,SELECT 操作。
START TRANSACTION;
DELETE FROM ordertotals;
ROLLBACK;
  • 一般sql語句隱含提交(implicit commit),即自動提交。但是事務處理中,不會隱含提交,需要使用COMMIT 。COMMIT或者ROLLBACK之後,事務會自動關閉,將來更改會隱含提交。
START TRANSACTION;
DELETE FROM orderitems WHERE order_num = 20010;
DELETE FROM orders WHERE order_num = 20010;
COMMIT;
  • SAVEPOINT 可以實現部分回退功能。
    保留點在事務處理完成之後自動釋放,也可以使用RELEASE SAVEPOINT 明確釋放保留點。
SAVEPOINT delete1;
ROLLBACK TO delete1;
  • autocommit標識是否提交更改,針對每個連線而不是伺服器。
    SET autocommit = 0 設為不自動提交更改。SET autocommit = 1 設為自動提交更改。

字符集和校對

  • 字符集:字母和符號的集合。
    編碼:字符集成員的內部表示。
    校對:規定字元如何比較。
  • 一個字符集可以有不止一種校對,有些校對區分大小寫(_cs結尾區分大小寫,_ci結尾不區分大小寫)。
  • 通過CHARACTER SET 指定字符集,COLLATE 指定校對。
    如果不指定,則使用資料庫的預設值
    也可以為每個列設定字符集和校對。
CREATE TABLE mytable
(
    col1 INT,
    col2 VARCHAR(10),
    col3 VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_general_ci,
    PRIMARY KEY (col1)
)
CHARACTER SET hebrew
COLLATE hebrew_general_ci;
  • 可以在SELECT中臨時指定校對,區分大小寫,從而影響最終排序。
SELECT * FROM mytable
ORDER BY col3
COLLATE latin1_general_cs;

安全管理

  • 使用者應該對他們所需要的資料具有適當的許可權,既不能多也不能少。
  • 訪問控制有助於防止無意的錯誤。儘量不要使用root。

設定賬戶

  • 查詢賬號列表。賬號資訊儲存在mysql資料庫的user表中。賬號為[email protected],host可以為%,表示不限制登入主機。
USE mysql;
SELECT user FROM user;
  • CREATE 建立賬號, IDENTIFIED BY PASSWORD 給出口令。
CREATE USER aaa IDENTIFIED BY 'aaa';
  • 重新命名賬號。
RENAME USER aaa TO bbb;
  • 刪除賬號。
DROP USER bbb;
  • 修改密碼。FOR省略,則更新當前登入使用者的口令。
SET PASSWORD FOR aaa = PASSWORD('bbb');
SET PASSWORD = PASSWORD('bbb);

設定賬戶許可權

  • 設定訪問許可權。GRANT 賦予許可權,REVOKE 取消許可權。
GRANT SELECT,INSERT ON mysql_crash_course.* TO aaa;

REVOKE INSERT ON mysql_crash_course.* FROM aaa;
  • 許可權的範圍,ON之後。
    • 整個伺服器。 ON *.*
    • 整個資料庫。 ON database.*
    • 特定的表。 ON database.table
    • 特定的列。GRANT SELECT(col1, col2) ON database.table
    • 特定的儲存過程。GRANT EXECUTE ON PROCEDURE database.procedureName
  • 許可權的型別。

效能分析

EXPLAIN