Oracle中最常用的字串型別可能就是varchar2了,但是一直以來,讓人吐槽最多的,可能就是他的存盤容量,12c之前,允許存盤4000位元組,請注意這的單位是位元組,如果你按照非常規的字符定義欄位,就得結合字符集,確定他能存盤的容量,如果要存盤超過這個限制的字符,就得改為CLOB型別了,他的容量是4G,另外一種變通的形式,不想使用大欄位,就將要存盤的字符拆成多個varchar2型別的欄位,讀的時候拼接這些欄位,起到一樣的效果,
從12c開始,varchar2(實際包括nvarchar2和raw)開始支持32767個位元組,即32K的容量,他是由max_string_size這個引數控制的,默認值是STANDARD,為了支持32K,需要將其改為EXTENDED,
SQL> show parameter max_string_size
NAME TYPE VALUE
---------------- ------ ----------
max_string_size string STANDARD
從官方檔案,我們知道,non-CDB、CDB、PDB都支持這個引數,

(1) 如果是non-CDB,步驟較為簡單,
1. 關閉資料庫,shutdown immediate,
2. 啟動資料庫到升級模式,startup upgrade,
3. 修改max_string_size=’EXTENDED’,scope=both,
4. 執行@?/rdbms/admin/utl32k.sql
5 .重啟資料庫至正常open狀態,shutdown immdeiate -> startup,
(2) 如果是PDB,步驟和上述相同,只是必須在PDB執行以下操作,
SQL> alter pluggable database bisalpdb2 close;
Pluggable database altered.
SQL> alter pluggable database bisalpdb2 open upgrade;
Pluggable database altered.
SQL> alter system set max_string_size=extended scope=both;
System altered.
SQL> @?/rdbms/admin/utl32k.sql
Session altered.
//腳本執行速度,應該和當前資料庫中的物件數量有關,
SQL> alter pluggable database bisalpdb2 close;
Pluggable database altered.
SQL> alter pluggable database bisalpdb2 open;
Pluggable database altered.
此時的引數值,已經改為EXTENDED,
SQL> show parameter max_string_size
NAME TYPE VALUE
---------------- ------ --------
max_string_size string EXTENDED
我們就可以創建一個32767位元組的varchar2型別欄位,
SQL> create table test(c varchar2(32767));
Table created.
(3) 如果是CDB,執行以上操作,還需要單獨設定pdb$seed以及其他pdb的max_string_size,操作程序:
close->open upgrade->max_string_size->close->open
這就不操作了,
雖然能支持32K的字串了,但是還存在一些風險和限制,例如,
(1) EXTENDED只支持heap table,不支持cluster table簇表和index-organized tables索引組織表,
(2) max_string_size如果改為EXTENDED,不能再改為STANDARD,這是單向操作,因此要提前設計,
SQL> alter pluggable database bisalpdb2 close;
Pluggable database altered.
SQL> alter pluggable database bisalpdb2 open upgrade;
Pluggable database altered.
SQL> alter system set max_string_size=standard scope=both;
alter system set max_string_size=standard scope=both
*
ERROR at line 1:
ORA-02097: parameter cannot be modified because specified value is invalid
ORA-14693: The MAX_STRING_SIZE parameter must be EXTENDED.
(3) 32K的字串在Oracle內部還是以LOB的方式存盤的,容易造成行鏈接,對資料讀取的性能產生一定的影響,
(4) 索引中的欄位,不能直接支持EXTENDED,需要洗掉索引,更改欄位,再重建索引,
(5) 官方檔案上提到了如下這些場景,第一個場景,應該和索引長度限制相關,如果按照標準8k的資料塊,一個B樹索引塊所支持的索引長度可能就6千多位元組,這就和在MySQL中索引鍵值長度的問題很像了(《小白學習MySQL - 索引鍵長度限制的問題》),或者通過substr截取創建索引,或者通過substr創建虛擬列,再創建索引,
Altering MAX_STRING_SIZE will update database objects and possibly invalidate them, as follows:
Tables with virtual columns will be updated with new data type metadata for virtual columns of VARCHAR2(4000), 4000-byte NVARCHAR2, or RAW(2000) type.
Functional indexes will become unusable if a change to their associated virtual columns causes the index key to exceed index key length limits. Attempts to rebuild such indexes will fail with ORA-01450: maximum key length exceeded.
Views will be invalidated if they contain VARCHAR2(4000), 4000-byte NVARCHAR2, or RAW(2000) typed expression columns.
Materialized views will be updated with new metadata VARCHAR2(4000), 4000-byte NVARCHAR2, and RAW(2000) typed expression columns
因此,為了能從語法上支持32K的varchar2,還是需要一些代價的,究竟是設定max_string_size,還是選擇CLOB,或者是拆分欄位,可能就得結合實際的場景,綜合考量,
近期更新的文章:
《“自以為對的”MyBatis空閑連接探測的機制》
《積累一些SQL》
《創建主鍵的三種方式對指定索引表空間操作的糾正》
《Oracle優化器的“短路”》
《MySQL行轉列的小需求》
《Oracle的greatest和least函式》
《我的股市生涯》
《Oracle創建主鍵的三種方式》
《非Oracle Linux下Oracle 19c CDB資料庫安裝》
《案例糾正一則》
《Redis和Sentinel的安裝部署和配置》
《“火線”和“零線”》
《通過索引提升SQL性能案例一則》
《如何手動添加jar包到maven本地庫?》
《1元股權轉讓的一點思考》
《如何打造一個經常宕機的業務系統?》
《Linux恢復誤刪檔案的操作》
《Linux的scp指令使用場景》
《Oracle處理IN的幾種方式》
《如何搭建一支拖垮公司的技術團隊?》
《IP地址決議的規則》
《MySQL的skip-grant-tables》
《國產資料庫不平凡的一年》
《Oracle要求順序的top資料檢索問題》
《日常作業中碰到的幾個技術問題》
《了解一下sqlhc》
《Oracle的MD5函式介紹》
《Oracle 19c的examples靜默安裝》
《sqlplus登錄緩慢的解決》
《VMWare 11安裝RedHat Linux 7程序中碰到的坑》
《COST值相同?是真是假?》
《Oracle 11g的examples靜默安裝》
文章分類和索引:
《公眾號700篇文章分類和索引》
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/276965.html
標籤:AI
