Mysql replace into注意事項
什麼時候使用replace into
在向表中插入資料的時候,經常遇到這樣的情況:1. 首先判斷資料是否存在; 2. 如果不存在,則插入;3.如果存在,則更新。
在 SQL Server 中可以這樣處理:
if not exists (select 1 from t where id = 1)
insert into t(id, update_time) values(1, getdate())
else
update t set update_time = getdate() where id = 1
那麼 mysql 中如何實現這樣的邏輯呢?彆著急 mysql中有更簡單的方法: replace into
replace into t(id, update_time) values(1, now());
或
replace into t(id, update_time) select 1, now();
replace into原理
replace into 跟 insert 功能類似,不同點在於:replace into 首先嚐試插入資料到表中,
如果發現表中已經有此行資料(根據主鍵或者唯一索引判斷)則先刪除此行資料,然後插入新的資料。 2. 否則沒有此行資料的話,直接插入新資料。
replace into的應用注意事項
1)插入資料的表必須有主鍵或者是唯一索引!否則的話,replace into 會直接插入資料,這將導致表中出現重複的資料。
2)如果資料庫裡邊有這條記錄,則直接修改這條記錄;如果沒有則,則直接插入,在有外來鍵的情況下,對主表進行這樣操作時,因為如果主表存在一條記錄,被從表所用時,直接使用replace into是會報錯的,這和replace into的內部原理是相關(ps.它會先刪除然後再插入)。
3)正確做法是- 即先刪除該條存在的資料,然後再次插入這條資料,這和外來鍵約束相悖呢,因此只能採用update和insert這樣的組合,來應對外來鍵約束
sql_select_1='''select * from one_and_two_stars where kn_id = %d ''' %( int(one_level_id))
res_num_1= self.execute_kg(sql_select_1)
if res_num_1 > 0:
# 修改該條記錄
sql_update_one_and_two_stars
self.execute_kg(sql_update_one_and_two_stars)
self.commit_kg()
else:
# 直接插入這條資料
sql_insert_one_and_two_stars= '''insert into one_and_two_stars(kn_id,kn_name,parent_kn_id,ctime)
values('%s','%s','%s','%s')
''' % (str(one_level_id), str(kn_name_1),str(parent_kn_id_1),str(dt))
self.execute_kg(sql_insert_one_and_two_stars)
self.commit_kg()
replace into的使用形式
MySQL replace into 有三種形式:
1) replace into tbl_name(col_name, ...) values(...)
2) replace into tbl_name(col_name, ...) select ...
3) replace into tbl_name set col_name=value, ...
前兩種形式用的多些。其中 “into” 關鍵字可以省略,不過最好加上 “into”,這樣意思更加直觀。另外,對於那些沒有給予值的列,MySQL 將自動為這些列賦上預設值。
語法:replace into table( col1, col2, col3 ) values ( val1, val2, val3 )語義:向table表中col1, col2, col3列replace資料val1,val2,val3
先講講組合(多列)索引是什麼
組合索引的生效原則是 從前向後依次生效,如果中間某個索引沒有使用, 那麼斷點前面的索引部分起作用,斷點後面的索引沒有起作用,即最左優先原則
例如建立多列索引(a,b,c)
where a=3 and b=45 and c=5...
這種三個索引順序使用中間沒有斷點,全部發揮作用;
where a=3 and c=5...
這種情況下b就是斷點,a發揮了效果,c沒有效果;
where b=3 and c=4...
這種情況下a就是斷點,在a後面的索引都沒有發揮作用,這種寫法聯合索引沒有發揮任何效果;
where b=45 and a=3 and c=5...
這個跟第一個一樣,全部發揮作用,abc只要用上了就行,跟寫的順序無關;
如何建立組合索引
語法:CREATE UNIQUE INDEX index ON table( col1, col2, col3 )
例項:CREATE UNIQUE INDEX index_unique ON app(pkgName,version,device,osver)
很簡單是不是,但是我還是遇到了兩個坑,浪費了我一下午,第一個坑就是建立的索引長度是有限制的,不能超過767,發現欄位的長度也用不了varchar(256)於是改成了varchar(100)。
你以為這樣就OK了,NAIVE!第二個坑,“error: Duplicate etry ~”,英文不好真的很費勁,我翻譯出來“重複例項”,卻還是沒能理解是什麼意思,還一味的排除sql語句的錯誤。。。直到逛了外網論壇才發現是表的問題,因為在建立這個唯一索引的時候表中已經有很多重複資料了,所以很肯定建立不成功!
清空表資料,完美。。。