MySQL中的存儲(chǔ)過(guò)程異常處理
在使用MySQL存儲(chǔ)過(guò)程時(shí),其中的代碼可能會(huì)出現(xiàn)運(yùn)行錯(cuò)誤從而導(dǎo)致異常,此時(shí)需要將存儲(chǔ)過(guò)程中產(chǎn)生的異常捕獲并打印出來(lái)
需要知道的概念:
condition
hanlder
diagnostics area(診斷區(qū))
1. condition
存儲(chǔ)過(guò)程中出現(xiàn)的錯(cuò)誤事件也就是異常都可以被稱為condition。
declare condition語(yǔ)法:
DECLARE condition_name CONDITION FOR condition_value condition_value: mysql_error_code | SQLSTATE [VALUE] sqlstate_value
declare condition語(yǔ)句的作用是給需要進(jìn)行處理的condition定義一個(gè)名稱,并提供給后續(xù)的declare handler進(jìn)行調(diào)用,從而使代碼清晰化。
例如:定義一個(gè)名稱為"no_such_table"的condition,并在declare handler中調(diào)用該名稱。
declare condition中可以使用error code(報(bào)錯(cuò)的代碼)值或是sqlstate(5位的字符串)值。
使用error code值定義condition:
DECLARE no_such_table CONDITION FOR 1051; DECLARE CONTINUE HANDLER FOR no_such_table BEGIN -- body of handler END;
使用sqlstate值定義condition
DECLARE no_such_table CONDITION FOR SQLSTATE '42S02'; DECLARE CONTINUE HANDLER FOR no_such_table BEGIN -- body of handler END;
開(kāi)頭為’0’的error code或是開(kāi)頭為’00’的sqlstate值不能用于定義condition,因?yàn)樗鼈兇淼氖浅晒?,而不是異常?/p>
在SIGNAL或者是RESIGNAL中引用的condition,必須是使用sqlstate定義的condition,不能使用error code定義的condition。
存儲(chǔ)過(guò)程中的declare condition語(yǔ)句,必須出現(xiàn)在declare cursor或是declare handler之前,否則會(huì)報(bào)錯(cuò)。
2.handler
handler就是用來(lái)處理condition的,當(dāng)定義的condition發(fā)生時(shí),就執(zhí)行handler中定義的處理邏輯,handler可以處理多個(gè)condition。
declare handler語(yǔ)法:
DECLARE handler_action HANDLER FOR condition_value [, condition_value] ... statement handler_action: CONTINUE | EXIT | UNDO condition_value: mysql_error_code | SQLSTATE [VALUE] sqlstate_value | condition_name | SQLWARNING | NOT FOUND | SQLEXCEPTION
declare handler的語(yǔ)句必須在declare condition語(yǔ)句和定義變量語(yǔ)句之后出現(xiàn)
當(dāng)handler中定義的condition觸發(fā)時(shí),可以采取以下三種處理方式:
- 1.CONTINUE:發(fā)送錯(cuò)誤時(shí)繼續(xù)執(zhí)行后續(xù)代碼
- 2.EXIT:發(fā)生錯(cuò)誤時(shí)退出該handler定義所在的代碼塊(可能是子代碼塊或者main代碼塊)
- 3.UNDO:回滾所有的操作,目前還不支持,所以只有continue和exit可用。
示例:
1.使用error code定義handler
? ? DECLARE CONTINUE HANDLER FOR 1051 ? ? BEGIN ? ? -- body of handler ? ? END;
2.使用sqlstate值定義handler
? ? DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' ? ? BEGIN ? ? -- body of handler ? ? END;
3.SQLWARNING代表01開(kāi)頭的sqlstate值
? ? DECLARE CONTINUE HANDLER FOR SQLWARNING ? ? BEGIN ? ? -- body of handler ? ? END;
4.NOT FOUND代表02開(kāi)頭的sqlstate值,這通常用于具有游標(biāo)的上下文關(guān)系中,用來(lái)處理游標(biāo)走到數(shù)據(jù)集終點(diǎn)時(shí)的condition。
? ? DECLARE CONTINUE HANDLER FOR NOT FOUND ? ? BEGIN ? ? -- body of handler ? ? END;
5.SQLEXCEPTION代表所有其他不是以00,01,02開(kāi)頭的sqlstate值
? ? DECLARE CONTINUE HANDLER FOR SQLEXCEPTION ? ? BEGIN ? ? -- body of handler ? ? END;
注意1:
在存儲(chǔ)過(guò)程中,如果出現(xiàn)了一個(gè)condition,但是此時(shí)沒(méi)有定義相關(guān)的handler,那么處理該condition的方法取決于該condition的類型
- SQLEXCEPTION類型的condition
- 默認(rèn)使用EXIT handler來(lái)進(jìn)行處理,如果此時(shí)該存儲(chǔ)過(guò)程被另外一個(gè)存儲(chǔ)過(guò)程調(diào)用,那么將使用調(diào)用者中定義的handler來(lái)進(jìn)行處理。
- SQLWARNING類型的condition
- 默認(rèn)使用CONTINUE handler來(lái)進(jìn)行處理,存儲(chǔ)過(guò)程繼續(xù)執(zhí)行。
- NOT FOUND類型的condition
- 如果condition被正常拋出,那么存儲(chǔ)過(guò)程正常執(zhí)行,也就是continue的處理方式,如果是被SIGNAL或RESIGNAL拋出,那么存儲(chǔ)過(guò)程終止運(yùn)行,也就是exit的處理方式
來(lái)看官網(wǎng)的一個(gè)SQLSTATE '23000’主鍵沖突的例子:
mysql> CREATE TABLE test.t (s1 INT, PRIMARY KEY (s1)); Query OK, 0 rows affected (0.00 sec) mysql> delimiter // mysql> CREATE PROCEDURE handlerdemo () -> BEGIN -> DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1; -> SET @x = 1; -> INSERT INTO test.t VALUES (1); -> SET @x = 2; -> INSERT INTO test.t VALUES (1); -> SET @x = 3; -> END; -> // Query OK, 0 rows affected (0.00 sec) mysql> CALL handlerdemo()// Query OK, 0 rows affected (0.00 sec) mysql> SELECT @x// +------+ | @x | +------+ | 3 | +------+ 1 row in set (0.00 sec)
可以看到存儲(chǔ)過(guò)程是正常執(zhí)行的。
如果希望被handler對(duì)捕獲到condition不進(jìn)行任何處理,那么可以這樣定義handler:
DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN END;
注意2:
標(biāo)簽的代碼范圍不包括declare handler的代碼范圍,所以在declare handler中不能使用iterate和leave語(yǔ)句,即使標(biāo)簽的范圍包含了declare handler的范圍。
在下述例子中,標(biāo)簽retry的范圍是整個(gè)repeat循環(huán)的范圍,在這個(gè)范圍中使用了declare handler語(yǔ)句,表面上看retry包含了declare handler,但實(shí)際上retry的范圍只是IF語(yǔ)句的范圍,并不包括declare handler的范圍。
CREATE PROCEDURE p () BEGIN DECLARE i INT DEFAULT 3; retry: REPEAT BEGIN DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN ITERATE retry; # 我不屬于retry的作用范圍哦,所以我不能使用retry標(biāo)簽 END; IF i < 0 THEN LEAVE retry; #我才屬于retry的范圍,我可以使用retry標(biāo)簽。 END IF; SET i = i - 1; END; UNTIL FALSE END REPEAT; END;
所以存儲(chǔ)過(guò)程執(zhí)行時(shí)會(huì)出現(xiàn)下述錯(cuò)誤:
ERROR 1308 (42000): LEAVE with no matching label: retry
所以為了避免在handler的中引用外部標(biāo)簽,可以使用下述方法:
1.定義exit類型的handler
如果存儲(chǔ)過(guò)程遇到異常停止運(yùn)行時(shí),無(wú)需做一些cleanup操作,可以如下定義:
DECLARE EXIT HANDLER FOR SQLWARNING BEGIN END;
如果需要做一些cleanup操作,可以在begin…end中編寫(xiě)相應(yīng)處理邏輯:
DECLARE EXIT HANDLER FOR SQLWARNING BEGIN block cleanup statements END;
2.定義continue類型的handler,并使用一個(gè)狀態(tài)變量
CREATE PROCEDURE p () BEGIN DECLARE i INT DEFAULT 3; DECLARE done INT DEFAULT FALSE; retry: REPEAT BEGIN DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN SET done = TRUE; END; IF done OR i < 0 THEN LEAVE retry; END IF; SET i = i - 1; END; UNTIL FALSE END REPEAT; END;
這里使用了一個(gè)名稱為done的變量,通過(guò)判斷這個(gè)變量的狀態(tài),從而得知是否調(diào)用了continue handler。
3.diagnostics area
SQL語(yǔ)句的執(zhí)行會(huì)產(chǎn)生診斷信息,并存放于診斷區(qū)中
通過(guò)GET DIAGNOSTICS語(yǔ)句獲取診斷區(qū)中的內(nèi)容,該語(yǔ)句不需要特殊的權(quán)限。
診斷區(qū)分為當(dāng)前診斷區(qū)和堆棧診斷區(qū),通過(guò)CURRENT關(guān)鍵字來(lái)獲取當(dāng)前診斷區(qū)中的內(nèi)容,通過(guò)STACKED獲取堆棧診斷區(qū)中的內(nèi)容,堆棧診斷區(qū)只有在上下文為condition handler的情況下才可以使用,如果不指定關(guān)鍵字默認(rèn)從當(dāng)前診斷區(qū)獲取信息
在客戶端獲取診斷區(qū)中的數(shù)據(jù)
DROP TABLE test.no_such_table; GET DIAGNOSTICS CONDITION 1 @p1 = RETURNED_SQLSTATE, @p2 = MESSAGE_TEXT; SELECT @p1, @p2;
此時(shí)并不能使用GET STACKED DIAGNOSTICS堆棧診斷區(qū)中的內(nèi)容,
因?yàn)镚ET STACKED DIAGNOSTICS只能在condition handler中使用
診斷區(qū)匯總包含2種信息:
1.語(yǔ)句信息,例如conditions的數(shù)量和影響的行數(shù)
2. Condition信息,包括錯(cuò)誤代碼和錯(cuò)誤消息,如果SQL語(yǔ)句拋出多個(gè) conditions,那么在這部分診斷區(qū)中,會(huì)為每一個(gè)condition分配一個(gè)condition區(qū),如果沒(méi)有拋出condition那么就不會(huì)分配
如果語(yǔ)句產(chǎn)生了3個(gè)condition,那么診斷區(qū)包含的語(yǔ)句信息和condition信息類似:
Statement information: row count ... other statement information items ... Condition Handling Condition area list: Condition area 1: error code for condition 1 error message for condition 1 ... other condition information items ... Condition area 2: error code for condition 2: error message for condition 2 ... other condition information items ... Condition area 3: error code for condition 3 error message for condition 3 ... other condition information items ...
GET DIAGNOSTICS語(yǔ)句可以獲取語(yǔ)句信息或者condition信息,但是一條GET DIAGNOSTICS無(wú)法同時(shí)獲取這2種信息。
獲取診斷區(qū)中語(yǔ)句信息并保存到p1和p2變量中,本例中獲取的是condition的數(shù)量和rows-affected數(shù)量
GET DIAGNOSTICS @p1 = NUMBER, @p2 = ROW_COUNT;
通過(guò)指定condition的編號(hào)獲取診斷區(qū)中相應(yīng)condition信息到p3和p4變量中,本例中獲取的是sqlstate值和錯(cuò)誤消息。
GET DIAGNOSTICS CONDITION 1 @p3 = RETURNED_SQLSTATE, @p4 = MESSAGE_TEXT;
在SQL標(biāo)準(zhǔn)中,如果出現(xiàn)多個(gè)condition,那么第一個(gè)condition是關(guān)于前一個(gè)SQL語(yǔ)句返回的sqlstate值的,但是在MySQL中,無(wú)法保證這一點(diǎn),為了得到主要的錯(cuò)誤,不能使用下面的方法:
GET DIAGNOSTICS CONDITION 1 @errno = MYSQL_ERRNO;
而是先取回condition的數(shù)量,然后使用該值來(lái)指定要查看的condition
正確的方法:
GET DIAGNOSTICS @cno = NUMBER; GET DIAGNOSTICS CONDITION @cno @errno = MYSQL_ERRNO;
關(guān)于診斷區(qū),官網(wǎng)的例子:
CREATE PROCEDURE do_insert(value INT) BEGIN -- Declare variables to hold diagnostics area information DECLARE code CHAR(5) DEFAULT '00000'; DECLARE msg TEXT; DECLARE rows INT; DECLARE result TEXT; -- Declare exception handler for failed insert DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN GET DIAGNOSTICS CONDITION 1 code = RETURNED_SQLSTATE, msg = MESSAGE_TEXT; END; -- Perform the insert INSERT INTO t1 (int_col) VALUES(value); -- Check whether the insert was successful IF code = '00000' THEN GET DIAGNOSTICS rows = ROW_COUNT; SET result = CONCAT('insert succeeded, row count = ',rows); ELSE SET result = CONCAT('insert failed, error = ',code,', message = ',msg); END IF; -- Say what happened SELECT result; END;
假設(shè)上述存儲(chǔ)過(guò)程中的t1表的字段類型int,并且not null,那么在進(jìn)行下述操作分別向表t1中插入非空值和空值,各自得到的結(jié)果如下:
#插入非空值 mysql> CALL do_insert(1); +---------------------------------+ | result | +---------------------------------+ | insert succeeded, row count = 1 | +---------------------------------+ ##插入null mysql> CALL do_insert(NULL); +---- ------------------------------------------------------------+ | result | +-----------------------------------------------------------------+ insert failed, error = 23000, message = Column 'int_col' cannot be null +-----------------------------------------------------------------+
當(dāng)存儲(chǔ)過(guò)程中的condition handler被激活時(shí),會(huì)發(fā)生一個(gè)向診斷區(qū)堆棧推送的事件:
1.當(dāng)前診斷區(qū)(第一診斷區(qū))會(huì)變?yōu)槎褩T\斷區(qū)(第二診斷區(qū)),并且創(chuàng)建一個(gè)新的診斷區(qū)作為當(dāng)前診斷區(qū)。
2.在condition Handler中可以使用 GET [CURRENT] DIAGNOSTICS 和 GET STACKED DIAGNOSTICS來(lái)獲取當(dāng)前診斷區(qū)或堆棧診斷區(qū)中的內(nèi)容。
3.在開(kāi)始的時(shí)候,當(dāng)前診斷區(qū)和堆棧診斷區(qū)會(huì)返回相同的結(jié)果,所以有可能從當(dāng)前診斷區(qū)獲取到被激活的Handler的condition的相關(guān)信息,只要此時(shí)handler中沒(méi)有其他SQL語(yǔ)句去改變當(dāng)前診斷區(qū)中的內(nèi)容。
4.隨著Handler中語(yǔ)句的執(zhí)行,會(huì)根據(jù)一定的規(guī)則對(duì)當(dāng)前診斷區(qū)的內(nèi)容進(jìn)行清空或者修改。
所以更可靠地獲取被激活condition handler中信息的方法是從堆棧診斷區(qū)中獲取相關(guān)信息,因?yàn)槎褩T\斷區(qū)中的內(nèi)容不會(huì)被condition handler中的語(yǔ)句所修改,除了RESIGNAL語(yǔ)句。
通過(guò)下面例子來(lái)說(shuō)明,在condition中如何通過(guò) GET STACKED DIAGNOSTICS語(yǔ)句來(lái)獲取關(guān)于handler異常的信息,盡管此時(shí)當(dāng)前診斷區(qū)已經(jīng)被清空或修改。
DROP TABLE IF EXISTS t1; CREATE TABLE t1 (c1 TEXT NOT NULL); DROP PROCEDURE IF EXISTS p; delimiter // CREATE PROCEDURE p () BEGIN -- Declare variables to hold diagnostics area information DECLARE errcount INT; DECLARE errno INT; DECLARE msg TEXT; DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN -- Here the current DA is nonempty because no prior statements -- executing within the handler have cleared it GET CURRENT DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'current DA before mapped insert' AS op, errno, msg; GET STACKED DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'stacked DA before mapped insert' AS op, errno, msg; -- Map attempted NULL insert to empty string insert INSERT INTO t1 (c1) VALUES(''); -- Here the current DA should be empty (if the INSERT succeeded), -- so check whether there are conditions before attempting to -- obtain condition information GET CURRENT DIAGNOSTICS errcount = NUMBER; IF errcount = 0 THEN SELECT 'mapped insert succeeded, current DA is empty' AS op; ELSE GET CURRENT DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'current DA after mapped insert' AS op, errno, msg; END IF ; GET STACKED DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'stacked DA after mapped insert' AS op, errno, msg; END; INSERT INTO t1 (c1) VALUES('string 1'); INSERT INTO t1 (c1) VALUES(NULL); END; // delimiter ; CALL p(); SELECT * FROM t1;
在上述存儲(chǔ)過(guò)程中,定義了一個(gè)condition handler,在這個(gè)handler的開(kāi)頭處分別獲取當(dāng)前診斷區(qū)和堆棧診斷區(qū)中的內(nèi)容,然后執(zhí)行一條insert語(yǔ)句,之后再分別查詢當(dāng)前診斷區(qū)和堆棧診斷區(qū)的內(nèi)容。
在handler定義結(jié)束后,是這個(gè)存儲(chǔ)過(guò)程的主體,也就是2條insert語(yǔ)句,其中一條insert語(yǔ)句為非空值字符串,另外一條insert插入的值為null,
所以該存儲(chǔ)過(guò)程執(zhí)行順序如下:
1.首先成功執(zhí)行INSERT INTO t1 (c1) VALUES(‘string 1’);
2.執(zhí)行INSERT INTO t1 (c1) VALUES(NULL);因?yàn)閠1表中禁止插入空值,所以會(huì)拋出異常。
3.拋出的異常被condition handler捕獲,condition handler被激活從而觸發(fā)其中的處理邏輯,并打印condition handler中當(dāng)前診斷區(qū)和堆棧診斷區(qū)的內(nèi)容,二者內(nèi)容相同。
4.condition handler中的INSERT INTO t1 (c1) VALUES(’’);語(yǔ)句執(zhí)行,該語(yǔ)句的執(zhí)行會(huì)清空當(dāng)前診斷區(qū)中的內(nèi)容。
+---------------------------------+-------+----------------------------+ | op | errno | msg | +---------------------------------+-------+----------------------------+ | stacked DA before mapped insert | 1048 | Column 'c1' cannot be null | +---------------------------------+-------+----------------------------+
5.再次打印condition handler中當(dāng)前診斷區(qū)和堆棧診斷區(qū)的內(nèi)容,此時(shí)因?yàn)楫?dāng)前診斷區(qū)的內(nèi)容被清空,所以打印’mapped insert succeeded, current DA is empty’,接著打印堆棧診斷區(qū)中內(nèi)容,因?yàn)槎褩T\斷區(qū)中的內(nèi)容不會(huì)隨著語(yǔ)句的執(zhí)行而被清空掉,所以堆棧診斷區(qū)顯示的內(nèi)容依舊是:
+--------------------------------+-------+----------------------------+ | op | errno | msg | +--------------------------------+-------+----------------------------+ | stacked DA after mapped insert | 1048 | Column 'c1' cannot be null | +--------------------------------+-------+----------------------------+
需要注意的是
1.GET DIAGNOSTICS語(yǔ)句也會(huì)清空當(dāng)前診斷區(qū)中的內(nèi)容,所以上述代碼中把condition handler中的insert語(yǔ)句去掉,得到的結(jié)果也是一樣的
2.如果將上述存儲(chǔ)過(guò)程進(jìn)行如下修改,也就是將3條declare變量的語(yǔ)句放到declare handler中,實(shí)際的結(jié)果將取決于MySQL的版本,如果是在MySQL-5.7.2之前的版本,下述修改后并不會(huì)影響診斷區(qū)中的內(nèi)容,實(shí)際結(jié)果與上述結(jié)果相同,如果實(shí)在MySQL-5.7.2及之后的版本,declare變量語(yǔ)句會(huì)清空當(dāng)前診斷區(qū)中的內(nèi)容。
CREATE PROCEDURE p () BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN -- Declare variables to hold diagnostics area information DECLARE errcount INT; DECLARE errno INT; DECLARE msg TEXT; GET CURRENT DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'current DA before mapped insert' AS op, errno, msg; GET STACKED DIAGNOSTICS CONDITION 1 errno = MYSQL_ERRNO, msg = MESSAGE_TEXT; SELECT 'stacked DA before mapped insert' AS op, errno, msg; ...
所以在需要獲取診斷區(qū)中的內(nèi)容時(shí),一定要從堆棧診斷區(qū)中獲取,而不是當(dāng)前診斷區(qū)。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
mysql實(shí)現(xiàn)合并同一ID對(duì)應(yīng)多條數(shù)據(jù)的方法
這篇文章主要介紹了mysql實(shí)現(xiàn)合并同一ID對(duì)應(yīng)多條數(shù)據(jù)的方法,涉及mysql GROUP_CONCAT函數(shù)的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06MySQL文件權(quán)限存在的安全問(wèn)題和解決方案
MySQL文件權(quán)限是用來(lái)控制用戶對(duì)數(shù)據(jù)庫(kù)文件以及目錄的操作權(quán)限,在MySQL中,這些權(quán)限通常由系統(tǒng)管理員分配,通過(guò)GRANT和REVOKE語(yǔ)句進(jìn)行管理,本文給大家介紹了MySQL文件權(quán)限存在的安全問(wèn)題和解決方案,需要的朋友可以參考下2024-07-07mysql數(shù)據(jù)庫(kù)mysql: [ERROR] unknown option ''--skip-grant-tables'
這篇文章主要介紹了mysql數(shù)據(jù)庫(kù)mysql: [ERROR] unknown option '--skip-grant-tables',需要的朋友可以參考下2020-03-03淺談Mysql時(shí)間的存儲(chǔ)?datetime還是時(shí)間戳timestamp
本文主要介紹了淺談Mysql時(shí)間的存儲(chǔ)?datetime還是時(shí)間戳timestamp,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07數(shù)據(jù)庫(kù)中笛卡爾積定義、生成與避免策略實(shí)踐方法
笛卡爾積是指兩個(gè)集合中的每個(gè)元素都與另一個(gè)集合中的每個(gè)元素組合形成的所有元素的集合,這篇文章主要給大家介紹了關(guān)于數(shù)據(jù)庫(kù)中笛卡爾積定義、生成與避免策略實(shí)踐的相關(guān)資料,需要的朋友可以參考下2024-05-05MySQL配置了雙主,是如何避免出現(xiàn)數(shù)據(jù)回環(huán)沖突的
這篇文章主要介紹了MySQL配置了雙主,是如何避免出現(xiàn)數(shù)據(jù)回環(huán)沖突的,幫助大家更好的理解和使用MySQL數(shù)據(jù)庫(kù),感興趣的朋友可以了解下2021-01-01MySQL處理DB讀寫(xiě)分離數(shù)據(jù)不一致問(wèn)題的方案
在互聯(lián)網(wǎng)中大型項(xiàng)目中,讀寫(xiě)分離應(yīng)該是我們小伙伴經(jīng)常聽(tīng)說(shuō)的,這個(gè)主要解決大流量請(qǐng)求時(shí),提高系統(tǒng)的吞吐量,本文給大家介紹了MySQL處理DB讀寫(xiě)分離數(shù)據(jù)不一致問(wèn)題的方案,需要的朋友可以參考下2024-02-02MySQL使用全庫(kù)備份數(shù)據(jù)恢復(fù)單表數(shù)據(jù)的方法
這篇文章主要給大家介紹了關(guān)于MySQL使用全庫(kù)備份數(shù)據(jù)恢復(fù)單表數(shù)據(jù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用mysql具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧2018-12-12mysql explain的用法(使用explain優(yōu)化查詢語(yǔ)句)
mysql explain可以幫助你檢查索引和更好的優(yōu)化查詢語(yǔ)句,今天特地學(xué)習(xí)了下mysql explain的用法,需要的朋友可以參考下2017-01-01