MathJax

MathJax-2

MathJax-3

Google Code Prettify

置頂入手筆記

EnterproseDB Quickstart — 快速入門筆記

由於考慮採用 EnterpriseDB 或是直接用 PostgreSQL 的人,通常需要一些入手的資料。這邊紀錄便提供相關快速上手的簡單筆記 ~ 這篇筆記以 資料庫安裝完畢後的快速使用 為目標,基本紀錄登入使用的範例:

2017年8月29日 星期二

變更 Postgres 9.x 列舉(enum)資料型態的標籤值

Postgres 的 enum 資料型態類似 C 語言裡面的 enum,可以用數值指稱一組標籤,可以節省資料存放的空間。資料存取上,與一般字串欄位沒什麼不同。並且比起直接存放一些固定選項的字串的欄位,使用 enum 還可以建立比較快速的 Index,直接放字串的話,在 PGSQL 只能作次佳的索引。

不過有時候會希望調整標籤的品項,要怎麼樣作調整?

截至 PGSQL 9.x 為止,還沒有支援變更 enum Type 的語法。
如果要調整內容的話,需要去異動存放 enum 資料型態資訊的系統表 pg_enum
先建立一個 enum 型態,並弄一個示範表格
edb=# CREATE TYPE zhday AS ENUM (
  '星期一', '星期二', 
  '星期三', '星期四', 
  '星期五', '星期六', 
  '星期七');
CREATE TYPE
edb=# CREATE TABLE monkey_memo(week zhday, memo TEXT);
CREATE TABLE
edb=# INSERT INTO monkey_memo VALUES
('星期一', '猴子穿新衣'),
('星期二', '猴子肚子餓'),
('星期三', '猴子去爬山'),
('星期四', '猴子去考試'),
('星期五', '猴子去跳舞'),
('星期六', '猴子去斗六'),
('星期七', '猴子刷油漆');
INSERT 0 7

查看一下
edb=# select * from monkey_memo ;
  week  |    memo    
--------+------------
  星期一 | 猴子穿新衣
  星期二 | 猴子肚子餓
  星期三 | 猴子去爬山
  星期四 | 猴子去考試
  星期五 | 猴子去跳舞
  星期六 | 猴子去斗六
  星期七 | 猴子刷油漆
(7 rows)

查看 pg_enum 相關內容
edb=# select * from pg_enum where enumtypid = 'zhday'::regtype;
 enumtypid | enumsortorder | enumlabel 
-----------+---------------+-----------
     16470 |             1 | 星期一
     16470 |             2 | 星期二
     16470 |             3 | 星期三
     16470 |             4 | 星期四
     16470 |             5 | 星期五
     16470 |             6 | 星期六
     16470 |             7 | 星期七
(7 rows)
 
edb=# select enum_range(NULL::zhday);
                     enum_range                     
----------------------------------------------------
 {星期一,星期二,星期三,星期四,星期五,星期六,星期七}
(1 row)

我們可以看到,enumsortorder 是實際上表格欄位上儲存的實際資料:數字比起長長一串字串,存放的空間要小的多了。此外,還可以把標籤當作數字比大小。

現在讓我們把「星期七」改成「星期天」
edb=# UPDATE pg_enum SET enumlabel = '星期天'
      WHERE enumtypid = 'zhday'::regtype
      AND enumlabel = '星期七';
UPDATE 1
edb=# SELECT * FROM pg_enum WHERE enumtypid = 'zhday'::regtype;
 enumtypid | enumsortorder | enumlabel 
-----------+---------------+-----------
     16470 |             1 | 星期一
     16470 |             2 | 星期二
     16470 |             3 | 星期三
     16470 |             4 | 星期四
     16470 |             5 | 星期五
     16470 |             6 | 星期六
     16470 |             7 | 星期天
(7 rows)
 
edb=# select enum_range(NULL::zhday);
                     enum_range                     
----------------------------------------------------
 {星期一,星期二,星期三,星期四,星期五,星期六,星期天}
(1 row)

我們可以檢查一下,剛剛的調整不會變更到表格內既有存放的內容
edb=# select * from monkey_memo ;
  week  |    memo    
--------+------------
  星期一 | 猴子穿新衣
  星期二 | 猴子肚子餓
  星期三 | 猴子去爬山
  星期四 | 猴子去考試
  星期五 | 猴子去跳舞
  星期六 | 猴子去斗六
  星期天 | 猴子刷油漆
(7 rows)

第十版已經支援透過 ALTER TYPE 指令來變更標籤的語法
ALTER TYPE zhday RENAME VALUE '星期七' TO '星期天';

最後補充一下,在 PostgreSQL 中建議 enum 的理由。
在有些主流資料庫下有提供 Bitmap 索引物件,一般是針對只會出現固定資料值的欄位建立。而 PGSQL 沒有對全表格的 Bitmap 索引,只有 In-Memory Bitmap 演算(Bitmap Heap Scan,Bitmap Index Scan)。一般會建議在 PGSQL 使用 GIN Index 對應其他資料庫的 Bitmap Index;但是如果在規劃上就能預見標的欄位的資料性質是當作標籤使用的話,就可以考慮對該欄位宣告 enum 型態。


參考資料

沒有留言:

張貼留言