程式設計師必備介面測試偵錯工具:
推薦學習:
MySQL 中我們最常用的增刪改查,對應SQL語句就是 insert 、delete、update、select,這種運算元據的語句,又叫Data Manipulation Statements(資料操作語句)。
一共是15種,分別是CALL、DELETE、DO、HANDLER、IMPORT TABLE、INSERT、LOAD DATA、LOAD XML、REPL ACE、SELECT、Subqueries、TABLE、UPDATE、VALUES、WITH。
insert 插入,下面給出插入資料行的通用語句,如果列表和 VALUES 列表都為空,則INSERT建立一行,每列設定為其預設值;
還可以使用 VALUES ROW() 語法的語句也可以插入多行。在這種情況下,每個值列表必須包含在ROW()(行建構函式)中,如下所示:
-- 插入語句模板
INSERT INTO tbl_name () VALUES();
-- 插入多行
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3), (4,5,6), (7,8,9);
INSERT INTO tbl_name (a,b,c) VALUES ROW(1,2,3), ROW(4,5,6), ROW(7,8,9);
登入後複製
我們建表的時候經常會使用主鍵,當我們的系統執行並行落庫的時候,為了避免主鍵衝突,經常會使用 ON DUPLICATE KEY UPDATE。
注意:ON DUPLICATE KEY UPDATE 是Mysql特有的語法,僅Mysql有效。作用:當執行insert操作時,有已經存在的記錄,執行update操作。
如果使用了 ON DUPLICATE KEY UPDATE 子句,並且重複的鍵導致執行UPDATE,則該語句需要更新列的UPDATE許可權。對於已讀取但未修改的列,您只需要SELECT許可權(因為無需更新,很好理解)。
INSERT INTO test ( id, NAME, age ) VALUES( 1, '張三', 13 )
ON DUPLICATE KEY UPDATE age = 13,
登入後複製
如果未啟用嚴格模式(嚴格 SQL 模式),MySQL 對任何沒有顯式定義預設值的列使用隱式預設值。如果啟用了嚴格模式,如果任何列沒有預設值,則會發生錯誤。(嚴格模式會在後續的文章中講到) 。
delete顧名思義是刪除,該DELETE語句從中刪除行 tbl_name並返回已刪除的行數。要檢查刪除的行數我們一般寫程式碼的時候使用 int 型別返回:
-- 刪除語法
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[WHERE where_condition] [ORDER BY ...] [LIMIT row_count]
-- WHERE 中的條件確定要刪除哪些行,如果沒有WHERE 子句則刪除所有行
-- 如果指定了ORDER BY子句,則按指定的順序刪除行
-- LIMIT子句對可以刪除的行數進行了限制
-- 如果指定LOW_PRIORITY修飾符,伺服器會延遲刪除,DELETE直到沒有其他使用者端從表中讀取
-- QUICK是否合併索引進行刪除操作,可能會導致索引中未回收的空間浪費
-- IGNORE,MySQL在刪除行的過程中忽略可忽略的錯誤
登入後複製
如果指定LOW_PRIORITY修飾符,伺服器會延遲刪除,DELETE直到沒有其他使用者端從表中讀取。QUICK是否合併索引進行刪除操作,可能會導致索引中未回收的空間浪費。IGNORE,MySQL在刪除行的過程中忽略可忽略的錯誤。
WHERE 中的條件確定要刪除哪些行,如果沒有WHERE 子句則刪除所有行,如果指定了ORDER BY子句,則按指定的順序刪除行,LIMIT子句對可以刪除的行數進行了限制
1、大批次刪除
如果要從大表中刪除許多行,則可能會超過InnoDB表的鎖表大小。為了避免這個問題,或者僅僅為了最小化表保持鎖定的時間,以下策略可能會有所幫助:
1、使用儲存過程進行不影響業務的小批次、長時間刪除,刪除完畢後將儲存過程從生產環境下線。
2、選擇不刪除的行,同步與原表結構相同的空表中:INSERT INTO t_copy SELECT * FROM t WHERE ... ;
3、用於 RENAMETABLE 以原子方式將原始表移開並將副本重新命名為原始名稱:RENAME TABLE t TO t_old, t_copy TO t;
2、多表刪除
1、根據WHERE子句中的條件,可以在DELETE語句中指定多個表以從一個或多個表中刪除行,但是不能在多表DELETE中使用ORDER BY或LIMIT。
DELETE FROM t1, t2 USING t1 INNER JOIN t2 INNER JOIN t3
WHERE t1.id=t2.id AND t2.id=t3.id;
登入後複製
UPDATE是修改表中行的語句,返回實際更改的行數,要檢查刪除的行數我們一般寫程式碼的時候使用 int 型別返回,對於單表語法,UPDATE語句使用新值更新命名錶中現有行的列。
SET 要修改的列以及應該給出的值,每個值都可以作為表示式或關鍵字DEFAULT給出,以將列顯式設定為其預設值。
WHERE 指定標識要更新哪些行的條件。如果沒有WHERE子句,將更新所有行。如果指定了ORDER BY子句,則將按指定的順序更新行。LIMIT子句限制了可以更新的行數。
-- 更新單表語法
UPDATE [LOW_PRIORITY] [IGNORE] table_reference
SET assignment_list
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
-- 使用LOW_PRIORITY修飾符,UPDATE延遲執行,直到沒有其他使用者端從表中讀取
-- 使用IGNORE修飾符,即使更新期間發生錯誤,更新語句也不會中止
UPDATE item_id, discounted SET items_info WHERE id = "";
登入後複製
SELECT用於檢索從一個或多個表中選擇的行,並且可以包括UNION操作和子查詢。從MySQL 8.0.31開始,還支援INTERSECT和EXCEPT操作。後面筆者會單獨拿出一篇文章講解子查詢、左連線、查詢優化、查詢原理等等。
後面更新後會附上連線
類似於增刪改查的語句我們在第一節已經學習,本小節主要講解 CALL、DO、HANDLER、IMPORT TABLE、LOAD DATA、LOAD XML、REPL ACE、Subqueries、TABLE、VALUES、WITH,這11個語句的使用,後續會詳細的進行詳細分析,關注本專欄。
REPLACE的工作方式與INSERT完全相同,只是如果表中的一箇舊行與PRIMARY KEY或UNIQUE索引的新行具有相同的值,則在插入新行之前會刪除舊行。在MySQL 8.0中已不支援DELAYED。
CALL語句呼叫先前使用CREATE procedure定義的儲存過程。當過程返回時,使用者端程式還可以獲得例程內執行的最終語句所影響的行數。
TABLE是MySQL 8.0.19中引入的DML語句,返回命名錶的行和列。
WITH每個子子句提供一個子查詢,該子查詢生成一個結果集,並將名稱與子查詢相關聯。
WITH
cte1 AS (SELECT a, b FROM table1),
cte2 AS (SELECT c, d FROM table2)
SELECT b, d FROM cte1 JOIN cte2 WHERE cte1.a = cte2.c;
登入後複製
兩個值進行查詢,運算或者比較,首先要求資料型別必須一致。如果發現兩個資料型別不一致時就會發生隱式型別轉換。
問題描述:
分享一個筆者同事曾經發生的產線問題:在一次MySQL查詢中,某欄位為 varchar 字串型別,傳入引數值為 long 數位型別,發現查詢的結果和預期的不一致。
select * from 表 where odr_id = "";
select * from 表 where odr_id = long;
登入後複製
但是由於測試環境的資料量較少,並沒有發現,只到上了生產環境,在進行巨量資料查詢時,由於資料庫的odr_id是 varchar 型別,查詢條件是 long型別,所有每條查詢出來的資料都會進行隱式型別轉換的比較,直接導致long sql,處理辦法是緊急版本上線。
隱式型別轉換原理:
如果一個或兩個引數均為NULL,則比較的結果為NULL,除了 相等比較運運算元。對於NULL NULL,結果為true;如果比較操作中的兩個引數都是字串,則將它們作為字串進行比較;如果兩個引數都是整數,則將它們作為整數進行比較。
如果不與數位比較,則將十六進位制值視為二進位制字串;如果引數之一是 timestamp 或 datatime column,而另一個引數是常數,則在執行比較之前,該常數將轉換為時間戳;如果引數之一是十進位制值,則比較取決於另一個引數。
如果另一個引數是十進位制或整數值,則將引數作為十進位制值進行比較(這裡如果生產環境是varchar後果將是災難級的);
如果另一個引數是浮點值,則將引數作為浮點值進行比較。;在所有其他情況下,將引數作為浮點數(實數)進行比較。例如,將字串和數位運算元進行比較,將其作為浮點數的比較。
通過隱式型別轉換可以得出上述範例的結果:當查詢中有數位時那麼會將字串轉化成數位進行比較。所以當你的列為字串時那麼需要將列中字串進行型別格式轉換而進行字元格式轉換之後則與索引不一致;當你的列為數位時查詢等式為字串時只是把查詢的常數轉成數位並不影響列的型別所以依然可以使用索引並沒有破壞索引的型別。
推薦學習:
以上就是MySQL增刪改查與常見陷阱詳解的詳細內容,更多請關注TW511.COM其它相關文章!