高階特性——mysql必知必會(三)
阿新 • • 發佈:2018-12-25
檢視
- 作用:
- 重用 sql語句。
- 簡化複雜的sql。
- 保護資料,給予使用者部分資料的訪問許可權而不是整個表。
- 更改資料的格式和表示。
- 檢視不包含資料,是虛擬的表。每次使用檢視時,必須處理查詢的所有檢索,所以複雜檢視和巢狀檢視會大大降低效能。
- 檢視不能索引,也不能有關聯的觸發器。
- 檢視通常用於查詢,而不用於行的增刪。
使用
- 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;
儲存過程
- 作用:
- 封裝操作。簡化使用操作,減少錯誤,減少基礎資料的訪問從而提高安全性。
- 提高效能。儲存過程比單獨使用sql要快。
- 進行較複雜的邏輯操作。
使用
- 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 建立遊標, OPEN、CLOSE 開啟關閉遊標。
- FETCH 遊標訪問結果集的每一行。
- CONTINUE HANDLER 表示在條件出現時執行程式碼,SQLSTATE ‘02000’ 是未找到條件,即沒有更多行可以訪問。
- REPEAT 和UNTIL 為迴圈語句。
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;
觸發器
- 針對關聯的表, 在DELETE 、INSERT 、UPDATE 之前或者之後執行操作。是一種特殊的儲存過程。
- 只有表支援觸發器,檢視不支援。
使用
- 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
。
- 整個伺服器。
- 許可權的型別。