大型系統必須得要存儲過程和觸發器嗎,from 知乎
通常狀況下,Web 應用的瓶頸常在 DB 上,因此會盡量的減小 DB 作的事情,把耗時的服務作成 Scale Out,這種狀況下,確定不會使用存儲過程;mysql
而若是隻是通常的應用(好比,SAP、peopleSoft、ERP 等企業級別應用),DB 沒有性能上的問題,在適當的場景下,也可使用存儲過程。減小開發成本,畢竟其業務邏輯修改頻繁,並且爲通用,不少時候會把一些業務邏輯編寫成存儲過程,像 Oracle 會寫成包,比存儲過程更強大。另一個緣由是服務器的負載是可控,也即系統的訪問人數首先是可控的,沒有那麼大,並且這些數據又很是關鍵,爲此每每使用的設備也比較好,多用存儲櫃子支撐數據庫sql
至於觸發器,我是知道有這東西但歷來沒用過。我但願風險可控,遇到問題可以快速的找到緣由,儘量不會去使用觸發器。數據庫
存儲過程簡單來講,就是爲之後的使用而保存的一條或多條MySQL語句的集合。可將其視爲批文件,雖然它們的做用不限於批處理。安全
使用存儲過程的理由(簡單,安全,高性能
):服務器
經過把處理封裝在容易使用的單元中,簡化複雜的操做 - 簡單
。網絡
因爲不要求反覆創建一系列處理步驟,這保證了數據的完整性。 若是全部開發人員和應用程序都使用同一(test)存儲過程,則所使用的代碼都是相同的 -- 即防止錯誤。須要執行的步驟越多,出錯的可能性就越大。防止錯誤保證了數據一致性。併發
簡化對變更的管理。若是表名,列名或業務邏輯有變化,只須要更改存儲過程的代碼。 -- 即保證安全性
。系統管理員經過執行某一存儲過程的權限進行限制,可以實現對相應的數據的訪問權限的限制,避免了非受權用戶對數據的訪問,保證了數據的安全.ide
存儲過程能減小網絡流量。性能
針對同一個數據庫對象的操做(如查詢、修改),若是這一操做所涉及的 Transaction-SQL 語句被組織程存儲過程,那麼當在客戶計算機上調用該存儲過程時,網絡中傳送的只是該調用語句,從而大大增長了網絡流量並下降了網絡負載。fetch
提升性能
。使用存儲過程比使用單獨sql語句快.
若是某一操做包含大量的 Transaction-SQL 代碼或分別被屢次執行,那麼存儲過程要比批處理的執行速度快不少。由於存儲過程是預編譯的。在首次運行一個存儲過程時查詢,優化器對其進行分析 優化,而且給出最終被存儲在系統表中的執行計劃。而批處理的 Transaction-SQL 語句在每次運行時都要進行編譯和優化,速度相對要慢一些。
存儲過程的缺陷:
存儲過程的編寫比基本SQL複雜。
用戶可能沒有建立存儲過程的安全訪問權限。
mysql-- 無參數 或者 有參數 Delimiter // CREATE PROCEDURE productpricing( OUT pl DECIMAL(8,2), OUT ph DECIMAL(8,2), OUT pa DECIMAL(8,2), ) BEGIN SELECT MIN(prod_price) INTO pl FROM products; SELECT MAX(prod_price) INTO ph FROM products; SELECT Avg(prod_price) INTO pa FROM products; END // Delimiter ;
調用此修改過的存儲過程,指定出三個變量名
mysqlcall productpricing(@pricelow, @pricehigh, @priceaverage);
mysqlselect @priceaverage;
例子2: 檢索出產品平均價格
mysqlCREATE PROCEDURE ordertotal( IN onumber INT, OUT ototal DECIMAL(8,2), ) BEGIN SELECT Sum(item_price * quantity) from orderitems where order_num = onumber into ototal END // Delimiter ;
調用存儲過程
mysqlcall productpricing(20005, @total);
顯示查詢
mysqlselect @total;
遊標是一個存儲在mysql服務器上的數據庫查詢,他不是一條select語句,而是被該語句檢索出來的結果集。
如定義了ordernumbers的遊標,用來檢索全部訂單的select語句。
使用遊標的數據:
mysqlcreate procedure processorder() begin -- declare local variables declare o int; -- declare the cursor declare ordernumbers cursor for select order_num from orders; -- open the cursor open ordernumbers; -- get order number fetch ordernumbers into o; -- close the cursor close ordernumbers; end //
事務處理:是用戶定義的一個數據庫操做序列,這些操做保證成批的MySQL操做要麼徹底執行,要麼徹底不執行。 transaction processing 能夠用來維護數據庫的完整性
:若是沒有錯誤發生,整組語句提交給數據庫表。若是發生錯誤,則進行回退(撤銷)以恢復數據庫到某個已知且安全的狀態。
一個事務能夠是一條SQL語句,也能夠一組SQL語句。事務和程序是兩個概念,Generally, 一個程序包含多個事務。
MySQL 的事務支持不是綁定在 MySQL 服務器自己,而是與存儲引擎相關:
1.MyISAM:不支持事務,用於只讀程序提升性能
2.InnoDB:支持 ACID 事務、行級鎖、併發
3.Berkeley DB:支持事務
A 原子性: 事務是數據庫的邏輯工做單位,事務中包括的全部操做要麼都作,要麼都不作,不然事物將被終止在故障點,和之前的操做將回滾到之前的狀態。
C 一致性: 事務執行的結果必須是使數據庫從一個一致性的狀態變到另一個一致性狀態。
I 隔離性: 一個事物的執行不能被其餘事物干擾。即一個事物內部的操做及使用的數據對其餘事物是隔離的,併發執行的各個事物之間互相不干擾。
D 永久性: 一個事物一旦成功提交,對數據庫中數據的修改就是永久性。接下來其餘的其餘操做或故障不該該對其執行結果有任何影響。
管理事務處理的關鍵在於將SQL語句分解爲邏輯塊,並明確規定數據應該什麼時候回退,什麼時候不回退。保證事務的ACID是事務管理的重要任務。
begin transaction // 開始事務 commit // 結束事務(提交事務的全部操做,將事務中全部對DB的更新寫回到磁盤上的物理DB中,事務正常結束) rollback // 結束事務(回滾。事務在運行過程當中發生了某種故障,事務不能正常執行,系統將事務中對DB的全部已經完成的操做所有撤銷,回滾到事務開始的狀態。)
for eaxample: mysql語句使用rollback來回退/撤銷 mysql語句。
select * from orderitems; start transaction; delete from orderitems; rollback; select * from orderitems;
當系統運行過程當中發生故障,利用數據庫後備副本
和日誌文件
就能夠將數據庫恢復到故障以前的某個一致性狀態。
利用日誌
技術進行DB恢復時候,恢復子系統必須搜索日誌,肯定哪些事務須要REDO,哪些須要UNDO。(正向掃描日誌文件,找出故障發生前已經提交的事務(these transactions both have "begin transaction" and "commit"), 將其事務標識記入重作REDO隊列;同時找出故障發生時還沒有完成的事務(these transactions just have "begin transaction" not "commit")將其事務標識記入撤銷UNDO隊列)。
搜索整個日誌須要大量時間 --- 具備檢查點
的恢復技術。
多用戶數據庫系統。當多個用戶併發地存取數據庫時就會產生多個事務同時存取同一個數據的狀況。弱對併發操做不加控制就可能會存取和存儲不正確的數據,破壞事務的一致性
和數據庫的一致性
。 -- 因此引入併發控制。
事務ACID特性可能遭到破壞的緣由之一是多個事務對數據庫併發操做形成的。爲了保證事務的隔離性
和一致性
,DBMS須要對併發操做進行正確調度。
併發操做帶來的不一致性主要包括丟失修改,不可重複讀和讀髒數據。
併發控制的主要技術:封鎖,時間戳,樂觀控制法。
確保數據的安全和完整 -- 訪問控制, 即建立和管理用戶帳號。
MYSQL服務器的安全基礎是:用戶應該對他們須要的數據具備適當的訪問權,既不能多也不能少。
mysqlcreate user USERNAME identified by 'password';
mysqldrop user USERNAME;
建立用戶帳號後,必須接着分配訪問權限。新建立的用戶帳號沒有訪問權限,它們只能登陸mysql,可是看不到數據,不能執行任何數據庫操做
查看用戶的權限:
show grants for USERNAME;
GRANT
給出信息
- 要授予的權限
- 被授予訪問權限的數據庫或表
- 用戶名
grant容許用戶在數據庫creatdb.*的全部表上使用select
REVOKE
,撤銷特定的權限。
數據庫管理員而不是開發者使用這些語句。
mysqlANALYZE TABLE CHECK TABLE CHECKSUM TABLE OPTIMIZE TABLE REPAIR TABLE
首先保證全部數據都被寫到了磁盤,須要備份前刷新未寫數據
mysqlflush table
備份命令
- mysqldump
, 備份數據庫到外部文件
- mysqlhotcopy
從一個數據庫複製全部數據, 比mysldump快可是不被InnoDB支持。
- nysql的backup table
或者 select into outfile
轉儲全部數據到某個外部文件。
1. 對錶進行優化 (優化表主要做用是消除刪除或者更新形成的空間浪費) 2. 對錶進行分析(分析關鍵字的分佈, 分析並存儲 MyISAM 和 BDB 表中鍵的分佈) 3. 對錶進行檢查(檢查表的錯誤,而且爲 MyISAM 更新鍵的統計內容) 4. 對錶進行修復(修復被破壞的 MyISAM 表)
對錶的按期分析能夠改善性能,且應該成爲常規維護工做的一部分。由於經過更新表的索引信息對錶進行分析,可改善數據庫性能。
分析關鍵字的分佈, 分析並存儲 MyISAM 和 BDB 表中鍵的分佈
mysql 使用analyze table TABLENAME
來分析
Table:表示表的名稱;
Op:表示執行的操做。analyze 表示進行分析操做。check 表示進行檢查查找。optimize 表示進行優化操做;
Msg_type:表示信息類型,其顯示的值一般是狀態、警告、錯誤和信息這四者之一;
Msg_text:顯示信息。
檢查表和優化表以後也會出現這 4 列信息。
mysql 使用check table TABLENAME
來檢查,該語句能檢查InnoDB和MyISAM類型的表是否存在錯誤。並且能夠檢查視圖是否存在錯誤。
爲何優化?隨着 MySQL 的使用,包括 BLOB 和 VARCHAR 字節的表將變得比較繁冗,由於這些字段長度不一樣,對記錄進行插入、更新或刪除時,會佔有不一樣大小的空間,記錄就會變成碎片,且留下空閒的空間。像具備碎片的磁盤,會下降性能,須要整理,所以要優化。
三種優化的方式
1. mysql 使用optimize table TABLENAME
來檢查
2. 利用mysqlcheck
對錶進行優化
3. 利用myisamchk
對錶進行優化
想更一進步的支持我,請掃描下方的二維碼,你懂的~