MySQL 5.0+ 引入視圖與存儲過程,為資料庫層面的邏輯封裝、查詢簡化、安全控制提供了強大工具。善用這兩大特性,能顯著降低應用層複雜度,提升系統可維護性與安全性。
-- 建立視圖:學生成績與課程名稱關聯
CREATE VIEW `v_student_grade` AS
SELECT g.`student_id`, g.`score`, c.`course_name`
FROM `grade` g
JOIN `course` c ON g.`course_id` = c.`course_id`;
-- 應用層極簡查詢
SELECT `student_id`, `score`, `course_name`
FROM `v_student_grade`
WHERE `student_id` = 200410001;
無需在每個模組重寫 JOIN 與 WHERE 條件,修改業務邏輯只需調整視圖定義。
ALGORITHM = MERGE(預設,效能最佳)vs TEMPTABLE(含聚合/DISTINCT等無法合併時)。CALL proc_name(params)。DELIMITER //
CREATE PROCEDURE `sp_transfer_account`(
IN p_from_account INT,
IN p_to_account INT,
IN p_amount DECIMAL(10,2),
OUT p_result VARCHAR(50)
)
BEGIN
DECLARE v_balance DECIMAL(10,2);
START TRANSACTION;
SELECT `balance` INTO v_balance FROM `account` WHERE `id` = p_from_account FOR UPDATE;
IF v_balance >= p_amount THEN
UPDATE `account` SET `balance` = `balance` - p_amount WHERE `id` = p_from_account;
UPDATE `account` SET `balance` = `balance` + p_amount WHERE `id` = p_to_account;
INSERT INTO `transfer_log`(`from_id`,`to_id`,`amount`,`create_time`)
VALUES (p_from_account, p_to_account, p_amount, NOW());
SET p_result = 'SUCCESS';
ELSE
SET p_result = 'INSUFFICIENT_BALANCE';
END IF;
COMMIT;
END //
DELIMITER ;
-- 呼叫
CALL sp_transfer_account(1001, 1002, 500.00, @result);
SELECT @result;
| 場景 | 推薦方案 | 理由 |
|---|---|---|
| 簡化唯讀查詢、統一業務口徑 | 視圖 | 語義清晰、自動同步、可直接 JOIN |
| 需參數化、寫入操作、事務控制、複雜流程 | 存儲過程 | 封裝性強、原子性、減少網路交互 |
| 需回傳結果集且邏輯固定 | 視圖或存儲過程均可 | 視圖更直觀,存儲過程更靈活 |
ANALYZE TABLE 更新統計資訊,確保視圖/存儲過程查詢計劃最優。EXECUTE 權限,禁止直接操作基礎表。合理引入視圖與存儲過程,能讓資料庫從「單純的資料倉庫」進化為「具備業務語義的資料服務層」,是中大型系統架構演進的關鍵一步。