PostgreSQL中的OID

OID介紹

在PostgreSQL中隐解,對(duì)象標(biāo)識(shí)符Object identifiers (OIDs) 用來在整個(gè)數(shù)據(jù)集簇中唯一的標(biāo)識(shí)一個(gè)數(shù)據(jù)庫對(duì)象饿悬,這個(gè)對(duì)象可以是數(shù)據(jù)庫捐顷、表、索引狸膏、視圖沟饥、元組、類型等等湾戳。
同時(shí)OID也是系統(tǒng)內(nèi)部的一個(gè)數(shù)據(jù)類型贤旷,用4個(gè)字節(jié)的無符號(hào)整數(shù)表示。

OID的分配由系統(tǒng)中的一個(gè)全局OID計(jì)數(shù)器來實(shí)現(xiàn)砾脑,OID分配時(shí)會(huì)采用互斥鎖加以鎖定以避免多個(gè)要求分配OID的請(qǐng)求獲得相同的OID幼驶。

官方介紹 https://www.postgresql.org/docs/12/datatype-oid.html#DATATYPE-OID-TABLE

  1. Object identifiers (OIDs) are used internally by PostgreSQL as primary keys for various system tables. OID通常被用于系統(tǒng)表的主鍵,進(jìn)行系統(tǒng)表直接的鏈接韧衣。
  2. The oid type is currently implemented as an unsigned four-byte integer. Therefore, it is not large enough to provide database-wide uniqueness in large databases, or even in large individual tables. OID是由4字節(jié)無符號(hào)整形存儲(chǔ)盅藻,并且不能保證數(shù)據(jù)庫級(jí)的全局唯一性,甚至是數(shù)據(jù)量的大的表中元組的唯一性畅铭。

驗(yàn)證OID的數(shù)據(jù)集簇級(jí)別的全局唯一性

查看pg_class中表的OID氏淑,發(fā)現(xiàn)每個(gè)庫的相同系統(tǒng)表的OID一樣,這是由于他們都是從模板庫template1拷貝而來才導(dǎo)致一樣硕噩。

postgres=# select oid,relname from pg_class order by oid;
  oid  |                 relname
-------+-----------------------------------------
   112 | pg_foreign_data_wrapper_oid_index
   113 | pg_foreign_server_oid_index
   174 | pg_user_mapping_oid_index
   175 | pg_user_mapping_user_server_index
   548 | pg_foreign_data_wrapper_name_index
   549 | pg_foreign_server_name_index
   826 | pg_default_acl
   827 | pg_default_acl_role_nsp_obj_index
   828 | pg_default_acl_oid_index
  1136 | pg_pltemplate
  1137 | pg_pltemplate_name_index
  1213 | pg_tablespace
  1214 | pg_shdepend
  1232 | pg_shdepend_depender_index
  1233 | pg_shdepend_reference_index
  1247 | pg_type
  1249 | pg_attribute
  1255 | pg_proc
  1259 | pg_class
  1260 | pg_authid
  1261 | pg_auth_members
  1262 | pg_database
  1417 | pg_foreign_server
  1418 | pg_user_mapping
  2187 | pg_inherits_parent_index
  2328 | pg_foreign_data_wrapper
  2336 | pg_toast_2620
  2337 | pg_toast_2620_index
  2396 | pg_shdescription
  2397 | pg_shdescription_o_c_index
  2600 | pg_aggregate
  2601 | pg_am
  2602 | pg_amop
  2603 | pg_amproc
  2604 | pg_attrdef

我們?cè)诓煌瑤煜群蠼ū砑俨校碠ID其實(shí)不同。因此說OID是全數(shù)據(jù)集簇唯一的炉擅,而不只是一個(gè)database內(nèi)部唯一的辉懒。

postgres=# \d
No relations found.

postgres=# create table test(a int);
CREATE TABLE
postgres=# select oid,relname from pg_class where relname='test';;
  oid  | relname
-------+---------
 73735 | test
(1 row)

postgres=# \c testdb
You are now connected to database "testdb" as user "postgres".
testdb=# \d
No relations found.

testdb=# create table test(a int);
CREATE TABLE
testdb=# select oid,relname from pg_class where relname='test';;
  oid  | relname
-------+---------
 73738 | test
(1 row)

如何方便的知道OID對(duì)應(yīng)的對(duì)象是什么?

安裝目錄bin下面提供了一個(gè)oid2name命令用于查看某個(gè)OID代表的數(shù)據(jù)庫對(duì)象坑资,也可以查看某個(gè)數(shù)據(jù)庫對(duì)象下面的所有OID及其對(duì)象耗帕。

postgres@raspberrypi:bin $ oid2name --help
oid2name helps examining the file structure used by PostgreSQL.

Usage:
  oid2name [OPTION]...

