當進行 加列操作 時,所有的資料行 都必須要 增加一段資料(圖中的 列 4 資料)
如上一期**所講,當改變資料行的長度,就需要 重建表空間(圖中灰藍的部分為發生變更的部分)
資料字典中的列定義也會被更新
以上操作的問題在於 每次加列 操作都需要重建表空間,這就需要大量 io以及大量的時間
立刻加列
"立刻加列" 的過程如下圖:
輸入描述
輸入描述
"立刻加列" 時,只會變更資料字典中的內容,包括:
在列定義中增加 新列的定義
增加 新列的預設值
"立刻加列" 後,當要讀取表中的資料時:
由於 "立刻加列" 沒有 變更行資料,讀取的行資料只有 3 列
mysql 會將 新增的第 4 列的預設值,追加到 讀取的資料後
以上過程描述了 如何讀取 在 "立刻加列" 之前寫入的資料,其實質是:在讀取資料的過程中,"偽造" 了乙個新列出來
那麼如何讀取 在 "立刻加列" 之後 寫入的資料呢 ? 過程如下圖:
當讀取 行 4 時:
輸入描述
輸入描述
通過判斷 資料行的頭資訊中的instant 標誌位,可以知道該行的格式是 "新格式":該行頭資訊後有乙個新字段 "列數"
通過讀取 資料行的 "列數" 字段,可以知道 該行資料中多少列有 "真實" 的資料,從而按列數讀取資料
通過上圖可以看到:讀取 在"立刻加列" 前/後寫入的資料是不同的流程
通過以上的討論,我們可以總結 "立刻加列" 之所以高效的原因是:
在執行 "立刻加列" 時,不變更資料行的結構
讀取 "舊" 資料時,"偽造" 新增的列,使結果正確
寫入 "新" 資料時,使用了新的資料格式(增加了instant標誌位 和 "列數" 字段),以區分新舊資料
讀取 "新" 資料時,可以如實讀取資料
那麼 我們是否能一直 "偽造" 下去 ? "偽造" 何時會被拆穿 ?
考慮以下場景:
用 "立刻加列" 增加列 a
寫入資料行 1
用 "立刻加列" 增加列 b
寫入資料行 2
刪除列 b
我們推測一下 "刪除列 b" 的最小代價:需要修改 資料行中的instant標誌位或 "列數" 字段,這至少會影響到 "立刻加列" 之後寫入的資料行,成本類似於重建資料
從以上推測可知:當出現 與 "立刻加列" 操作不相容 的 ddl 操作時,資料表需要進行重建,如下圖所示:
輸入描述
輸入描述
使用限制
在了解原理之後,我們來看看 "立刻加列" 的使用限制,就很容易能理解其中的前兩項:
"立刻加列" 的加列位置只能在表的最後,而不能加在其他列之間
在元資料中,只記錄了 資料行 應有多少列,而沒有記錄 這些列 應出現的位置。所以無法實現指定列的位置
"立刻加列" 不能新增主鍵列
加列 不能涉及聚簇索引的變更,否則就變成了 "重建" 操作,不是 "立刻" 完成了
"立刻加列"不支援壓縮的**式
按照 wl 的說法:"compressed is no need to supported"(沒必要支援不怎麼用的格式)
總結回顧
我們總結一下上面的討論:
"立刻加列" 之所以高效的原因是:
在執行 "立刻加列" 時,不變更資料行的結構
讀取 "舊" 資料時,"偽造" 新增的列,使結果正確
寫入 "新" 資料時,使用了新的資料格式 (增加了 instant 標誌位 和 "列數" 字段),以區分新舊資料
讀取 "新" 資料時,可以如實讀取資料
"立刻加列" 的 "偽造" 手法,不能一直維持下去。當發生 與 "立刻加列" 操作不相容 的 ddl 時,表資料就會發生重建
回到之前遺留的兩個問題:
"立刻加列" 是如何工作的 ?
我們已經解答了這個問題
所謂 "立刻加列" 是否完全不影響業務,是否是真正的 "立刻" 完成 ?
可以看到:就算是 "立刻加列",也需要變更 資料字典,那麼 該上的鎖還是逃不掉的。也就是說 這裡的 "立刻" 指的是 "不變更資料行的結構",而並非指 "零成本地完成任務"
MySQL 新增列,修改列,刪除列
alter table 新增,修改,刪除表的列,約束等表的定義。sp rename sqlserver 內建的儲存過程,用與修改表的定義。mysql 檢視約束,新增約束,刪除約束 新增列,修改列,刪除列 sp rename sqlserver 內建的儲存過程,用與修改表的定義。先刪除主鍵 alter...
mysql 新增列,修改列,刪除列
原文 示例 alter table tb financial modify create time datetime 3 default null comment 錄入時間 alter table 新增,修改,刪除表的列,約束等表的定義。sp rename sqlserver 內建的儲存過程,用與修...
mysql 新增列,修改列,刪除列
alter table 新增,修改,刪除表的列,約束等表的定義。檢視列 desc 表名 修改表名 alter table old table rename to new table 新增列 alter table 表名 add column 列名 varchar 30 刪除列 alter table...