iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 8
2
Postgresql 的字元資料型態 

今天來探討 Postgresql 的字串資料型態,相信此資料型態為大家所熟悉.
但是 Postgresql 在 ANSI SQL 的標準之上,做了些加強.

首先是文件
https://docs.postgresql.tw/the-sql-language/data-types/character-types

接著來看一些測試

select octet_length('abcde'::varchar(1)) as "vc_1"
     , octet_length('abcde'::varchar(5)) as "vc_5"
     , octet_length('abcde'::varchar(10)) as "vc_10"
     , octet_length('abcde'::char(1)) as "c_1"
     , octet_length('abcde'::char(5)) as "c_5"
     , octet_length('abcde'::char(10)) as "c_10";

+------+------+-------+-----+-----+------+
| vc_1 | vc_5 | vc_10 | c_1 | c_5 | c_10 |
+------+------+-------+-----+-----+------+
|    1 |    5 |     5 |   1 |   5 |   10 |
+------+------+-------+-----+-----+------+

octet_length() 回報 string 使用的 bytes.
觀察上面的結果,可以知道 char(n) 型態,會浪費空間.

char(n) , varchar(n) 相信大家應該很熟悉了.
但是在 Postgresql 中並不建議使用,會保留主要是為了跟 ANSI SQL 標準相容,
當我們執行由其他資料庫匯出的 SQL Command 時,可以正常使用.

觀察以下這段 SQL Command 執行結果.

create table ithelp190923 (
  id int generated always as identity primary key
, vstr varchar not null
, txt text not null
);

commit;

insert into ithelp190923 (vstr, txt)
select rpad('a', 5001, 'pad'), rpad('a', 5001, 'pad');

commit;

select length(vstr) as "vstr_lngth"
     , octet_length(vstr) as "vstr_bytes"
     , length(txt) as "vstr_lngth"
     , octet_length(txt) as "vstr_bytes"
  from ithelp190923;

+------------+------------+------------+------------+
| vstr_lngth | vstr_bytes | vstr_lngth | vstr_bytes |
+------------+------------+------------+------------+
|       5001 |       5001 |       5001 |       5001 |
+------------+------------+------------+------------+

可以發現使用了 varchar , text. 而且都有很大的容量.

實際上在 Postgresql 中是以 text 為主要儲存的方式.而且容量達到 1GB.

varchar, text 在平常的應用中,提供很大的彈性.
以敝人以往的經驗,下載一些資料,是CSV格式的,要倒入資料庫中,最麻煩的就是
欄位長度的設定,往往需要反覆修改,耗時且繁瑣.當使用 Postgresql text 
型態,就很方便的倒入.這時候再計算各欄位最大長度,若需要轉到其他種資料庫,
由 Postgresql 來做前置處理也是一個好方法.

但是這種無截位的方式,也會來一些不便.當我們需要對輸入的資料做長度的限制時,
該如何處理?

在 Postgresql 有 ANSI SQL 的 Check
https://www.postgresql.org/docs/current/ddl-constraints.html#DDL-CONSTRAINTS-CHECK-CONSTRAINTS

來看以下的例子

create table ithelp190923a (
  id int generated always as identity primary key
, txt1 text not null check (length(txt1) <= 5)
, txt2 text not null check (txt2 ~ '^[[:alpha:]]{4}$')
);

commit;

insert into ithelp190923a (txt1, txt2) values
('abcde', 'abcd');

commit;

Postgresql 提供了 ANSI SQL 標準的 check, 搭配使用,會比 varchar(n)
的方式更靈活.
check 在之後的探討中,也會活躍的出現.

今天就先把最基本的字元資料型態,就 Postgresql 與其他資料庫產品比較特別需要注意
的地方,提出來供大家參考.至於相關函數等等,請參考

https://docs.postgresql.tw/the-sql-language/functions-and-operators/string-functions-and-operators


上一篇
Postgresql 的資料型態
下一篇
Postgresql 的字元資料型態的一些特殊功能
系列文
以Postgresql為主,聊聊資料庫.31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言