天天看點

如何插入? | 非開車,純技術交流

《InnoDB自增鍵基礎知識測試》

中的四道測試題,全答對的朋友少之又少,為了講清楚InnoDB自增鍵,今天先系統性講講,什麼是插入,如何插入。 MySQL有一系列的語句,可以往資料庫新增資料,稱作範插入語句(insert-like statement)。不同的插入方式,對自增鍵的影響是不一樣的。畫外音:自增鍵,是指auto_increment,大家應該都用得很多。 更為細化後,總的來說,插入方式分為三類:

  • 簡單插入(simple insert)
  • 批量插入(bulk insert)
  • 混合插入(mixed-mode insert)

 什麼是簡單插入(simple insert)?普通的insert/replace語句,不管是單條插入還是多條插入,都是簡單插入。畫外音:(1)不包含遞歸的子查詢;(2)不包含insert … on duplicate key update… ; 如

《自增鍵測試》

裡的實驗一:

insert into t1(id, name) values(1,"shenjian");

insert into t1(name) values("zhangsan"),("lisi"),("ww");

都是簡單插入。 簡單插入的特點是,能夠提前知道被插入的行數。 是以,這類插入,在處理自增鍵時,是最容易的。畫外音:很容易保證自增鍵連續性。 什麼是批量插入(bulk insert)?與簡單插入相對,在插入時,不知道被插入的行數,是批量插入。 如

裡的實驗二:

insert into t1(name) select name from t2;

 除此之外,像:

  • replace … select …
  • load data

都是批量插入。 由于不能夠提前知道多少行插入,在處理自增列時,每插入一行,才會指派新的自增值。畫外音,官網原文是:

InnoDB assigns new values for the AUTO_INCREMENT column one at a time as each row is processed.

 這裡的潛台詞是,在批量插入事務并發時,“可能”出現同一個事務的自增鍵不連續。畫外音:為啥是“可能”呢?潛在解決方案,未來撰文詳述。 什麼是混合插入(mixed-mode insert)?如

裡的實驗三:

insert into t1(id, name) values (111,"111"),(NULL, "abc"),(222,"222"),(NULL,"xyz");

 有些行插入時指定了自增鍵,無需資料庫生成;有些行插入時未指定自增鍵(NULL),需要資料庫生成。畫外音:具體走哪個分支,實際執行時才知道。 以及

裡實驗四:

insert into t1(name) values("shenjian"),("aaa"),("bbb")

on duplicate key update count=100;

 有些行插入實際上是修改,無需資料庫生成自增鍵;有些行插入實際上就是插入,需要資料庫生成自增鍵。畫外音:具體走哪個分支,也是實際執行時才知道。 insert … on duplicate key update … 這種情況是最最複雜的,它可能導緻,系統生成的自增值,在更新階段用不上。畫外音,官網原文是:

an INSERT followed by a UPDATE, where the allocated value for the AUTO_INCREMENT column may or may not be used during the update phase.

 說了這麼多,

中的四道測試題,大家心中都有譜了吧?看完本文,是不是解答了四道題的疑問呢?畫外音:昨天确實答對率比較低,今天可以再回過頭重新做一遍。 末了,最近罵我的水友比較多,回報幫朋友推廣的文章越來越多了,我統一回複下:(1)精力有限,平均每周産出2-3篇技術文的頻率沒有降低;(2)朋友讓我幫忙,我幫還是不幫?(3)我的地盤我做主; 另外||| 在這裡,能有機會系統性思考,之前沒有想過的問題。畫外音:當然,我隻能分享和引導,收獲有多大,得看大夥細節扣得多深。就像昨天和今天的兩篇,“自增鍵”和“插入”誰都會用,但真的思考過這些“coding時用不到”的看似無用的知識麼。 在這裡,你能看到别處沒有的技術文章。畫外音:(1)文章原創;(2)以“戲谑”的文筆“踏實”的做學問:素材可以複現,絕不“張口就來”;知識點親自考證,要麼官網,要麼源碼,絕不傳播樓主不确定的二手消息;

最後,再挖兩個坑,大夥想想。

 作業題一:insert into t1(name)values("zhangsan"),("lisi"),("wangwu");這類簡單插入,當有并發事務執行時,自增鍵仍能保證連續性,是如何做到的?A: 行粒度加鎖,實施互斥B: 表粒度加鎖,實施互斥C: 全局自增鍵單例,實施互斥D: SQL語句粒度加鎖,實施互斥E: 事務粒度加鎖,實施互斥 作業題二:基于SQL複制的主從同步,如果執行并發批量插入(bulk insert)事務,“可能”出現同一個事務的自增鍵不連續,那麼能否保證主從資料的一緻性?如果能,是怎麼保證的?

本文轉自“架構師之路”公衆号,58沈劍提供。