1. 程式人生 > >Oracle資料庫的邏輯結構未完待續、、、

Oracle資料庫的邏輯結構未完待續、、、

這是一張非常基本同時也是非常重要的結構圖。物理結構很簡單,就是作業系統物理塊組成資料檔案,對於作業系統來說,資料檔案跟其他非資料庫檔案沒有區別。重點是邏輯結構。

oracle資料庫從邏輯儲存結構上來講,主要包括表空間,段,區,資料塊。

他們之間的關係為:一個


一、表空間
  從9i開始,oracle支援不同塊大小的表空間,

也就是說同一個資料庫中,不同表空間的資料塊大小可以不一樣。假設預設8k的話,還可以建立比如4k、16k、32k、64k等大小的表空間。不過如果有不同塊大小的表空間,請記得為它們設定不同的db_nk_cache_size引數,以為這些表空間的資料訪問分配記憶體。
  從10g開始,oracle支援重命名錶空間,語法是alter tablespace rename to ;這個操作在傳輸表空間時非常有用,當源和目標的表空間名稱不一致時,通過此命令可以方便地更名,這是一大進步。


二、段(segment)
  參考上圖,一個段可以跨越多個數據檔案,但只能在一個表空間中。一個段由多個區(extent)組成。每一個段都有一個單獨的data_object_id對應。這裡需要額外說明一下data_object_id和object_id的區別。簡單的說,object_id對應的是物件,而data_object_id對應的是段。比如一個procedure有object_id,但沒有data_object_id,因為它不是段。因為每一個段都唯一對應一個表空間,而每一個段都擁有自己獨一無二的data_object_id,所以通過data_object_id,就能唯一定位這個段所在的表空間,這就是rowid的原理。

這裡做一個實驗,來說明data_object_id和object_id的區別以及一些操作對data_object_id的影響。首先建立一張分割槽表

SQL>create table part_test(id number,create_time date)
  partition by range (id)
  (partition part1 values less than (100),
  partition part2 values less than (200),
  partition part3 values less than (maxvalue));
  看一下沒有資料時的情況
  SQL>select object_name,subobject_name,object_type,object_id,data_object_id from user_objects where object_name = 'PART_TEST';
OBJECT_NAME          SUBOBJECT_NAME       OBJECT_TYPE          OBJECT_ID DATA_OBJECT_ID
-------------------- -------------------- ------------------- ---------- --------------
PART_TEST                                 TABLE                    73205
PART_TEST            PART1                TABLE PARTITION          73206          73206
PART_TEST            PART2                TABLE PARTITION          73207          73207
PART_TEST            PART3                TABLE PARTITION          73208          73208

可以看出,初始沒有資料的時候,data_object_id和object_id一樣。考慮到data_object_id是記錄了資料存放的位置,我們看一下先插入資料,再將表truncate之後的情況。

SQL> insert into part_test values(1,sysdate);
  1 row created.
  SQL> insert into part_test values(101,sysdate+1);
  1 row created.
  SQL> commit;
  Commit complete.
  SQL> truncate table part_test;
  Table truncated.
  SQL> select object_name,subobject_name,object_type,object_id,data_object_id from user_objects where object_name = 'PART_TEST';
OBJECT_NAME          SUBOBJECT_NAME       OBJECT_TYPE          OBJECT_ID DATA_OBJECT_ID
-------------------- -------------------- ------------------- ---------- --------------
PART_TEST            PART3                TABLE PARTITION          73208          73208
PART_TEST            PART2                TABLE PARTITION          73207          73211
PART_TEST            PART1                TABLE PARTITION          73206          73210
PART_TEST                                 TABLE                    73205
  可以看出,有資料的段,對應的data_object_id改變了,這是因為truncate之後,oracle重新分配了這些段儲存資料的空間,因此改變了data_object_id。而沒有資料的段,data_object_id沒有改變,因為oracle並沒有對這些段重新分配資料儲存空間。

三、區(extent)
  一個區由連續的塊組成。這裡要強調的就是連續。因此,一個區是不能跨資料檔案的(參見上圖跟資料檔案相連的那條線)
  四、塊(block)
  這是oracle存取資料最小的單位,在建立資料庫的時候指定,一旦指定則無法修改。(但在9i之後可以建立不同塊大小的表空間,一定程度上解決了這個問題。)
  一個塊除了了塊頭、表目錄和行目錄之外的空間,都可以用來存放資料。按照預設8k大小的塊來說,這部分可以真正存放資料的空間是8096位元組。然後因為各種其他開銷,每行資料的最小長度大約是11個位元組,也就是說,每個塊最大存放的行數理論值是8096/11=736行。我們可以做個試驗來驗證一下。

http://www.searchdatabase.com.cn/showcontent_42161.htm