ROWID與ROWNUM的簡介與對比

還不算暈發表於2013-12-10

關於ROWID:

在使用者向表中插入一行資料時,ORACLE會自動在這一行資料加上一個ROWID,每行都有一個唯一ROWID,ORACLE利用ROWID定位資料行。ROWID並不顯式儲存為一列的值(偽列--不是存在表中的實際資料,可能是內部採用函式什麼的根據行所在塊的資訊轉換的),是訪問一個表中行的最快機制。索引中儲存的有索引行的值及索引行的ROWID的值--實際資料。

ORACLE ROWID分為物理ROWID,邏輯ROWID。
詳見:    通過rowid得到資料塊的相關資訊

關於ROWNUM:

對於rownum來說它是oracle系統順序分配為從查詢返回的行的編號,返回的第一行分配的是1,第二行是2,依此類推,這個偽欄位可以用於限制查詢返回的總行數,而且rownum不能以任何表的名稱作為字首。 

ROWNUM的使用示例總結如下:

使用=時,只有rownum=1有用,=其它數值將返回空集。
使用<和<=時,能返回所需的行。
使用>和>=時,只有>=1時返回全表資料,其它只能返回空集。rownum對於大於某值的查詢條件,使用rownum>2是查不出記錄的,原因是由於rownum是一個總是從1開始的偽列,Oracle 認為rownum> n(n>1的自然數)這種條件依舊不成立,所以查不到記錄
小於與小於等於:
BYS@ bys3>select * from dept where rownum<2;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
BYS@ bys3>select * from dept where rownum<=2;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS

大於與大於等於:

BYS@ bys3>select * from dept where rownum>=1;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
BYS@ bys3>select * from dept where rownum>1;
no rows selected
BYS@ bys3>select * from dept where rownum>2;
no rows selected
BYS@ bys3>select * from dept where rownum>=2;
no rows selected         

等於:
BYS@ bys3>select * from dept where rownum=1;
    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
BYS@ bys3>select * from dept where rownum=2;
no rows selected           

不等於:--條件不成立返回空集
BYS@ bys3>select * from dept where rownum<>1;
no rows selected
#############

ROWNUM與ROWID在DML操作中的變化示例:

系統是按照記錄插入時的順序給記錄排的號,rowid也是順序分配的。  --查詢時不指定排序欄位時, oracle是按rowid升序取資料
rownum 表示查詢某條記錄在整個結果集中的位置,在查詢的結果集中順序分配的。
1.查詢ROWID與ROWID中的行號、ROWNUM
BYS@ bys3>select rowid,dbms_rowid.rowid_row_number(rowid) rowid_num,rownum,dept.* from dept order by deptno desc;
ROWID               ROWID_NUM     ROWNUM     DEPTNO DNAME          LOC
------------------ ---------- ---------- ---------- -------------- -------------
AAAFT7AAEAAAAIFAAD          3          4         40 OPERATIONS     BOSTON
AAAFT7AAEAAAAIFAAC          2          3         30 SALES          CHICAGO
AAAFT7AAEAAAAIFAAB          1          2         20 RESEARCH       DALLAS
AAAFT7AAEAAAAIFAAA          0          1         10 ACCOUNTING     NEW YORK
以其中一行記錄為例分析:
AAAFT7AAEAAAAIFAAC          2          3         30 SALES          CHICAGO
這一行的ROWID是AAAFT7AAEAAAAIFAAC ,按ROWID的演算法,可以得出資料塊中第2行
但是此行的ROWNUM是3,是在查詢出的結果集中的排序。很直觀的對比出ROWID中一行資料在資料塊中的第幾行與ROWNUM的號碼不是同一事物。
2.刪除一條資料
BYS@ bys3>delete dept where deptno=30;
1 row deleted.
BYS@ bys3>commit;
Commit complete.
3.查詢ROWID與ROWID中的行號、ROWNUM。發現ROWID與ROWID中的行號已經刪除,但是ROWNUM被自動順序分配了。
BYS@ bys3>select rowid,dbms_rowid.rowid_row_number(rowid) rowid_num,rownum,dept.* from dept order by deptno desc;
ROWID               ROWID_NUM     ROWNUM     DEPTNO DNAME          LOC
------------------ ---------- ---------- ---------- -------------- -------------
AAAFT7AAEAAAAIFAAD          3          3         40 OPERATIONS     BOSTON
AAAFT7AAEAAAAIFAAB          1          2         20 RESEARCH       DALLAS
AAAFT7AAEAAAAIFAAA          0          1         10 ACCOUNTING     NEW YORK
4.插入一條資料
BYS@ bys3>insert into dept values(99,'chedan','bj');
1 row created.
BYS@ bys3>commit;
Commit complete.
5.查詢ROWID與ROWID中的行號、ROWNUM。發現ROWID與ROWID中的行號自動向下分配而不是重用第3步中刪除的行的ROWID。ROWNUM依然自動順序分配
BYS@ bys3>select rowid,dbms_rowid.rowid_row_number(rowid) rowid_num,rownum,dept.* from dept order by deptno desc;
ROWID               ROWID_NUM     ROWNUM     DEPTNO DNAME          LOC
------------------ ---------- ---------- ---------- -------------- -------------
AAAFT7AAEAAAAIFAAE          4          4         99 chedan         bj
AAAFT7AAEAAAAIFAAD          3          3         40 OPERATIONS     BOSTON
AAAFT7AAEAAAAIFAAB          1          2         20 RESEARCH       DALLAS
AAAFT7AAEAAAAIFAAA          0          1         10 ACCOUNTING     NEW YORK
        

關於不同的排序結果使用ROWNUM,ROWNUM顯示會不會變化?  實驗結果是不會改變的

BYS@ bys3>select rownum,dept.* from dept;

    ROWNUM     DEPTNO DNAME          LOC
---------- ---------- -------------- -------------
         1         10 ACCOUNTING     NEW YORK
         2         20 RESEARCH       DALLAS
         3         40 OPERATIONS     BOSTON

         4         99 chedan         bj
BYS@ bys3>select rownum,dept.* from dept order by loc;
    ROWNUM     DEPTNO DNAME          LOC
---------- ---------- -------------- -------------
         3         40 OPERATIONS     BOSTON
         2         20 RESEARCH       DALLAS
         1         10 ACCOUNTING     NEW YORK

         4         99 chedan         bj

查表中最後一行記錄的方法:

BYS@ bys3>select * from dept where rowid in(select max(rowid) from dept);
    DEPTNO DNAME          LOC
---------- -------------- -------------
        40 OPERATIONS     BOSTON
BYS@ bys3>select * from dept where rownum<=(select count(*) from dept) minus select * from dept where rownum<=(select count(*)-1 from dept);
    DEPTNO DNAME          LOC
---------- -------------- -------------
        40 OPERATIONS     BOSTON

相關文章