這樣會(huì)默認(rèn)在表的最后增加一個(gè)auth字段,如果你想在開(kāi)頭添加,你可以這樣寫(xiě):
為霞山等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及霞山網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè)、霞山網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!
在中間增加:
語(yǔ)法:
以上,如有紕漏,歡迎指正。
你如果想要給表增加一個(gè)字段,那么有很多種方法可以完成,比如說(shuō)直接add一個(gè)字段在add的后面寫(xiě)上字段的名稱和屬性。
1. GCS行格式
需要在innodb中實(shí)現(xiàn)類似oracle的快速加字段功能,僅僅基于原來(lái)的行格式是不行的,必須對(duì)其進(jìn)行擴(kuò)展。為了保證原MySQL和innodb的兼容性,不改變?cè)鎯?chǔ)格式的行為,在線加字段功能是通過(guò)新增一種innodb行格式GCS(Game Cloud Storage)來(lái)實(shí)現(xiàn),從而避免對(duì)其他格式造成影響。
雖然說(shuō)是新增格式,但該格式與原默認(rèn)的compact是基本一樣的,只是新增了關(guān)鍵的Field Count(字段數(shù))控制信息。
下面先回顧下compact行格式
Record Extra Bytes:是固定的5字節(jié),表示記錄的額外信息。
Nullable Bitmap:記錄可空位圖,使用1個(gè)bit來(lái)表示一個(gè)可空字段是否為NULL。
non-NULL Variable-Length Array:非空變長(zhǎng)字段數(shù)組,表示非空變長(zhǎng)字段(如varchar、varbinary)在該行的長(zhǎng)度。
關(guān)于Compact格式的詳細(xì)介紹可以參考文章。
compact格式有很重要的兩個(gè)特點(diǎn):
●字段的定義順序與存儲(chǔ)順序基本一致(主鍵除外)
●字段為NULL不占存儲(chǔ)空間,只需通過(guò)Nullable Bitmap記錄。
基于以上特點(diǎn),實(shí)現(xiàn)快速加字段功能GCS格式只需在記錄頭添加Field Count(字段數(shù)),來(lái)表示當(dāng)前記錄的字段數(shù),占用1~2字節(jié)(若大于127,則使用2字節(jié))
那么,解析GCS記錄的關(guān)鍵邏輯就變?yōu)椋?/p>
假設(shè)某GCS記錄的Field count記錄為x,表字段數(shù)為y,那么x = y總是成立的。對(duì)于GCS格式,字段的解析變?yōu)椋?/p>
●如果x == y或非GCS格式,按原來(lái)compact方式解析
●如果x y,那么記錄必定是在Alter Table加字段前就生成,那么最后y-x個(gè)字段必為NULL或默認(rèn)值。
●如果該字段是允許為NULL,則為NULL。
●如果該字段不允許為NULL,則為默認(rèn)值。
這樣就可以將新增的字段解析出來(lái)。
另外,GCS格式在TMySQL中會(huì)替代compact作為innodb的默認(rèn)行格式。
mysql大表添加字段超市處理方法。
①創(chuàng)建一個(gè)臨時(shí)的新表,首先復(fù)制舊表的結(jié)構(gòu)(包含索引);
②給新表加上新增的字段;
③把舊表的數(shù)據(jù)復(fù)制過(guò)來(lái);
④刪除舊表,重命名新表的名字為舊表的名字。
傳統(tǒng)情況
我們先回顧一下,在沒(méi)有 "立刻加列" 功能時(shí),加列操作是怎么完成的。我們也借此來(lái)熟悉一下本期的圖例:
當(dāng)進(jìn)行 加列操作 時(shí),所有的數(shù)據(jù)行 都必須要 增加一段數(shù)據(jù)(圖中的 列 4 數(shù)據(jù))
如上一期圖解所講,當(dāng)改變數(shù)據(jù)行的長(zhǎng)度,就需要 重建表空間(圖中灰藍(lán)的部分為發(fā)生變更的部分)
數(shù)據(jù)字典中的列定義也會(huì)被更新
以上操作的問(wèn)題在于 每次加列 操作都需要重建表空間,這就需要大量 IO以及大量的時(shí)間
立刻加列
"立刻加列" 的過(guò)程如下圖:
請(qǐng)點(diǎn)擊輸入圖片描述
請(qǐng)點(diǎn)擊輸入圖片描述
"立刻加列" 時(shí),只會(huì)變更數(shù)據(jù)字典中的內(nèi)容,包括:
在列定義中增加 新列的定義
增加 新列的默認(rèn)值
"立刻加列"?后,當(dāng)要讀取表中的數(shù)據(jù)時(shí):
由于 "立刻加列" 沒(méi)有 變更行數(shù)據(jù),讀取的行數(shù)據(jù)只有 3 列
MySQL 會(huì)將 新增的第 4 列的默認(rèn)值,追加到 讀取的數(shù)據(jù)后
以上過(guò)程描述了 如何讀取?在 "立刻加列" 之前寫(xiě)入的數(shù)據(jù),其實(shí)質(zhì)是:在讀取數(shù)據(jù)的過(guò)程中,"偽造"?了一個(gè)新列出來(lái)
那么如何讀取?在 "立刻加列" 之后?寫(xiě)入的數(shù)據(jù)呢 ? 過(guò)程如下圖:
當(dāng)讀取 行 4 時(shí):
請(qǐng)點(diǎn)擊輸入圖片描述
請(qǐng)點(diǎn)擊輸入圖片描述
通過(guò)判斷?數(shù)據(jù)行的頭信息中的instant?標(biāo)志位,可以知道該行的格式是 "新格式":該行頭信息后有一個(gè)新字段?"列數(shù)"
通過(guò)讀取?數(shù)據(jù)行的?"列數(shù)"?字段,可以知道 該行數(shù)據(jù)中多少列有 "真實(shí)" 的數(shù)據(jù),從而按列數(shù)讀取數(shù)據(jù)
通過(guò)上圖可以看到:讀取?在"立刻加列"?前/后寫(xiě)入的數(shù)據(jù)是不同的流程
通過(guò)以上的討論,我們可以總結(jié)?"立刻加列"?之所以高效的原因是:
在執(zhí)行?"立刻加列"?時(shí),不變更數(shù)據(jù)行的結(jié)構(gòu)
讀取 "舊" 數(shù)據(jù)時(shí),"偽造"?新增的列,使結(jié)果正確
寫(xiě)入 "新" 數(shù)據(jù)時(shí),使用了新的數(shù)據(jù)格式(增加了instant標(biāo)志位 和?"列數(shù)"?字段),以區(qū)分新舊數(shù)據(jù)
讀取 "新" 數(shù)據(jù)時(shí),可以如實(shí)讀取數(shù)據(jù)
那么?我們是否能一直 "偽造"?下去???"偽造"?何時(shí)會(huì)被拆穿 ?
考慮以下場(chǎng)景:
用 "立刻加列" 增加列 A
寫(xiě)入數(shù)據(jù)行 1
用 "立刻加列" 增加列?B
寫(xiě)入數(shù)據(jù)行?2
刪除列?B
我們推測(cè)一下 "刪除列 B" 的最小代價(jià):需要修改 數(shù)據(jù)行中的instant標(biāo)志位或?"列數(shù)"?字段,這至少會(huì)影響到?"立刻加列"?之后寫(xiě)入的數(shù)據(jù)行,成本類似于重建數(shù)據(jù)
從以上推測(cè)可知:當(dāng)出現(xiàn) 與?"立刻加列"?操作不兼容 的 DDL 操作時(shí),數(shù)據(jù)表需要進(jìn)行重建,如下圖所示:
請(qǐng)點(diǎn)擊輸入圖片描述
請(qǐng)點(diǎn)擊輸入圖片描述
擴(kuò)展思考題:是否能設(shè)計(jì)其他的數(shù)據(jù)格式,取代instant標(biāo)志位和?"列數(shù)"?字段,使得 加列/刪列 操作都能 "立刻完成" ?(提示:考慮 加列?- 刪列?- 再加列 的情況)
使用限制
在了解原理之后,我們來(lái)看看?"立刻加列"?的使用限制,就很容易能理解其中的前兩項(xiàng):
"立刻加列"?的加列位置只能在表的最后,而不能加在其他列之間
在元數(shù)據(jù)中,只記錄了 數(shù)據(jù)行 應(yīng)有多少列,而沒(méi)有記錄 這些列 應(yīng)出現(xiàn)的位置。所以無(wú)法實(shí)現(xiàn)指定列的位置
"立刻加列"?不能添加主鍵列
加列 不能涉及聚簇索引的變更,否則就變成了 "重建" 操作,不是 "立刻" 完成了
"立刻加列"不支持壓縮的表格式
按照 WL 的說(shuō)法:"COMPRESSED is no need to supported"(沒(méi)必要支持不怎么用的格式)
總結(jié)回顧
我們總結(jié)一下上面的討論:
"立刻加列" 之所以高效的原因是:
在執(zhí)行 "立刻加列" 時(shí),不變更數(shù)據(jù)行的結(jié)構(gòu)
讀取 "舊" 數(shù)據(jù)時(shí),"偽造"?新增的列,使結(jié)果正確
寫(xiě)入 "新" 數(shù)據(jù)時(shí),使用了新的數(shù)據(jù)格式?(增加了?instant 標(biāo)志位?和 "列數(shù)" 字段),以區(qū)分新舊數(shù)據(jù)
讀取 "新" 數(shù)據(jù)時(shí),可以如實(shí)讀取數(shù)據(jù)
"立刻加列"?的 "偽造" 手法,不能一直維持下去。當(dāng)發(fā)生?與 "立刻加列" 操作不兼容?的 DDL?時(shí),表數(shù)據(jù)就會(huì)發(fā)生重建
回到之前遺留的兩個(gè)問(wèn)題:
"立刻加列" 是如何工作的 ?
我們已經(jīng)解答了這個(gè)問(wèn)題
所謂 "立刻加列" 是否完全不影響業(yè)務(wù),是否是真正的 "立刻" 完成 ?
可以看到:就算是 "立刻加列",也需要變更 數(shù)據(jù)字典,那么 該上的鎖還是逃不掉的。也就是說(shuō) 這里的 "立刻" 指的是 "不變更數(shù)據(jù)行的結(jié)構(gòu)",而并非指 "零成本地完成任務(wù)"
通過(guò)AUTO_INCREMENT設(shè)置SQLINSERT語(yǔ)句的時(shí)候,要避免指定那個(gè)自增的字段.否則會(huì)發(fā)生主鍵的沖突。通過(guò)ALTERTABLE語(yǔ)句可以修改自增的數(shù)值,但是只能增加,不能減少。TRUNCATETABLE語(yǔ)句,會(huì)將自增ID重置為零。mysqlCREATETABLEtest_create_tab2(-idINTAUTO_INCREMENT,-valVARCHAR(10),-PRIMARYKEY(id)-);QueryOK,0rowsaffected(0.09sec)mysqlINSERTINTOtest_create_tab2(val)VALUES('NOid');QueryOK,1rowaffected(0.03sec)mysqlselectlast_insert_id()asid;+----+|id|+----+|1|+----+1rowinset(0.00sec)mysqlINSERTINTOtest_create_tab2(val)VALUES('NOid2');QueryOK,1rowaffected(0.03sec)mysqlselectlast_insert_id()asid;+----+|id|+----+|2|+----+1rowinset(0.00sec)mysqlselect*fromtest_create_tab2;+----+---------+|id|val|+----+---------+|1|NOid||2|NOid2|+----+---------+2rowsinset(0.00sec)