Postgresql 隱式轉換 — 資料庫也來一次 「中保研」

  • 2020 年 2 月 14 日
  • 筆記

快要過年了,此篇作為2019年最後一篇的技術文字,年後還有一批正在路上,感謝大家一年多的關注。

——————————————————————————————

汽車界最近最熱的話題是,中保研碰撞試驗 ,所以資料庫是不是也應該來一次碰撞測試,繼 SQL SERVER ,和 MYSQL 的隱式轉換文字後,POSTGRESQL 也撞撞看。

作為一個未來更自由和先進的資料庫,部分(傳統)企業會選擇一種理想的資料庫及原型,別的資料庫遇到的問題,在POSTGRESQL 存在嗎,那如何注意,實際上隱式轉換會給我們使用POSTGRESQL 帶來什麼影響這是需要了解和清楚的。

這裡我們要列出的是POSTGRESQL 支援的數據常用類型(因為POSTGRESQL 支援的類型比較多,並且有些不是傳統DBA 能理解的類型(例如範圍類型),這次僅僅對字元類型進行「碰撞」)

當然其中的含義可不僅僅是弄清楚,這裡還有更深層次的一層需求。(不建議使用char類型,原因請參見之前的文字)

目前postgresql 存儲的數據的字元類型主要有三種 varchar char 和 text

1 先看一下這三種類型的隱式轉換是否存在,如果存在並且給錯對應的類型會有什麼結果。

create table conver_test (id SERIAL primary key, info char(500),info2 varchar(500),info3 text, c_time timestamp);

insert into conver_test (info,info2,info3,c_time) select md5(random()::char),md5(random()::varchar),md5(random()::text),clock_timestamp() from generate_series(1,100000);

create index ix_conver on conver_test (info,info2,info3);

在建立好測試的數據後,我們開始下一步的探索實驗

1 char 的類型如果接受到varchar 的字元還是否可以走索引 (info 為 char , info2 varchar, info3 text)

char 的欄位接受 varchar 的類型是可以走索引的

char 的欄位接受本身的類型是可以走索引的

char 的欄位接受text 是不可以走索引

2 作為常用的varchar 欄位類型,在接受不同的類型會有什麼反應

1 接受本身同樣的字元類型,一定是能走索引的

2 而如果將字元類型更換為char , 那就不走索引了,開始走了全表掃描

3 最後將將字元的類型定義為text ,結果很有趣的走了索引

3 最後就是text 欄位的形式了

結果出人意料,啥格式的都能走索引。

這裡要清楚一個概念,就能大概了解到 CHAR VARCHAR 為什麼互不給對方面子,CHAR 類型的在定義大小後,不足的位置是要進行空格補齊的,而varchar 不會,或許就是雙方不給面子的一個原因。

到這裡先小結一下,POSTGRESQL 資料庫和別的資料庫在字元存儲方面還是可圈可點的,例如在別的資料庫中提出的text類型相對於其他的類型雖然存儲的內容要多,但是性能要低的情況,在POSTGRESQL 是不存在的,也就是你使用char , varchar ,text 存儲大小相同的字元類型的時候,除了char 的性能可能會稍微低一些,varchar , text 是不會有性能上的差別(同等字元量上,但存儲的數據結構不同)這也就造成很多表設計中的字元大部分都是text 上面的結果也看到了,這可能就是原因之一。

另外最近在群裡面討論的一個問題,關於一個字元,佔用幾個位元組,POSTGRESQL 如果你使用的字符集是 utf8 就想當一個字會佔據(1-4)個位元組,並且包含漢子不會在有亂碼的可能。UTF8這是一種unicode 的編碼,所以要盡量讓你的客戶端和伺服器端的字符集都是utf8 這樣一般是不會出現亂碼的問題。(每種資料庫是不一樣的,MYSQL 是 UTF8 可和POSTGRESQL 的UTF8 不是一碼事)

其中PostgreSQL掃描器/解析器將詞法元素分為五個基本類別:整數、非整數、字元串、標識符和關鍵字。大多數非數值類型的常量首先被歸類為字元串。SQL語言定義允許使用字元串指定類型名稱,並且在PostgreSQL中可以使用這種機制來按照正確的路徑啟動解析器。

那我們在不指定類型的情況下,POSTGRESQL 的隱式轉換又會是怎樣的情況

很顯然在POSTGRESQL 每種類型的自動隱式轉換都是令人滿意的。

另外純屬個人感受(僅僅代表個人此時此刻的知識和能力範疇),POSTGRESQL 的字元處理方面尤其在使用了text類型來處理字元,相對比其他的資料庫系統來說是有優勢的(從擴展性,處理速度,限制 對比其他的資料庫),上面的部分結果也能對以上的看法有所支援。