2021年3月30日 星期二

9.1 資料型態與字元集

Oracle 資料庫字元集的設定可以分為兩種,一般字元集 (Character Set) 與國際字元集 (National Character Set),兩者差別只在於對應的是不同資料型態,國際字元集所對應的資料型態是有 “N” 開頭的,例如 NCHAR、NVARCHAR2,而一般字元集是沒有 “N” 的,例如 CHAR、VARCHAR2,透過這種方式,使得 Oracle 資料庫可以利用資料型態的設定來同時使用兩種不同的字元集。


透過查詢 v$nls_valid_values 可以得知目前 Oracle 資料庫可以設定的一般字元集:

SQL> select parameter,value from v$nls_valid_values where parameter='CHARACTERSET';


對於我們中文語系來說,最常使用的莫過於中文字元集,ZHT16BIG5、ZHT16MSWIN950,或是 Unicode 字元集, UTF8 、 AL32UTF8 ,兩者最大的差別在於使用中文字元集時,一個中文字的長度為 2 bytes,而使用 Unicode 時,則為 3 bytes。 UTF8 與 AL32UTF8 同為 Unicode 字元集,差別只在於 UTF8 的最大長度為 3 bytes,而 AL32UTF8 最大可達 4 bytes,因此 AL32UTF8 可容納的字元數量多於 UTF8,可以說是 UTF8 的母字元集。


而國際字元集只提供了兩種設定,AL16UTF16 與 UTF8,預設為 AL16UTF16,差別在於 AL16UTF16 為固定長度,不論是英文字或是中文字都是 2 bytes;UTF8 為變動長度,例如英文字為 1 bytes 而中文字為 3 bytes。


不論是一般字元集或是國際字元集,在資料庫建立的當下就必須決定好要使用哪個,如果之後要更改,可以使用 “alter database character set” 指令來更改,例如將一般字元集改為 AL32UTF8,國際字元集改為 UTF8:

SQL> alter system set cluster_database=false scope=spfile;

     (若為 RAC 必須先將參數 cluster_database 設定為 false)

SQL> shutdown immediate

SQL> startup restrict

SQL> alter database character set INTERNAL_USE AL32UTF8;

     (一般字元集改為 AL32UTF8)

SQL> alter database national character set INTERNAL_USE UTF8;

     (國際字元集改為 UTF8)

SQL> shutdown immediate

SQL> startup


在此必須要特別注意的是,更改資料庫的字元集設定並不會更改資料庫裡面已經存在的字元,它只會影響之後所新增的字元,例如原本設定為 ZHT16BIG5,中文字為 2 bytes,此時將它改為 AL32UTF8 ,已經存在資料庫的中文字並不會自動變成 3 bytes ,而是之後新增的中文字才會變成 3 bytes,因此非常不建議在資料庫建立後再去更改字元集,因為這樣會造成資料庫字集長度的混亂,所以對於 Oracle 管理者來說,字元集在資料庫建立之後就是一個無法更改的設定。


Oracle 文字的資料型態為 CHAR、VARCHAR2 (或是 NCHAR、NVARCHAR2) ,使用上在資料型態後面來指定大小,單位可以使用 byte 或是 char , byte 表示資料長度以 byte 來計算, char 表示資料長度以一個完整的 “字” 來計算,例如 VARCHAR2(20 byte) ,表示這個文字的資料長度最大為 20 byte,最多可以容納 10 個中文字 (一個中文 2 bytes,以ZHT16BIG5來說);若是 VARCHAR2(20 char) ,則是以 “字” 為單位,最多就可以容納 20 個 “字” (包含中文或英文) , 如果不指定單位的話,例如只設定 VARCHAR2(20) ,那麼長度單位就由參數 nls_length_semantics 所決定,預設為 byte。 CHAR 與 VARCHAR2 的差別在於 CHAR 為固定長度而 VARCHAR2 為變動長度,例如 CHAR(10) 設定下,我們只塞了 “scott” 五個字,那麼整個資料會在 “scott” 後面補上五個空白字元讓整體的資料長度為 10 byte,未來所看到的資料就會變成 “scott     “ ;而 VARCHAR2(10) 就不會在後面補空白字元,塞入 “scott” 五個字它的長度就是 5 bytes。


VARCHAR2 最大可設定的長度為 4000 bytes,到了 Oracle 12c 之後,可以將 VARCHAR2 拓展為 32767 bytes (32K)。 Oracle 12c 之後提供了參數 max_string_size ,預設為 STANDARD ,表示 VARCHAR2 長度最大為 4000 ,若設定為 EXTENDED ,則 VARCHAR2 可拓展為 32K,設定時必須將資料庫啟動在 upgrade mode 並執行 32k 的 script:

1. 將資料庫啟動在 upgrade mode

 SQL> shutdown immediate

 SQL> startup upgrade


2. 更改參數 max_string_size

 SQL> alter system set max_string_size=EXTENDED scope=spfile;


3. 以 sysdba 身分執行 32k script

 SQL> @?/rdbms/admin/utl32k.sql


4. 重啟資料庫至正常模式

 SQL> shutdown immediate

 SQL> startup


5. 重新編譯無效物件

 SQL> @?/rdbms/admin/utlrp.sql


在此必須要注意的是,一旦max_string_size 更改為 EXTENDED 之後,就無法再還原回 STANDARD 了。


Oracle 數值資料型態可為 NUMBER 或是 INTEGER,例如 NUMBER(4) 表示最大長度為4的數字,例如 9999 ; 而 NUMBER(4,2) 表示最大長度為 4 包含兩個小數位,例如 99.99 。 INTEGER 則表示是整數的數字型態,沒有小數的設定。


日期的資料型態可為 DATE 或是 TIMESTAMP,差別在於 TIMESTAMP 預設可以顯示到秒位數小數點後的六位。日期顯示的格式由參數 nls_date_format 所設定,預設為 DD-MON-RR ,我們可以經由調整 nls_date_format 的設定讓日期格式的可讀性更高:


除了上述常用的資料型態之外,還有一些特殊的資料型態可以使用,例如CLOB (NCLOB) , 文字型態的大型物件、 BLOB ,二進位(Binary) 型態的大型物件、 BIGFILE ,將檔案(Binary File)儲存在資料庫外部的資料型態、 XMLTYPE , 存放 XML 格式的資料型態,到了 Oracle 12c 之後更是可以將 JSON 格式的資料型態直接存放在 Oracle 資料庫當中。


在了解字元集與資料型態之後,我們就可以依據應用系統的需求來建立資料庫物件。






沒有留言:

張貼留言