MySQL入門系列:資料的插入、刪除和更新
上集中介紹了讓人眼花繚亂的查詢方式,包括簡單查詢、子查詢、連結查詢、組合查詢以及各種查詢細節,可別忘了表裡先得有資料,才能後查詢才能有意義啊!之前我們只是簡單介紹了資料的插入語句,本集中我們將詳細嘮叨各種對錶中資料的操作,包括插入資料、刪除資料和更新資料。
準備工作
本集中要嘮叨的是對錶中資料的操作,首先需要確定用哪個表來演示這些操作,本著勤儉節約的精神,我們還是複用之前用過的first_table
表,只不過這個錶快被玩壞了,我們把它刪掉重建一個,一切重新開始:
mysql> DROP TABLE first_table; Query OK, 0 rows affected (0.02 sec) mysql> mysql> CREATE TABLE first_table ( ->first_column INT, ->second_column VARCHAR(100) -> ); Query OK, 0 rows affected (0.03 sec) mysql> 複製程式碼
對於first_table
表來說,我們保留了兩個列,一個是INT
型別的first_column
列,另一個是VARCHAR(100)
型別的second_column
列。
插入資料
在關係型資料庫中,資料一般都是以記錄
(或者說行
)為單位被插入到表中的,具體的插入形式且看我們慢慢道來。
插入完整的記錄
在插入完整的一條記錄時,需要我們指定要插入表的名稱和該條記錄中全部 列的具體資料,完整的語法是這樣:
INSERT INTO 表名 VALUES(列1的值,列2的值, ..., 列n的值); 複製程式碼
比如first_table
裡有兩個列,分別是first_column
和second_column
,如果我們想要插入完整的記錄的話,VAULES()
中必須依次填入first_column
列和second_column
列的值,比如這樣:
mysql> INSERT INTO first_table VALUES(1, 'aaa'); Query OK, 1 row affected (0.00 sec) mysql> 複製程式碼
可以看到執行結果是Query OK, 1 row affected (0.01 sec)
,表明成功的插入了一行。然後再用SELECT
語句看看錶中的資料:
mysql> SELECT * FROM first_table; +--------------+---------------+ | first_column | second_column | +--------------+---------------+ |1 | aaa| +--------------+---------------+ 1 row in set (0.00 sec) mysql> 複製程式碼
現在的first_table
中就有了一條記錄了。在使用這種插入一條完整記錄的語法時必須注意,VALUES語句中必須給出表中所有列的值,缺一個都不行
,如果某個列我們不知道填什麼值,可以使用填入NULL
值(前提是該列沒有宣告NOT NULL
屬性),就像這樣:
mysql> INSERT INTO first_table VALUES(2, NULL); Query OK, 1 row affected (0.01 sec) mysql> mysql> SELECT * FROM first_table; +--------------+---------------+ | first_column | second_column | +--------------+---------------+ |1 | aaa| |2 | NULL| +--------------+---------------+ 2 rows in set (0.00 sec) mysql> 複製程式碼
值得注意的是,雖然這種資料插入語法很簡單,但是並不鼓勵使用,因為這種插入語法VALUES列表中的值高度依賴表中列的順序
,也就是說一旦表的結構改變,比方把first_column
和second_column
列的順序換一下,這種插入語句就不適用了。所以我們可以在書寫插入語句的時候就把列的順序規定好,就像這樣:
mysql> INSERT INTO first_table(first_column, second_column) VALUES (3, 'ccc'); Query OK, 1 row affected (0.00 sec) mysql> 複製程式碼
在這個語句中,我們顯式的指定了列的插入順序是(first_column, second_column)
,對應於VALUES
列表中的值的順序,也就是說first_column
與值3
對應,second_column
與值'ccc'
對應。之後即使first_table
表中列的結構改變了,這個語句仍然能繼續使用。我們也可以隨意指定列的插入順序,比如這樣:
mysql> INSERT INTO first_table(second_column, first_column) VALUES ('ddd', 4); Query OK, 1 row affected (0.01 sec) mysql> 複製程式碼
我們把second_column
放在了first_column
之前,所以VALUES
列表中的值也需要改變順序,來看一下插入效果:
mysql> SELECT * FROM first_table; +--------------+---------------+ | first_column | second_column | +--------------+---------------+ |1 | aaa| |2 | NULL| |3 | ccc| |4 | ddd| +--------------+---------------+ 4 rows in set (0.00 sec) mysql> 複製程式碼
插入記錄的一部分
我們在插入資料的時候,某些列的值可以被省略,但是這個列必須滿足下邊列出的某個條件之一:
- 該列允許儲存NULL值
- 該列有DEFAULT屬性,給出了預設值
我們定義的first_table
表中的兩個欄位都允許存放NULL
值,所以在插入資料的時候可以省略部分列的值。沒有顯式指定的列的值將被設定為NULL
,意思是還沒有指定值,比如這樣寫:
mysql> INSERT INTO first_table(first_column) VALUES(5); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO first_table(second_column) VALUES('fff'); Query OK, 1 row affected (0.00 sec) mysql> 複製程式碼
第一條插入語句我們只指定了first_column
列的值是5
,而沒有指定second_column
的值,所以second_column
的值就是NULL
;第二條插入語句我們只指定了second_column
的值是'ddd'
,而沒有指定first_column
的值,所以first_column
的值就是NULL
,也表示沒有資料~ 看一下現在表中的資料:
mysql> SELECT * FROM first_table; +--------------+---------------+ | first_column | second_column | +--------------+---------------+ |1 | aaa| |2 | NULL| |3 | ccc| |4 | ddd| |5 | NULL| |NULL | fff| +--------------+---------------+ 6 rows in set (0.00 sec) mysql> 複製程式碼
在使用這種方式插入資料時需要注意,
指定的列順序可以改變,但是一定要和VALUES
列表中的值一一對應起來
。其實如果把所有列都給出來的話,其實就相當於插入完整的記錄了。
批量插入記錄
每插入一條記錄寫一條語句也不是不行,但是對人來說太煩了,而且每插入一行資料提交一個請求給伺服器遠沒有一次把所有插入的資料提交給伺服器效率高,所以MySQL
為我們提供了批量插入的語句,就是直接在VALUES
後多加幾組值,每組值用小括號()
擴起來並用逗號分隔就好了,就像這樣:
mysql> INSERT INTO first_table(first_column, second_column) VALUES(7, 'ggg'), (8, 'hhh'); Query OK, 2 rows affected (0.00 sec) Records: 2Duplicates: 0Warnings: 0 mysql> 複製程式碼
我們在這個插入語句中插入了(7, 'ggg')
、(8, 'hhh')
這麼兩條記錄,直接把它們放到VALUES
後邊用逗號分開就好了,我們看一下插入效果:
mysql> SELECT * FROM first_table; +--------------+---------------+ | first_column | second_column | +--------------+---------------+ |1 | aaa| |2 | NULL| |3 | ccc| |4 | ddd| |5 | NULL| |NULL | fff| |7 | ggg| |8 | hhh| +--------------+---------------+ 8 rows in set (0.00 sec) mysql> 複製程式碼
將某個查詢結果集插入表中
上邊的插入語句都是我們顯式的將記錄的值放在VALUES
後邊,其實我們也可以將某個查詢結果作為資料來源插入到表中。我們先新建一個second_table
表:
mysql> CREATE TABLE second_table ( ->s VARCHAR(200), ->i INT -> ); Query OK, 0 rows affected (0.03 sec) mysql> 複製程式碼
這個表有兩個列,一個是VARCHAR
型別的s
列,另一個是INT
型別的i
列。現在這個second_table
表中是沒有資料的,我們想把first_column
表中的一些資料插入到second_table
表的話可以這麼寫:
mysql> INSERT INTO second_table(s, i) SELECT second_column, first_column FROM first_table WHERE first_column < 5; Query OK, 4 rows affected (0.00 sec) Records: 4Duplicates: 0Warnings: 0 mysql> 複製程式碼
這條語句可以分成兩條語句理解:
-
先執行查詢語句。
SELECT second_column, first_column FROM first_table WHERE first_column < 5; 複製程式碼
這條語句的結果集是
+---------------+--------------+ | second_column | first_column | +---------------+--------------+ | aaa|1 | | NULL|2 | | ccc|3 | | ddd|4 | +---------------+--------------+ 複製程式碼
-
把查詢語句得到的結果集插入到指定的表中。
把第1步中的到的結果集中的記錄批量插入到
second_table
表中,得到的結果就是:mysql> SELECT * FROM second_table; +------+------+ | s| i| +------+------+ | aaa|1 | | NULL |2 | | ccc|3 | | ddd|4 | +------+------+ 4 rows in set (0.00 sec) mysql> 複製程式碼
在將某個查詢的結果集插入到表中時需要注意,INSERT語句指定的列要和查詢列表中的列一一對應
。比方說上邊的INSERT語句指定的列是s, i
,對應於查詢語句中的second_column, first_column
。
插入或忽略
對於一些是主鍵或者具有唯一性約束的列或者列組合來說,它們不允許重複值的出現,比如我們把first_table
的first_column
列新增一個唯一性約束:
mysql> ALTER TABLE first_table MODIFY COLUMN first_column INT UNIQUE; Query OK, 0 rows affected (0.03 sec) Records: 0Duplicates: 0Warnings: 0 mysql> 複製程式碼
因為有了唯一性約束,所以如果插入的資料中first_column
列的值與已有的值重複的話就會報錯,比如這樣:
mysql> INSERT INTO first_table(first_column, second_column) VALUES(1, '哇哈哈'); ERROR 1062 (23000): Duplicate entry '1' for key 'first_column' mysql> 複製程式碼
我們在插入資料的時候又不知道表裡有沒有重複的記錄,所以我們現在想要一個這樣的效果:如果表中沒有重複的記錄,則插入,如果表中有重複的記錄,則忽略本次插入
。MySQL
給我們提供了INSERT IGNORE
的語法來實現這個功能:
mysql> INSERT IGNORE INTO first_table(first_column, second_column) VALUES(1, '哇哈哈') ; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> 複製程式碼
我們只是簡單的在INSERT
後邊加了個IGNORE
單詞便不再報錯了!對於批量插入的情況,INSERT IGNORE
同樣使用,它會把在具有唯一性約束列上沒有重複的記錄成功插入,把有重複記錄的忽略
,比如這樣:
mysql> INSERT IGNORE INTO first_table(first_column, second_column) VALUES(1, '哇哈哈'), (9, 'iii'); Query OK, 1 row affected, 1 warning (0.00 sec) Records: 2Duplicates: 1Warnings: 1 mysql> 複製程式碼
這個批量插入的語句中我們想插入(1, '哇哈哈')
和(9, 'iii')
這兩條記錄,因為first_column
列值為1
的記錄已經在表中存在,所以這個記錄會被忽略,而(9, 'iii')
這條記錄被插入成功,看插入效果:
mysql> SELECT * FROM first_table; +--------------+---------------+ | first_column | second_column | +--------------+---------------+ |1 | aaa| |2 | NULL| |3 | ccc| |4 | ddd| |5 | NULL| |NULL | fff| |7 | ggg| |8 | hhh| |9 | iii| +--------------+---------------+ 9 rows in set (0.01 sec) mysql> 複製程式碼
插入或更新
對於主鍵或者有唯一性約束的列或列組合來說,新插入的記錄如果和表中已有的記錄重複的話,我們可以選擇的策略不僅僅是忽略這次插入,我們也可以選擇更新這條重複的記錄。比如我們想在first_table
表中插入一條記錄,內容是(1, '哇哈哈')
,我們想要的效果是:如果表中沒有重複的記錄,則插入,如果表中有重複的記錄,則按照規定更新這些重複記錄中某些列的值
。MySQL給我們提供了INSERT ... ON DUPLICATE KEY UPDATE ...
的語法來實現這個功能:
INSERT INTO first_table (first_column, second_column) VALUES(1, '哇哈哈') ON DUPLICATE KEY UPDATE second_column = '雪碧'; 複製程式碼
這個語句的意思就是,對於要插入的資料(1, '哇哈哈')
來說,如果first_table
表中有某些重複的記錄,那就把記錄的second_column
列更新為'雪碧'
,看一下效果:
mysql> SELECT * FROM first_table; +--------------+---------------+ | first_column | second_column | +--------------+---------------+ |1 | 雪碧| |2 | NULL| |3 | ccc| |4 | ddd| |5 | NULL| |NULL | fff| |7 | ggg| |8 | hhh| |9 | iii| +--------------+---------------+ 9 rows in set (0.00 sec) mysql> 複製程式碼
如果我們在遇到記錄後想更新的值就是準備插入的記錄中的值,比如這樣:
INSERT INTO first_table (first_column, second_column) VALUES(1, '哇哈哈') ON DUPLICATE KEY UPDATE second_column = '哇哈哈'; 複製程式碼
我們想插入的記錄的second_column
列的值是'哇哈哈'
,如果有重複記錄後對second_column
列想更新的值也是'哇哈哈'
,那我們可以用VALUES(列名)
的形式來替代顯式把值寫出來的形式:
mysql> INSERT INTO first_table (first_column, second_column) VALUES(1, '哇哈哈') ON DUPLICATE KEY UPDATE second_column = VALUES(second_column); Query OK, 2 rows affected (0.00 sec) mysql> 複製程式碼
VALUES(second_column)
就代表著要準備插入的記錄中second_column
的值,本例中就是'哇哈哈'
。這種形式在批量插入或更新中更重要:
mysql> INSERT INTO first_table (first_column, second_column) VALUES(2, '紅牛'), (3, '橙汁兒') ON DUPLICATE KEY UPDATE second_column = VALUES(second_column); Query OK, 4 rows affected (0.00 sec) Records: 2Duplicates: 2Warnings: 0 mysql> 複製程式碼
我們準備批量插入兩條記錄(2, '紅牛')
和(3, '橙汁兒')
,在遇到重複記錄時把該重複記錄的second_column
列更新成準備插入的記錄中的值就好了,所以效果是這樣:
mysql> SELECT * FROM first_table; +--------------+---------------+ | first_column | second_column | +--------------+---------------+ |1 | 哇哈哈| |2 | 紅牛| |3 | 橙汁兒| |4 | ddd| |5 | NULL| |NULL | fff| |7 | ggg| |8 | hhh| |9 | iii| +--------------+---------------+ 9 rows in set (0.00 sec) mysql> 複製程式碼
刪除資料
如果某些記錄我們不想要了,可以刪掉的,語法就是這樣:
DELETE FROM 表名 [WHERE 布林表示式]; 複製程式碼
我們把first_table
中first_column
的值大於4
的記錄都刪掉看看:
mysql> DELETE FROM first_table WHERE first_column > 4; Query OK, 4 rows affected (0.00 sec) mysql> 複製程式碼
其中的Query OK, 4 rows affected (0.00 sec)
表名成功的刪除了4條記錄,然後看一下刪除效果:
mysql> SELECT * FROM first_table; +--------------+---------------+ | first_column | second_column | +--------------+---------------+ |1 | 哇哈哈| |2 | 紅牛| |3 | 橙汁兒| |4 | ddd| |NULL | fff| +--------------+---------------+ 5 rows in set (0.00 sec) mysql> 複製程式碼
first_column
大於4
的記錄就都不見了哈~ 當然刪除語句的WHERE
子句是可選的,如果不加WHERE
子句的話,意味著刪除表中所有資料,比如我們想清除second_table
表中的所有資料,可以這麼寫:
mysql> DELETE FROM second_table; Query OK, 4 rows affected (0.01 sec) mysql> 複製程式碼
不過在使用刪除語句需要特別特別注意:記錄被刪除之後就非常難恢復了,所以使用刪除語句時需要十分慎重!另外,雖然刪除語句的WHERE條件是可選的,但是如果不加WHERE條件的話將刪除所有的記錄,這是玩火的行為!超級危險!十分危險!請慎重使用 。
更新資料
有時候對於某些記錄的某些列的值不滿意,我們可以去修改它們,我們需要指定更改哪張表中的哪些記錄以及具體的修改內容,語法就是這樣:
UPDATE 表名 SET 列1=值1, 列2=值2, ...,列n=值n [WHERE 布林表示式]; 複製程式碼
凡是滿足布林表示式
的行都會被更新,你想更新哪些列的值,就把它們寫到SET
單詞後邊,如果想更新多個列的話,它們之間用逗號,
分隔開。比如我們把first_table
表中first_column
的值是NULL
的記錄的first_column
的值更新為5
,second_column
的值更新為'乳娃娃'
,可以這麼寫:
mysql> UPDATE first_table SET first_column = 5, second_column = '乳娃娃' WHERE first_column IS NULL; Query OK, 1 row affected (0.01 sec) Rows matched: 1Changed: 1Warnings: 0 mysql> 複製程式碼
Query OK, 1 row affected (0.01 sec)
就表明成功更新了1行資料。Rows matched: 1
表示符合WHERE
條件的記錄一共有1條,Changed: 1
表示有1條記錄的內容發生了變化。我們看一下修改後的效果:
mysql> SELECT * FROM first_table; +--------------+---------------+ | first_column | second_column | +--------------+---------------+ |1 | 哇哈哈| |2 | 紅牛| |3 | 橙汁兒| |4 | ddd| |5 | 乳娃娃| +--------------+---------------+ 5 rows in set (0.00 sec) mysql> 複製程式碼
在使用更新語句也需要特別特別注意:雖然更新語句的WHERE條件是可選的,但是如果不加WHERE條件的話將更新所有的記錄,這是玩火的行為!超級危險!十分危險!請慎重使用 。
總結
-
使用
INSERT
語句來向表中插入資料,可以使用這兩種方式:-
不指定需要插入資料的列:
INSERT INTO 表名 VALUES(列1的值,列2的值, ..., 列n的值); 複製程式碼
這種方式高度依賴表中列的順序,不推薦使用。
-
顯式指定需要插入資料的列
INSERT INTO 表名(列1, 列2, ..., 列n) VALUES(列1的值,列2的值, ..., 列n的值); 複製程式碼
推薦使用這種方式進行插入,在表結構允許的情況下還可以只對部分列進行插入。
-
-
直接在
VALUES
後多加幾組值,每組值用小括號()擴起來並用逗號分隔就好了就是批量插入語句。 -
對於主鍵或者有唯一性約束的列或列組合來說,新插入的記錄如果和表中已有的記錄重複的話,我們可以選擇下邊這兩種插入策略:
-
插入或忽略
使用
INSERT IGNORE
語法,如果表中沒有重複的記錄,則插入,如果表中有重複的記錄,則忽略本次插入。 -
插入或更新
使用
INSERT ... ON DUPLICATE KEY UPDATE ...
語法,如果表中沒有重複的記錄,則插入,如果表中有重複的記錄,則按照規定更新這些重複記錄中某些列的值。
-
-
刪除記錄的語法很簡單:
DELETE FROM 表名 [WHERE 布林表示式]; 複製程式碼
-
更新記錄的語法也很簡單:
UPDATE 表名 SET 列1=值1, 列2=值2, ...,列n=值n [WHERE 布林表示式]; 複製程式碼