Oracle Lob型別儲存淺析
在Oracle中,為資料表欄位column和PL/SQL語言,分別提供了多種資料型別,以應對實際開發中的多種型別。Lob型別是Oracle推出一種儲存大物件的資料型別。當我們考慮將資訊檔案(十進位制、二進位制)、影像甚至音訊資訊採用資料庫作為儲存載體時,就需要使用lob型別資料。
目前Oracle支援的Lob型別具體包括四個子型別(subtype),分別為CLOB、BLOB、NLOB和BFILE。其中,CLOB、BLOB和NLOB都是將資料儲存在資料庫內部,而BFILE型別儲存的核心是檔案指標,真正的檔案是儲存在資料庫外。
與傳統的資料型別相比較,lob型別資料無論在管理上還是空間使用上,都有很多特殊之處。本篇主要介紹lob型別一些基本的儲存特性。
1、 環境準備和資料段segment特性
我們選擇在Oracle 10gR2下進行試驗。
SQL> select * from v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 – Production
使用create table命令,可以構建出一個實驗資料表T。
SQL> create table t (id number, cl clob);
Table created
對於一般的資料表而言,一個資料表只會對應一個儲存資料段data segment物件。這裡的特殊情況是分割槽表,通常一個分割槽就對應一個單獨的儲存物件。當資料表中包括lob型別的資料列時,也會有獨特的段物件建立。
SQL> select segment_name, segment_type, tablespace_name from user_segments;
SEGMENT_NAME SEGMENT_TY TABLESPACE_NAME
------------------------------ ---------- ------------------------------
SYS_LOB0000056069C00002$$ LOBSEGMENT USERS
T TABLE USERS
SYS_IL0000056069C00002$$ LOBINDEX USERS
(篇幅原因,無關物件省略。。。。。。)
9 rows selected
我們發現,除了常規的資料段T之外,另外增加了兩個明顯是系統命名的段物件,型別分別為lobsegment和lobindex。
對Oracle lob型別資料表而言,一個帶lob列的資料表建立是要對應多個資料段建立的。除了傳統的資料表建立的資料段Table Data Segment之外,一個lob列都會生成兩個專門的段:lob段和lob索引段。
Lob段(LobSegment)對應的是存放在資料表lob列上的資料。在Oracle的lob型別資料列,有兩種儲存位置結構。一個是in-row storage,也就是每一行的lob資料同其他列的資料以行的形式一起儲存在資料塊中。這種情況的lob列取值較小。而另一種為out-of-row storage,當lob物件較大,不能儲存在一個資料塊中時,可以將其放置在一個獨立lobsegment中進行儲存。而out-of-row storage時資料行中lob列上儲存的只是一個指向lobsegment對應位置的指標引用。
Lob索引段(LobIndex)是Oracle為每一個lob型別列強制生成的索引,主要作用是用於進行lob型別資料檢索加速的操作。Lobindex與lob列共生,如果強制進行刪除操作,是會報錯的。
SQL> drop index SYS_IL0000056069C00002$$;
drop index SYS_IL0000056069C00002$$
ORA-22864: 無法 ALTER 或 DROP LOB 索引
2、lob型別資料表原始定義分析
使用dbms_metadata包,我們可以獲取到資料表的全部定義,包括各種預設引數和細節資訊。
CREATE TABLE "SCOTT"."T"
( "ID" NUMBER,
"CL" CLOB
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "USERS"
LOB ("CL") STORE AS (
TABLESPACE "USERS" ENABLE STORAGE IN ROW CHUNK 8192 PCTVERSION 10
NOCACHE LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)) ;
CREATE UNIQUE INDEX "SCOTT"."SYS_IL0000056069C00002$$" ON "SCOTT"."T" (
PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "USERS"
PARALLEL (DEGREE 0 INSTANCES 0) ;
可以看到我們抽取出的後設資料包括兩個組成部分,資料表建立部分和lob索引建立部分。在資料表建立部分,我們可以看到將lob作為一個獨立段物件進行儲存設定和引數設定。
在lob索引建立部分,我們可以看到雖然是對應索引建立語句,但是從索引名稱上顯然是系統自動生成的物件名稱。
此外,還有很多是針對lob特殊的引數,如cache、enable storage in-row等,這些引數在資料表lob的行為和訪問效能上有巨大的影響。由於篇幅和內容所限,我們在本篇中不加以累述。
3、lob段與lob索引儲存轉移
對於一個資料表涉及的多個段,很多時候我們需要將其進行移動處理。其中最常用的方法是使用move進行物件表空間的移動。
SQL> select segment_name, segment_type, tablespace_name from user_segments;
SEGMENT_NAME SEGMENT_TY TABLESPACE_NAME
------------------------------ ---------- ------------------------------
SYS_LOB0000056099C00002$$ LOBSEGMENT USERS
T TABLE USERS
SYS_IL0000056099C00002$$ LOBINDEX USERS
9 rows selected
SQL> alter table t move tablespace system;
Table altered
SQL> select segment_name, segment_type, tablespace_name from user_segments;
SEGMENT_NAME SEGMENT_TY TABLESPACE_NAME
------------------------------ ---------- ------------------------------
T TABLE SYSTEM
SYS_LOB0000056099C00002$$ LOBSEGMENT USERS
SYS_IL0000056099C00002$$ LOBINDEX USERS
9 rows selected
上面實驗可以明確看到,當使用一般的move命令時,只會將資料表T段進行移動到新表空間。Lob段和對應的lobindex段沒有變化。如果需要移動lob/lobindex,需要額外的單獨操作。
SQL> alter index SYS_IL0000056069C00002$$ rebuild tablespace users;
alter index SYS_IL0000056069C00002$$ rebuild tablespace users
ORA-02327: 無法以資料型別 LOB 的表示式建立索引
Lobindex是不能使用rebuild直接重構的。
SQL> select segment_name, segment_type, tablespace_name from user_segments;
SEGMENT_NAME SEGMENT_TY TABLESPACE_NAME
------------------------------ ---------- ------------------------------
T_LOGSEGMENT LOBSEGMENT USERS
SYS_IL0000056069C00002$$ LOBINDEX USERS
T TABLE EXAMPLE
9 rows selected
SQL> alter table t move lob(cl) store as t_logsegment (tablespace example);
Table altered
SQL> select segment_name, segment_type, tablespace_name from user_segments;
SEGMENT_NAME SEGMENT_TY TABLESPACE_NAME
------------------------------ ---------- ------------------------------
T TABLE EXAMPLE
SYS_IL0000056069C00002$$ LOBINDEX EXAMPLE
T_LOGSEGMENT LOBSEGMENT EXAMPLE
9 rows selected
使用alter table xxx move lob(xx) store as xxx (tablespace xxx);命令,我們可以進行lob列的儲存位置調節。
在建立資料表的時候,同樣可以使用lob(xxx)對應的資料表空間字句,執行儲存lob物件的空間資訊。
SQL> Create table DemoLob ( A number, B clob )
2 LOB(b)
3 STORE AS lobsegname (
4 TABLESPACE users
5 --STORAGE (lobsegment storage clause)
6 INDEX lobindexname (
7 TABLESPACE example
8 --STORAGE ( lobindex storage clause )
9 )
10 )
11 TABLESPACE system
12 --STORAGE( tables storage clause )
13 ;
Table created
SQL> select table_name, column_name, segment_name, tablespace_name, index_name from user_lobs;
TABLE_NAME COLUMN_NAM SEGMENT_NAME TABLESPACE_NAME INDEX_NAME
---------- ---------- ------------------------------ ------------------------------ ------------------------------
T CL T_LOGSEGMENT EXAMPLE SYS_IL0000056069C00002$$
在實際物理設計部署過程中,經常有將大物件分割槽和儲存單獨部署表空間的情況。可以根據實際的情況,將一些很大的lob列連同索引儲存在單獨的表空間上。
但是注意,一般資料表而言,lob段和lobindex段是在一個表空間上。即使在SQL語法上存在支援,但是將lob段和lobindex分開儲存的語句通常被忽略掉。
SQL> alter table t move lob(cl) store as T_LOGSEGMENT (tablespace example index t_logindex (tablespace users));
Table altered
SQL> select table_name, column_name, segment_name, tablespace_name, index_name from user_lobs;
TABLE_NAME COLUMN_NAM SEGMENT_NAME TABLESPACE_NAME INDEX_NAME
---------- ---------- ------------------------------ ------------------------------ ------------------------------
T CL T_LOGSEGMENT EXAMPLE SYS_IL0000056069C00002$$
SQL> select segment_name, segment_type, tablespace_name from user_segments;
SEGMENT_NAME SEGMENT_TY TABLESPACE_NAME
------------------------------ ---------- ------------------------------
T TABLE EXAMPLE
SYS_IL0000056069C00002$$ LOBINDEX EXAMPLE
T_LOGSEGMENT LOBSEGMENT EXAMPLE
9 rows selected
4、結論
Lob型別是一種我們經常使用的複雜資料型別。處理和管理lob型別的方法和我們常規的手段存在很大差異,無論是開發還是運維過程中都要特別注意。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29119536/viewspace-1139905/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle基本資料型別儲存格式淺析——RAW型別Oracle資料型別
- Android 檔案儲存淺析Android
- [20191219]oracle timestamp資料型別的儲存.txtOracle資料型別
- 淺析number型別的值型別
- [20190930]oracle number型別儲存轉化指令碼.txtOracle型別指令碼
- [20191003]oracle number型別儲存轉化指令碼.txtOracle型別指令碼
- [20191013]oracle number型別儲存轉化指令碼.txtOracle型別指令碼
- [20241009]oracle timestamp with time zone資料型別的儲存.txtOracle資料型別
- 杉巖:淺談物件儲存和塊儲存區別物件
- 淺析Kubernrtes服務型別(Service Types)型別
- 【LOB】Oracle Lob管理常用sqlOracleSQL
- 建立NFS型別的儲存NFS型別
- 【LOB】Oracle lob管理常用語句Oracle
- Block型別及儲存區域BloC型別
- JavaScript 隱性型別轉換步驟淺析JavaScript型別
- 淺析Oracle(rownum)和Mysql(limit)分頁的區別OracleMySqlMIT
- [20190531]lob型別pctversion 和 retention.txt型別
- JavaScript中的資料型別-儲存差別JavaScript資料型別
- SAP EWM - 儲存型別 - 入庫控制型別
- mysql儲存日期使用什麼型別MySql型別
- redis-4.資料儲存型別Redis型別
- 淺析雲端儲存的TCS和LCA兩大架構架構
- java多型性淺析Java多型
- C#引用型別和值型別在堆、棧中的儲存C#型別
- SQL Server中datetimeset轉換datetime型別問題淺析SQLServer型別
- Oracle儲存過程Oracle儲存過程
- Golang的值型別和引用型別的範圍、儲存區域、區別Golang型別
- 資料的儲存結構淺析LSM-Tree和B-tree
- 作用域、連結屬性和儲存型別型別
- VMware 與 SmartX 分散式儲存快取機制淺析與效能對比分散式快取
- Oracle 共享儲存掛載Oracle
- oracle的儲存過程Oracle儲存過程
- Oracle儲存過程-1Oracle儲存過程
- dbms_lob儲存過程導致臨時表空間100%儲存過程
- InnoDB儲存引擎鎖機制(二、 鎖的型別)儲存引擎型別
- Mybatis讀取和儲存json型別的資料MyBatisJSON型別
- 淺析多媒體互動展廳幾個常見型別型別
- 濃縮的才是精華:淺析GIF格式圖片的儲存和壓縮
- ORACLE LOB大欄位維護Oracle