
主鍵 id 用自增和 uuid 有什麼差別?
● uuid 有 16 個位元組,比 int(4 byte)和 bigint(8 byte)占用更多存儲空間
有大量資料的時候 uuid 主鍵不會像自增主鍵那樣越界,如果使用自增 id,字段類型一般選擇 bigint
● 如果 InnoDB 表的資料寫入順序能和 B + 樹索引的葉子節點順序一緻的話,這時候存取效率是最高的,uuid 由于無序性,插入和查詢比自增主鍵差
● uuid 做主鍵相對安全,不能簡單的從 uuid 擷取資訊,但是如果自增,則容易暴露資訊,如果一個客戶 id 是 123456,很容易猜到有客戶 id 是 123456
● uuid 保證資料在表和庫都是獨立的,有利于處理分布式存儲的資料表
uuid 主要解決的是分布式生成唯一編号的問題,但是不一定非要用現有的 uuid 方法,可以把每個機器都編個号,這樣機器号加自增 id 也是一種 uuid
主鍵自增 id 衍生問題
Ⅰ、初始 3 條資料,最大 id 是 3
Ⅱ、delete 第 3 條資料
Ⅲ、insert 一條資料
我們可以看到主鍵 id 不連續,MySQL innodb 表的自增變量的值是記憶體中的臨時值
● 删除指令:
針對整張表資料(保留表結構)的删除,可以使用 DELETE 或者 TRUNCATE,二者的差別如下:
① TRUNCATE 在各種表上無論是大的還是小的都非常快。如果有 ROLLBACK 指令 DELETE 将被撤銷,而 TRUNCATE 則不會被撤銷
② TRUNCATE不能進行復原操作,DELETE 語句執行删除的過程是每次從表中删除一行,并且同時将該行的的删除操作作為事務記錄在日志中儲存以便進行進行復原操作
③ 當表被 TRUNCATE 後,這個表和索引所占用的空間會恢複到初始大小,而 delete 操作不會減少表或索引所占用的空間
④ 不能 TRUNCATE 一個帶有外鍵的表,如果要删除首先要取消外鍵,然後再删除
⑤ TRUNCATE 全表後,主鍵自增 id 會重新從 1 開始,而 delete 全表後自增 id 不從 1 開始
● 面試題 Ⅰ
如果 DELETE 第 3 行資料後,MySql 服務挂了,手動重新開機 MySql 服務,請問在 InnoDB 和 MyISAM 存儲引擎中,新增一條資料,自增 id 的值是 3 還是 4?
MyISAM 引擎:MyISAM 表會把自增主鍵的最大 ID 記錄到資料檔案裡,重新開機 MySQL 自增主鍵的最大 ID 也不會丢失。
InnoDB 引擎:InnoDB 表把自增主鍵的最大 ID 記錄到記憶體中,重新開機資料庫後,都會導緻最大自增 ID 重置。當我們執行 insert 操作的時候,MySQL 會預設擷取到自增長的最大值,類似于使用
SELECT MAX(id) FROM student FOR UPDATE; 然後再 + 1
是以說正确答案選 C
注意:在 MySql 8.0 版本中新增特性,「 自增主鍵持久化 」
将自增主鍵的計數器持久化到 redo log 中。每次計數器發生改變,都會将其寫入到 redo log 中。如果資料庫發生重新開機,InnoDB 會根據 redo log 中的計數器資訊來初始化其記憶體值。為了盡量減小對系統性能的影響,計數器寫入到 redo log 中,并不會馬上重新整理。
● 面試題 Ⅱ
主鍵 id 不連續的解決辦法(假設主鍵 id 與其他表無關聯)
① 去掉 id 主鍵自增
② 增加一列 idd 作為主鍵,設定為自動遞增
③ 讓 id 列從 1 開始自增
④ 删除idd
⑤ 将 id 重新設定為主鍵,加上自動遞增
>>>Python 之 MySql“未解之謎”10--我以為我很懂MySql索引(下)