【新炬網路名師大講堂】Oracle中大表新增帶有預設值列的討論(包括11G,12C新特性)
(本文轉自“NCN新炬網路團隊部落格”)
這個問題為什麼要討論呢,是有歷史根源的
我們從10G開始說起
在11G以前,一個大表,如果要新增一個新列,且新列有預設值,如果使用alter table xx add xx_1 number default 1000; 這類語句設定,那造成的後果是非常恐怖的。
它的動作其實就是,新增一個列,然後對這一列進行更新,如果這個表非常大,那麼將會產生一個非常大的事務。
而且因為它是ddl操作,它甚至會導致關於該表的select語句都被堵塞!後果非常可怕。
我們在10G中,遇到這種需求怎麼辦呢?
簡單來說,就是先新增一列(不設定預設值)
之後透過使用PL/SQL 對這一列進行批次提交更新(比如1000行 一提交)
好處是,不會鎖太多的行,而且每個事務都不大,出現故障之類的,不會產生死事務
這裡分享一個批次提交更新的指令碼模版
declare
row_num number :=0;
begin
for c_test in (select rowid from hankdai) loop
update hankdai t set NewColumn=1000 where t.rowid=hank_test.rowid;
row_num := row_num + 1;
if mod(row_num,2000) = 0 then
commit;
end if;
end loop;
commit;
end;
當然,這裡還可以使用線上重定義的方式。
http://blog.csdn.net/dbcrocodile/article/details/21512945 ,參考我的這篇部落格
到了11G中,我們對於表新增一列 帶有預設值,有了新特性
我們來測試一下,建立表t,100多萬資料。
SQL> select count(*) from t;
COUNT(*)
———-
1207317
對錶加了一列,並設定not null 加預設值
SQL> alter table t add MrDai number default 10000 not null;
Table altered.
Elapsed: 00:00:00.34
速度飛快
這裡其實只是在資料字典中做了一個標記,並不會對塊中行的實際資料進行修改,所以速度飛快
我們查詢的時候,會對新列做一個類似nvl()之類的操作,如果是null,則返回預設的數值。
在設定完成以後,如果是新插入的行,在預設值列,會將資料真正的插入到行
總結一下,這個特性類似於 給表設了一個斷點, 斷點之前的,如果該列是null,則對其轉換為 預設值,而斷點之後的,該列會插入真正的值
這裡存在一個問題,就是我上面標紅的not null。
畢竟一個新特性在口口相傳中可能會漏掉一些東西,比如最重要的not null 如果漏了
那麼將會產生與10G中相同的災難,超大DDL事務,hang死關於該表的一切操作(包括select)
這種誤操作可以說是非常容易發生的,看看下面這兩個語句有多像。
alter table t add MrDai1 number default 10000;
alter table t add MrDai1 number default 10000 not null;
OK。既然提出了可能會存在這種誤操作事故可能性,那麼我就一定要提出一個解決方案,否則這部落格豈不是玩笑了
12C。對這個功能再次做出了增強,這個增強最重要的就是將這個誤操作消除了。也就是說,大表新增預設值新列時,不用加not null 也可以實現metadata only 的增加方式。
實現如下:
百萬表
SQL> select count(*) from t;
COUNT(*)
———-
1454256
對錶直接增加一列(不設定not null)
SQL> alter table t add MrDai number default 10000;
Table altered.
Elapsed: 00:00:00.03
—————————————————————————————————————————–
上面主題討論完了,看起來不起眼的更新,其實在我們實際運用過程中影響卻十分巨大,所以有什麼新特性,一定要首先實驗實驗再實驗,將語句寫好,到業務庫上建議複製貼上。減少各種非常不 必要的誤操作。
—————————————————————————————————————————-
上面討論了12C中default列增強的一種,那麼將12C中關於default列的增強的其他部分也討論一下。
12C中default列方面增強了三塊。
1、default列metadata only增強(既我們上面討論過的特性)
2、default值直接使用sequence
3、顯式插入null值,依然將其變成default值特性(on null子句)
第一個特性我們已經討論過了,開始從第二個特性討論。
default值直接使用sequence
12C之前情況
建立sequence
SQL> create sequence t_seq;
Sequence created.
SQL>create table t1 (
id number default t_seq.nextval,
*
name varchar2(20)
4 );
ERROR at line 2:
ORA-00984: column not allowed here
說明,在12C之前,如果想產生一個順序預設值作為列值,必須在insert裡面做文章,如下
SQL>create table t1 (id number,
name varchar2(20)
);
Table created.
SQL> insert into t1 values(t_seq.nextval,’haha’);
1 row created.
Elapsed: 00:00:00.00
SQL> insert into t1 values(t_seq.nextval,’haha’);
1 row created.
Elapsed: 00:00:00.00
SQL> select * from t1;
ID NAME
———- ——————–
1 haha
2 haha
這裡是11G的情況,到了12C我們可以在表建立的過程中直接指定某列預設值為sequence值的nextval,currval
SQL> create sequence t_seq;
Sequence created.
Elapsed: 00:00:00.03
create table t1 (
id number default t_seq.nextval,
name varchar2(20)
4 );
Table created.
Elapsed: 00:00:00.08
插入資料(僅插入name列,id列不輸入值)
SQL> insert into t1(name) values(‘haha’);
1 row created.
Elapsed: 00:00:00.00
SQL> insert into t1(name) values(‘haha’);
1 row created.
Elapsed: 00:00:00.00
SQL> select * from t1;
ID NAME
———- ——————–
1 haha
2 haha
我們再也不用羨慕sqlserver中列值自增長了。
————————————————————————————-
顯式插入null值,依然將其變成default值特性(on null子句)
該特性不好描述,直接看實驗算了。
建立兩個sequence
SQL> create sequence t_seq;
Sequence created.
SQL> create sequence t2_seq;
Sequence created.
建立表t1,id,name ,id2 三列,並在id2列使用on null 子句
SQL>create table t1 (
id number default t_seq.nextval,
name varchar2(20),
id2 number default on null t2_seq.nextval
5 );
Table created.
插入資料
第一行,顯式指定三列值
SQL> insert into t1(id,name,id2) values(1,’Hank’,101);
1 row created.
第二行,顯式指定name列值
SQL> insert into t1(name) values(‘Hank2′);
1 row created.
第三行,顯式指定id,id2為null,name列值為hank3
SQL> insert into t1(id,name,id2) values(null,’Hank3′,null);
1 row created.
檢視三行分別的結果。
SQL> select * from t1;
ID NAME ID2
———- ——————– ———-
1 Hank 101 —-
三列都為原本指定的值
1 Hank2 1
—–1列和3列分別都為預設的sequence值
Hank3 2 —–顯
式指定null後,id2 on null列 也插入預設值2,而id列則插入顯式指定的null值。
這就是區別,描述的不好,但實驗結果應該是蠻清楚的。
原文連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29960155/viewspace-1426263/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【新炬網路名師大講堂】Oracle Database 12c 新特性總結OracleDatabase
- 【新炬網路名師大講堂】12c新特性:備份CDBs和PDBs
- 【新炬網路名師大講堂】12c新特性:使用RMAN連線CDB
- 【新炬網路名師大講堂】關於Oracle 12c Flex ASM特性的理解OracleFlexASM
- 【新炬網路名師大講堂】clone oracle 12c pluggable databasesOracleDatabase
- 【新炬網路名師大講堂】總結和結論
- 【新炬網路名師大講堂】Oracle 11g rac 刪除節點Oracle
- 【新炬網路名師大講堂】12c高可用新特性what-if command evaluation介紹
- 【新炬網路名師大講堂】SOA套件介紹套件
- 【新炬網路名師大講堂】weblogic整合ejbWeb
- 【新炬網路名師大講堂】Oracle中的回收站(Recycle Bin)Oracle
- 【新炬網路名師大講堂】Oracle 12C一個實用的新特性介紹:drop/truncate多個子分割槽Oracle
- 【新炬網路名師大講堂】svn在linux下的使用Linux
- 【新炬網路名師大講堂】關於LOG FILE SYNC的解惑
- 【新炬網路名師大講堂】oracle application server之核心技術opmnOracleAPPServer
- 【新炬網路名師大講堂】Oracle小知識- Oracle KILLED會話的釋放Oracle會話
- 【新炬網路名師大講堂】TUXEDO的配置最佳化之路一UX
- 【新炬網路名師大講堂】TUXEDO的配置最佳化之路二UX
- 【新炬網路名師大講堂】初識mysql的體系結構MySql
- 【新炬網路名師大講堂】關於IMSI/MSISDN/IMEI的介紹
- 【新炬網路名師大講堂】Data Guard–物理主備庫切換
- 【新炬網路名師大講堂】cursor: pin S wait on X模擬AI
- 【新炬網路名師大講堂】GoldenGate的ADD SCHEMATRANDATA命令研究Go
- 【新炬網路名師大講堂】AIX上的配置網路調優引數AI
- 【新炬網路名師大講堂】j2ee與weblogic簡介Web
- 【新炬網路名師大講堂】RAC環境下SYSDATE返回錯誤時間
- 【新炬網路名師大講堂】不同資料庫取前幾條記錄資料庫
- 【新炬網路名師大講堂】MySQL複製與監控系列文章(1)——篇首MySql
- 【新炬網路名師大講堂】WAS控制檯資料來源資訊無故丟失
- 【新炬網路名師大講堂】有限條件下怎樣做好恢復演練
- 【新炬網路名師大講堂】CBO中”與NULL在cardinality計算上的差別Null
- 【新炬網路名師大講堂】理解TimesTen錯誤日誌資訊”waiting for latch”AI
- 【新炬網路名師大講堂】DATABASE REPLAY加壓播放引數之SCALE_UP_MULTIPLIERDatabase
- 【新炬網路大師講堂】CMMI/敏捷方法入門敏捷
- 【新炬網路名師大講堂】記一次打PSU遇到的Copy failed的問題AI
- 【新炬網路名師大講堂】有關DBLINK操作的語句執行機制及最佳化方式
- 【新炬網路名師大講堂】TimesTen記憶體碎片(高水位)回收步驟詳解記憶體
- 【新炬網路名師大講堂】軟體測試中常見問題與解決辦法