91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MySQL和Oracle的添加字段的處理差別

發布時間:2020-08-12 15:02:54 來源:ITPUB博客 閱讀:180 作者:jeanron100 欄目:MySQL數據庫
昨天在微信群中有個朋友也是無意中問了一下,說數據庫中的表字段想保持一種相對規范的順序,怎么辦?要知道Oracle中這個操作就比較糾結了,因為是按照追加的方式來處理的。沒法在已有的字段1,字段2中間添加一個字段3。但是MySQL卻可以,這個方面MySQL看起來要靈活的多,這個是什么原因呢,他們在設計上有什么差別呢。
MySQL中對每個表存在一個定義文件,即frm文件,我們來取出一個表,看看能不能簡單解析一下。
比如一個表字段的內容如下:
> desc zd_warshrine_prostate;
+----------+--------------+------+-----+-------------------+----------------+
| Field    | Type         | Null | Key | Default           | Extra          |
+----------+--------------+------+-----+-------------------+----------------+
| id       | int(10)      | NO   | PRI | NULL              | auto_increment |
| proName  | varchar(100) | NO   | MUL | NULL              |                |
| TYPE     | varchar(10)  | NO   |     | NULL              |                |
| loaderr  | int(11)      | NO   |     | 0                 |                |
| loadTime | timestamp    | NO   |     | CURRENT_TIMESTAMP |                |
+----------+--------------+------+-----+-------------------+----------------+
我們可以使用strings來簡單解析一下,可以通過上面的內容能夠讀到一些信息。
# strings  zd_warshrine_prostate.frm
PRIMARY
in_ty_zyl_proName
InnoDB
)                                        
proName
TYPE
loaderr
loadTime
proName
TYPE
loaderr
loadTime
大體能夠看出,只解析出來了字段名。而查看MySQL中的數據字典columns,卻壓根看不到column_id這樣的字段。
MySQL和Oracle的添加字段的處理差別
在MySQL要實現添加字段的順序性,語句可以這樣寫:
ALTER TABLE test
    ADD COLUMN `amount_sum`  double(255,0) AFTER `amount_name`;
即在字段amount_name后添加字段amount_sum
難道是MySQL中的這種方式技高一籌,也不是了,對于添加字段,修改數據類型這類的操作,MySQL在早期版本也是飽受詬病,因為會直接鎖表,而且實現起來的思路其實就是復制表數據,類似于重建。這個情況在后來的一些版本比如5.6有了一些改善,有了pt-osc的工具,這個改進可以在線修改了。而實現方式其實有點類似于Oracle中的在線重定義,MySQL中會創建一個臨時表,然后創建2個觸發器,然后同步數據到臨時表,然后觸發器同步操作。如果表數據不大,倒還不是什么大問題,一旦數據量級上來了,業務關注度上來了,這個地方就值得好好挖掘挖掘。
Oracle中是怎么做的呢。看起來還是有不小的差別。
比如我們查看一個表users的數據。
SQL> select dbms_rowid.ROWID_RELATIVE_FNO(rowid) as file#,dbms_rowid.ROWID_BLOCK_NUMBER(rowid) as block#,dbms_rowid.ROWID_ROW_NUMBER(rowid) as row#,a.* from test.USERS a where rownum<2;
     FILE#     BLOCK#       ROW#     USERID USER_NAME
---------- ---------- ---------- ---------- --------------------
        24    1569619          0       1278 user1278
通過上面的輸出可以看到是在24號文件,數據塊1569619中,數據信息也一并輸出出來了,這個表含有兩個字段,userid,user_name;
那么數據是如何存儲的呢。我們做一個dump
alter system dump datafile 24 block 1569619;        
為了圖省事,可以直接查看select *from v$diag_info;得到trace文件的路徑。
/U01/app/oracle/diag/rdbms/mbionline/mbionline/trace/mbionline_ora_15752.trc
我們輸出幾行trace文件的內容,可以看到字段都是存在一個column_id的字樣,即col 0,col 1這樣的。
tab 0, row 56, @0x134a
tl: 16 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 3]  c2 0e 23
col  1: [ 8]  75 73 65 72 31 33 33 34
tab 0, row 57, @0x135a
tl: 16 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 3]  c2 0e 24
col  1: [ 8]  75 73 65 72 31 33 33 35
tab 0, row 58, @0x136a
tl: 16 fb: --H-FL-- lb: 0x1  cc: 2
col  0: [ 3]  c2 0e 25
col  1: [ 8]  75 73 65 72 31 33 33 36

Oracle中是按照這個column_id來進行字段的順序管理的。關于字段有兩個很相似的數據字典dba_tab_cols,tab_tab_columns。
里面很重要的一個屬性就是column_id,同時也能夠看出還有數據類型為Long的字段 DATA_DEFAULT ,這也算是Oracle為此問題付出的一個代價,為了保持兼容性,這個long類型的字段到了12c依舊是如此。
SQL> desc dba_tab_columns
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 OWNER                                     NOT NULL VARCHAR2(30)
 TABLE_NAME                                NOT NULL VARCHAR2(30)
 COLUMN_NAME                               NOT NULL VARCHAR2(30)
 DATA_TYPE                                          VARCHAR2(106)
 DATA_TYPE_MOD                                      VARCHAR2(3)
 DATA_TYPE_OWNER                                    VARCHAR2(60)
 DATA_LENGTH                               NOT NULL NUMBER
 DATA_PRECISION                                     NUMBER
 DATA_SCALE                                         NUMBER
 NULLABLE                                           VARCHAR2(1)
 COLUMN_ID                                          NUMBER
 DEFAULT_LENGTH                                     NUMBER
 DATA_DEFAULT                                       LONG
 NUM_DISTINCT                                       NUMBER
而如果對一個大表添加字段,如果涉及默認值,那就工作就很難了,除此之外添加字段方面,Oracle處理起來還是要好很多,至少不會重建表數據。這也算是兩者在設計上的一些差別吧。而對于Oracle可以有不少的診斷方式,對于MySQL似乎方式和手段就少了一些,不過也有幾種方式,
比如驗證MySQL對于添加字段,修改數據類型,可以查看show processlist,找到一個線程會標示copy to tmp table
而同時在數據目錄下會創建兩個臨時文件,類似下面的形式。
-rw-rw---- 1 mysql mysql        8860 Nov  4 19:15 #sql-2721_17a3a9.frm
-rw-rw---- 1 mysql mysql   549453824 Nov  4 19:16 #sql-2721_17a3a9.ibd
而更進一步想看到更多的內容,那就是源代碼了,其實還好了,已經看到有些牛人在解析這部分的內容了,不過我得自己讀一讀,消化一下,才能拿出來。
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

仪陇县| 闸北区| 万全县| 江门市| 夏邑县| 晴隆县| 固原市| 乌苏市| 酉阳| 曲水县| 沁阳市| 万荣县| 普安县| 卢龙县| 宁国市| 洞口县| 尖扎县| 乌兰县| 惠水县| 龙陵县| 道孚县| 恩施市| 石阡县| 分宜县| 平南县| 嵊州市| 台北县| 民丰县| 忻城县| 应用必备| 泽普县| 安丘市| 故城县| 汉中市| 宁德市| 太原市| 江门市| 天峻县| 南雄市| 凤山市| 洪泽县|