Options:
  -d DBNAME      database to connect to
  -f FILENODE    show info for table with given file node
  -H HOSTNAME    database server host or socket directory
  -i             show indexes and sequences too
  -o OID         show info for table with given OID
  -p PORT        database server port number
  -q             quiet (don't show headers)
  -s             show all tablespaces
  -S             show system objects too
  -t TABLE       show info for named table
  -U NAME        connect as specified database user
  -V, --version  output version information, then exit
  -x             extended (show additional columns)
  -?, --help     show this help, then exit

postgres@raspberrypi:bin $ oid2name
All databases:
    Oid  Database Name  Tablespace
----------------------------------
  12407       postgres  pg_default
  12406      template0  pg_default
      1      template1  pg_default
  16384         testdb  pg_default

postgres@raspberrypi:bin $ oid2name -d postgres -S
From database "postgres":
  Filenode               Table Name
-----------------------------------
      2600             pg_aggregate
      2601                    pg_am
      2602                  pg_amop
      2603                pg_amproc
      2604               pg_attrdef
      1249             pg_attribute
      1261          pg_auth_members
      1260                pg_authid
      2605                  pg_cast
      1259                 pg_class
      3456             pg_collation
      2606            pg_constraint
      2607            pg_conversion
      1262              pg_database
      2964       pg_db_role_setting
       826           pg_default_acl
      2608                pg_depend
      2609           pg_description
      3501                  pg_enum
      3466         pg_event_trigger
      3079             pg_extension
      2328  pg_foreign_data_wrapper
      1417        pg_foreign_server
      3118         pg_foreign_table
      2610                 pg_index

OID實(shí)際上是如何存儲(chǔ)的穆端?

無論是系統(tǒng)表的OID還是用戶表創(chuàng)建時(shí)指定了WITH OIDS袱贮,OID在實(shí)際存儲(chǔ)上并不是放在Tuple的數(shù)據(jù)部分,而是隱藏在了HeapTupleHeaderData里体啰。

struct HeapTupleHeaderData
{
    union
    {
        HeapTupleFields t_heap;
        DatumTupleFields t_datum;
    }           t_choice;

    ItemPointerData t_ctid;     /* current TID of this or newer tuple (or a
                                 * speculative insertion token) */

    /* Fields below here must match MinimalTupleData! */

#define FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK2 2
    uint16      t_infomask2;    /* number of attributes + various flags */

#define FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK 3
    uint16      t_infomask;     /* various flag bits, see below */

#define FIELDNO_HEAPTUPLEHEADERDATA_HOFF 4
    uint8       t_hoff;         /* sizeof header incl. bitmap, padding */

    /* ^ - 23 bytes - ^ */

#define FIELDNO_HEAPTUPLEHEADERDATA_BITS 5
    bits8       t_bits[FLEXIBLE_ARRAY_MEMBER];  /* bitmap of NULLs */

    /* MORE DATA FOLLOWS AT END OF STRUCT */
};

/*
 * information stored in t_infomask:
 */
#define HEAP_HASNULL            0x0001  /* has null attribute(s) */
#define HEAP_HASVARWIDTH        0x0002  /* has variable-width attribute(s) */
#define HEAP_HASEXTERNAL        0x0004  /* has external stored attribute(s) */
#define HEAP_HASOID             0x0008  /* has an object-id field */
#define HEAP_XMAX_KEYSHR_LOCK   0x0010  /* xmax is a key-shared locker */
#define HEAP_COMBOCID           0x0020  /* t_cid is a combo cid */
#define HEAP_XMAX_EXCL_LOCK     0x0040  /* xmax is exclusive locker */
#define HEAP_XMAX_LOCK_ONLY     0x0080  /* xmax, if valid, is only a locker */

#define HeapTupleHeaderGetOid(tup) \
( \
    ((tup)->t_infomask & HEAP_HASOID) ? \
        *((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) \
    : \
        InvalidOid \
)

通過t_infomask & HEAP_HASOID判斷元組上是否包含OID攒巍,然后在通過HeapTupleHeaderGetOid取出OID的值。因此可以得之如果存在OID則被隱藏在t_hoff前面荒勇,如果不存在則該位置直接就是t_hoff柒莉。

綜上所述

  1. OID既是一個(gè)數(shù)據(jù)類型也是一個(gè)列藏列,用于數(shù)據(jù)庫內(nèi)部對(duì)象的默認(rèn)主鍵沽翔,作為系統(tǒng)表之間的關(guān)聯(lián)使用兢孝。
  2. OID是整個(gè)數(shù)據(jù)庫實(shí)例級(jí)別的全局唯一窿凤,用4字節(jié)無符號(hào)整形存儲(chǔ),無法保證全局唯一性跨蟹,不建議用戶表使用雳殊。
  3. OID存儲(chǔ)在HeapTupleHeader上,不是在數(shù)據(jù)部分窗轩。因此屬于隱藏列夯秃。

OID與物理存儲(chǔ)的數(shù)據(jù)目錄關(guān)系,請(qǐng)看:http://www.reibang.com/p/cd8c5b988e52

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載痢艺,如需轉(zhuǎn)載請(qǐng)通過簡信或評(píng)論聯(lián)系作者仓洼。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市堤舒,隨后出現(xiàn)的幾起案子色建,更是在濱河造成了極大的恐慌,老刑警劉巖舌缤,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件镀岛,死亡現(xiàn)場離奇詭異,居然都是意外死亡友驮,警方通過查閱死者的電腦和手機(jī)漂羊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來卸留,“玉大人走越,你說我怎么就攤上這事〕苌” “怎么了旨指?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長喳整。 經(jīng)常有香客問我谆构,道長,這世上最難降的妖魔是什么框都? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任搬素,我火速辦了婚禮,結(jié)果婚禮上魏保,老公的妹妹穿的比我還像新娘熬尺。我一直安慰自己,他們只是感情好谓罗,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布粱哼。 她就那樣靜靜地躺著,像睡著了一般檩咱。 火紅的嫁衣襯著肌膚如雪揭措。 梳的紋絲不亂的頭發(fā)上胯舷,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音绊含,去河邊找鬼需纳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛艺挪,可吹牛的內(nèi)容都是我干的不翩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼麻裳,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼口蝠!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起津坑,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤妙蔗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后疆瑰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體眉反,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年穆役,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寸五。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡耿币,死狀恐怖梳杏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情淹接,我是刑警寧澤十性,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站塑悼,受9級(jí)特大地震影響劲适,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜厢蒜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一霞势、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧郭怪,春花似錦支示、人聲如沸刊橘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽促绵。三九已至攒庵,卻和暖如春嘴纺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背浓冒。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來泰國打工栽渴, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人稳懒。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓闲擦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親场梆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子墅冷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容