PostgreSQL隱藏字段tableoid

問題來源:app

今天羣裏有人問:tableoid字段在每行都有,並且一個表裏面的值是重複的,這樣不合理......學習

 

所以作了一些分析:spa

 

1)建立了一個表code

apple=# \d test_time
             Table "public.test_time"
 Column |            Type             | Modifiers
--------+-----------------------------+-----------
 id     | integer                     |
 date   | timestamp without time zone |

 

2)查看該表的全部字段 包括隱藏的:對象

apple=# select * from pg_attribute where attrelid in (select oid from pg_class where relname = 'test_time');
 attrelid | attname  | atttypid | attstattarget | attlen | attnum | attndims | attcacheoff | atttypmod | attbyval | attstorage | attalign | attnotnull | atthasdef | attisdropped | attislocal | attinhcount | attcollation | attacl | attoptions | attfdwoptions
----------+----------+----------+---------------+--------+--------+----------+-------------+-----------+----------+------------+----------+------------+-----------+--------------+------------+-------------+--------------+--------+------------+---------------
    33433 | tableoid |       26 |             0 |      4 |     -7 |        0 |          -1 |        -1 | t        | p          | i        | t          | f         | f            | t          |           0 |            0 |        |            |
    33433 | cmax     |       29 |             0 |      4 |     -6 |        0 |          -1 |        -1 | t        | p          | i        | t          | f         | f            | t          |           0 |            0 |        |            |
    33433 | xmax     |       28 |             0 |      4 |     -5 |        0 |          -1 |        -1 | t        | p          | i        | t          | f         | f            | t          |           0 |            0 |        |            |
    33433 | cmin     |       29 |             0 |      4 |     -4 |        0 |          -1 |        -1 | t        | p          | i        | t          | f         | f            | t          |           0 |            0 |        |            |
    33433 | xmin     |       28 |             0 |      4 |     -3 |        0 |          -1 |        -1 | t        | p          | i        | t          | f         | f            | t          |           0 |            0 |        |            |
    33433 | ctid     |       27 |             0 |      6 |     -1 |        0 |          -1 |        -1 | f        | p          | s        | t          | f         | f            | t          |           0 |            0 |        |            |
    33433 | id       |       23 |            -1 |      4 |      1 |        0 |          -1 |        -1 | t        | p          | i        | f          | f         | f            | t          |           0 |            0 |        |            |
    33433 | date     |     1114 |            -1 |      8 |      2 |        0 |          -1 |        -1 | t        | p          | d        | f          | f         | f            | t          |           0 |            0 |        |            |
(8 rows)

 

能夠發現有6個隱藏的字段,其中cmax xmax cmin xmin都跟事物有關,在PG事物處理相關文章中能夠常常看到。blog

剛好前段時間研究PG表去重複數據用過ctid,物理地址塊上的編號,所以今天再來學習一下tableoid。繼承

 

3)初步分析結果:事務

   A. 存磁盤的時候,數據是一行一行的存儲,有必要知道該行數據屬於哪一個表。(那麼若是支持列存儲的話,確實能夠對這些數據進行壓縮了,只存一條便可。)get

   B. 繼承表的狀況,知道數據是在哪一個子表裏面。it

 

4)視圖不會有默認字段:

apple=# select * from pg_attribute where attrelid in (select oid from pg_class where relname in (select viewname from pg_views)) and attnum < 0;
 attrelid | attname | atttypid | attstattarget | attlen | attnum | attndims | attcacheoff | atttypmod | attbyval | attstorage | attalign | attnotnull | atthasdef | attisdropped | attislocal | attinhcount | attcollation | attacl | attoptions | attfdwoptions
----------+---------+----------+---------------+--------+--------+----------+-------------+-----------+----------+------------+----------+------------+-----------+--------------+------------+-------------+--------------+--------+------------+---------------
(0 rows)

 

5)之後想查看錶的oid不再用去pg_class裏面找了:

apple=# select tableoid from test_time;
 tableoid
----------
    33433
(1 row)

 

搞了半天發現也沒啥,白折騰了......

 

-----------------------

在建立表的時候,能夠選擇是否建立有OID的隱藏列:create table xxx (id int,...) with oids;

apple=# create table test_without_oid(id int, info text, crt_time timestamp) without oids;
CREATE TABLE
apple=# select oid, * from test_without_oid ;
ERROR:  column "oid" does not exist
LINE 1: select oid, * from test_without_oid ;
               ^
HINT:  Perhaps you meant to reference the column "test_without_oid.id".
apple=# select * from test_without_oid ;
 id | info | crt_time
----+------+----------
(0 rows)


apple=# create table test_with_oid(id int, info text, crt_time timestamp) with oids;
CREATE TABLE
apple=# select oid, * from test_with_oid ;
 oid | id | info | crt_time
-----+----+------+----------
(0 rows)

 

--2017-05-05

 

 

參考消息:

每一個表都有幾個系統字段,這些字段是由系統隱含定義的。 所以,這些名字不能用於用戶定義的字段名。 (請注意這些限制與這個名字是否關鍵字無關;把名字用引號括起來並不能讓你逃離這些限制。) 你實際上不須要注意這些字段,只要知道它們存在就能夠了。

oid
行的對象標識符(對象 ID)。這個字段只有在建立表的時候使用了 WITH OIDS,或者是設置了配置參數 default_with_oids 時出現。 這個字段的類型是 oid(和字段同名); 參閱Section 8.12 獲取有關這種類型的更多信息。
tableoid
包含本行的表的 OID。這個字段對那些從繼承層次中選取的查詢特別有用(參閱 Section 5.8), 由於若是沒有它的話,咱們就很難說明一行來自哪一個獨立的表。 tableoid 能夠和pg_class 的 oid 字段鏈接起來獲取表名字。

xmin
插入該行版本的事務的標識(事務 ID)。(注意:在這個環境裏, 一個行版本是一行的一個狀態;一行的每次更新都爲同一個邏輯行建立一個新的行版本。)

cmin
在插入事務內部的命令標識(從零開始)。

xmax
刪除事務的標識(事務ID),若是不是被刪除的行版本,那麼是零。 在一個可見行版本里,這個字段有多是非零。這一般意味着刪除事務尚未提交, 或者是一個刪除的企圖被回滾掉了。

cmax
在刪除事務內部的命令標識符,或者是零。

ctid
一個行版本在它所處的表內的物理位置。請注意,儘管 ctid 能夠用於很是快速地定位行版本,但每次 VACUUM FULL 以後, 一個行的 ctid 都會被更新或者移動。 所以 ctid 是不能做爲長期的行標識符的。 應該使用OID,或者更好是用戶定義的序列號,來標識一個邏輯行。

 
相關文章
相關標籤/搜索