mysql優化之-增刪改具體分析(圖)
插入
將多行查詢結果插入到表中
語法
INSERT?INTO?table_name1(column_list1)?SELECT?(column_list2)?FROM?table_name2?WHERE?(condition)
table_name1指定待插入數據的表;column_list1指定待插入表中要插入數據的哪些列;table_name2指定插入數據是從
哪個表中查詢出來的;column_list2指定數據來源表的查詢列,該列表必須和column_list1列表中的字段個數相同,數據類型相同;
condition指定SELECT語句的查詢條件
從person_old表中查詢所有的記錄,并將其插入到person表
CREATE?TABLE?person?( ??id?INT?UNSIGNED?NOT?NULL?AUTO_INCREMENT, ??NAME?CHAR(40)?NOT?NULL?DEFAULT?'', ??age?INT?NOT?NULL?DEFAULT?0, ??info?CHAR(50)?NULL, ??PRIMARY?KEY?(id) ) CREATE?TABLE?person_old?( ??id?INT?UNSIGNED?NOT?NULL?AUTO_INCREMENT, ??NAME?CHAR(40)?NOT?NULL?DEFAULT?'', ??age?INT?NOT?NULL?DEFAULT?0, ??info?CHAR(50)?NULL, ??PRIMARY?KEY?(id) ) INSERT?INTO?person_old VALUES?(11,'Harry',20,'student'),(12,'Beckham',31,'police') SELECT?*?FROM?person_old
?可以看到,插入記錄成功,person_old表現在有兩條記錄。接下來將person_oldperson_old表中的所有記錄插入到person表
INSERT?INTO?person(id,NAME,age,info) SELECT?id,NAME,age,info?FROM?person_old; SELECT?*?FROM?person
可以看到數據轉移成功,這里的id字段為自增的主鍵,在插入時要保證該字段值的唯一性,如果不能確定,可以插入的時候忽略該字段,
只插入其他字段的值
如果再執行一次就會出錯
?
MYSQL和SQLSERVER的區別:
區別一
當要導入的數據中有重復值的時候,MYSQL會有三種方案
方案一:使用 ignore 關鍵字
方案二:使用 replace into
方案三:ON DUPLICATE KEY UPDATE
第二和第三種方案這里不作介紹,因為比較復雜,而且不符合要求,這里只講第一種方案
TRUNCATE?TABLE?person TRUNCATE?TABLE?persona_old? INSERT?INTO?person_old VALUES?(11,'Harry',20,'student'),(12,'Beckham',31,'police') ##注意下面這條insert語句是沒有ignore關鍵字的 INSERT??INTO?person(id,NAME,age,info) SELECT?id,NAME,age,info?FROM?person_old; INSERT?INTO?person_old? VALUES?(13,'kay',26,'student') ##注意下面這條insert語句是有ignore關鍵字的 INSERT?IGNORE?INTO?person(id,NAME,age,info) SELECT?id,NAME,age,info?FROM?person_old;
?
可以看到插入成功
SQLSERVER
在SQLSERVER這邊,如果要忽略重復鍵,需要在建表的時候指定?WITH (IGNORE_DUP_KEY=ON) ON [PRIMARY]?
這樣在插入重復值的時候,SQLSERVER第一次會保留值,第二次發現有重復值的時候,SQLSERVER就會忽略掉
區別二
插入自增列時的區別
SQLSERVER需要使用?SETIDENTITY_INSERT 表名ON?才能把自增字段的值插入到表中,如果不加?SET?IDENTITY_INSERT?表名?ON?
則在插入數據到表中時,不能指定自增字段的值,則id字段不能指定值,SQLSERVER會自動幫你自動增加一
INSERTINTO?person(NAME,age,info)?VALUES?('feicy',33,'student')
而MYSQL則不需要,而且自由度非常大
你可以將id字段的值指定為NULL,MYSQL會自動幫你增一
INSERTINTO?person(id,NAME,age,info)?VALUES?(NULL,'feicy',33,'student')
也可以指定值
INSERT?IGNORE?INTO?person(id,NAME,age,info)?VALUES?(16,'tom',88,'student')
也可以不寫id的值,MYSQL會自動幫你增一
INSERT?IGNORE?INTO?person(NAME,age,info)?VALUES?('amy',12,'bb')
你可以指定id字段的值也可以不指定,指定的時候只要當前id字段列沒有你正在插入的那個值就可以,即沒有重復值就可以
自由度非常大,而且無須指定?SET?IDENTITY_INSERT?表名?ON?選項
區別三
唯一索引的NULL值重復問題
MYSQL
在MYSQL中UNIQUE 索引將會對null字段失效
insert?into?test(a)?values(null) ? insert?into?test(a)?values(null)
上面的插入語句是可以重復插入的(聯合唯一索引也一樣)
SQLSERVER
SQLSERVER則不行
CREATE?TABLE?person?( ??id?INT??NOT?NULL?IDENTITY(1,1), ??NAME?CHAR(40)??NULL?DEFAULT?'', ??age?INT?NOT?NULL?DEFAULT?0, ??info?CHAR(50)?NULL, ??PRIMARY?KEY?(id) ) CREATE?UNIQUE?INDEX?IX_person_unique?ON?[dbo].[person](name) INSERT?INTO?[dbo].[person] ????????(?[NAME],?[age],?[info]?) VALUES??(?NULL,?--?NAME?-?char(40) ??????????1,?--?age?-?int ??????????'aa'??--?info?-?char(50) ??????????), ??????????(?NULL,?--?NAME?-?char(40) ??????????2,?--?age?-?int ??????????'bb'??--?info?-?char(50) ??????????)
消息?2601,級別?14,狀態?1,第?1?行 不能在具有唯一索引“IX_person_unique”的對象“dbo.person”中插入重復鍵的行。重復鍵值為?(<null>)。 語句已終止。</null>
更新
更新比較簡單,就不多說了
UPDATE?person?SET?info?='police'?WHERE?id?BETWEEN?14?AND?17 SELECT?*?FROM?person
刪除
刪除person表中一定范圍的數據
DELETE?FROM??person??WHERE?id?BETWEEN?14?AND?17 SELECT?*?FROM?person
如果要刪除表的所有記錄可以使用下面的兩種方法
##方法一 DELETE?????FROM?person ##方法二 TRUNCATE?TABLE??person
跟SQLSERVER一樣,TRUNCATE TABLE會比DELETE FROM TABLE 快
MYISAM引擎下的測試結果,30行記錄
跟SQLSERVER一樣,執行完TRUNCATE TABLE后,自增字段重新從一開始。
################################ INSERT?IGNORE?INTO?person(id,NAME,age,info) SELECT?id,NAME,age,info?FROM?person_old; SELECT?*?FROM?person TRUNCATE?TABLE??person INSERT?IGNORE?INTO?person(NAME,age,info)?VALUES?('amy',12,'bb') SELECT?*?FROM?person
當你剛剛truncate了表之后執行下面語句就會看到重新從一開始
SHOW?TABLE?STATUS?LIKE?'person'