一個常見操作是插入一個新行(如果不存在或更新現有行)。不幸的是,插入和更新SQL語句的語法是完全不同的:Insert獲取一列後接相應的值列表,而更新獲取列=值對的列表。 MySQL「insert ... on duplicate key update」語句(它的upsert語句)不能解決這個問題,因爲它仍然需要完整的插入列/值列表,然後是完整的更新列/值列表。 [更新:來自Wrikken的評論指出,這兩個語句可以共享column = value語法,但其他問題仍然存在。]簡化MySQL中的更新/插入(upsert)處理
與此問題相關的是,如果您使用觸發器來檢查數據我需要),你需要兩個觸發器(before-insert和before-update),並且,因爲他們必須使用「new」限定符,所以你必須寫兩次檢查代碼,每次觸發一次,或者把它放入程序。如果您使用過程,則必須將每列作爲單獨參數傳遞,因爲該過程不能使用「新」,如果您有很多列,則很可能會出現容易出錯的輸入。每一列必須在create table語句中具有其類型,然後再次在檢查過程的定義中。一旦出現一點小錯誤,你創建了一個微妙的,難以發現的錯誤。我不喜歡任何涉及兩次編碼同一事物的方法。 (它的非正常化的等價物)
這個插入/更新問題的思考,我一直在玩弄以下的想法,我想一些反饋,特別是如果任何人真正嘗試過:
僅對佔位符行使用插入,僅保留最少量的數據以及獲取或設置主鍵。然後,將所有用戶輸入的數據放入更新語句中。現在,您不需要「插入...重複密鑰更新」,就像純更新一樣。此外,您只需在更新前觸發器上檢查數據,因爲沒有任何內容需要檢查。 (來自輸入表格的所有用戶提供的數據都由更新處理,而不是由插入處理。)
該方法的主要缺點當然是對於新行有兩個操作:插入後跟更新,而不是插入。但是,這可能不是一個因素,因爲:
插入可能比較少見。例如,在幾年前我爲Richardson(TX)學區做過的學生評分申請中,每年只增加幾千名學生,而成千上萬的更新,因爲老師使用系統在整個學年。
在我創建的其他系統中,性能無關緊要。例如,我正在處理的當前系統只有兩三個人每週只更新數據庫幾個小時。負載非常小,以至於只有一個操作就足夠了,兩個操作(insert + update)引起的開銷不大。 (這僅適用於新行,切記。)
那麼,有沒有人真正嘗試這樣的:插入只有創造簡約的佔位符行,併爲所有用戶提供的數據更新使用更新?
你知道'INSERT INTO tablename SET col1 = 1,col2 = 2' ...等是否有效?我還沒有找到寫一個查詢只是一個累贅... – Wrikken
http://dev.mysql.com/doc/refman/5.5/en/insert.html – jchapa
感謝您指出這一點。在PHP中,如果賦值被組合爲一個字符串,那麼該字符串可以在兩個地方的「insert ... on duplicate key」語句中使用,這有點幫助。但是,需要兩個觸發器仍然存在。我的想法仍然只允許一個觸發器,這大大簡化了觸發器編碼。想法呢? –