問題來源: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,或者更好是用戶定義的序列號,來標識一個邏輯行。