PostgreSQL 烤麪包的味道好極了 TOAST

在傳統的數據庫中,DBA最恨  聽到的詞就是,我要使用 BLOB 字段,或者類似的類型來處理,huge的數據,他可能是一段圖形的在轉換後的“亂碼”,也可能是某個蹩腳 程序設計出來的 “怪胎”。如果是強有力的 DBER 可能直接駁回此類需求,但換來的是,“這不有這個字段嘛”, 爲啥不讓用,就你事多的,我就存幾行諸如此類的,“歡迎詞”。

PostgreSQL的管理員們是否會得到這樣的歡迎詞,就與他對Postgresql 的TOAST 的瞭解以有關。PG的默認的數據也大小是多少,8K,與SQL SERVER類似。MYSQL 是16KB的PAGE頁(默認)

那TOAST 首先的含義以及出現的需求就有了,因爲默認的數據庫的頁面,無法處理大容量的數據,所以針對大容量的數據就產生了一些字段的類型,來滿足某些“變態” 的需求。TOAST的含義其實就是通過對大字段的分解,將其分配到多個物理行上的方式。所以一個大面包,把他切片,然後就是叫“吐司”,TOAST的名詞來源可能是這樣來的。

當然如果僅僅想到就是將多個物理行進行組織後來存儲大型數據,未免想的還是少了一點,任何數據庫的數據要進行處理,都需要走內存的這一關,而如何將大字段與內存進行一個友好的“匹配”, 那就還得在費點功夫。

這裏如果對PG 陌生的話,先糾正一個概念,TOAST不是一個字段類型,他是一種底層數據存儲的方式,在其上方纔是那些需要擴展的字段類型,所以大型字段的存儲都要經過TOAST一關。

還是先感官再理論,否則按照什麼理論來發散,腦子大約會開始陷入停轉可能。

CREATE TABLE messages (message text);

INSERT INTO messages

SELECT (SELECT

        string_agg(chr(floor(random() * 26)::int + 65), '')

        FROM generate_series(1,10000))

FROM generate_series(1,10);

在你的PG上(我這裏的版本是11),運行了上面的語句,插入一堆數據後

我就得到了關於下面的這個圖,一個存儲數據的toast表的實際內容是什麼樣的

下面總結一下TOAST

1 PG的大容量數據和實體表不是存在一起的

2 PG會分配一個表來單獨存儲分出來的數據

3 這個表裏面會存儲大容量的數據。

4 在這個專門存儲toast的數據類型也是有選擇的,json , text,varchar, bytea等類型都會將數據存儲在這個實體表對應的toast表中。

5 TOAST 的在存儲數據的時候有四種模式  plain (不使用toast) extended (默認壓縮,既要壓縮,也要行外存儲)external (不壓縮,直接使用行外存儲)  Main模式(壓縮,但行外存儲會排在最後的選擇範圍)

那這裏就會對上面的產生一個問題,就是我們在處理這樣的數據的時候,這四種可以選擇的類型,那種是最優選,或者有什麼推薦,或者還是使用默認的模式。

參看上面的文字,其中對於上面四種模式中給出了建議,使用Main 模式

怎麼修改優化,參見下面的語句

ALTERTABLE YourTable
ALTERCOLUMN YourColumn SET STORAGE (PLAIN | EXTENDED | EXTERNAL |MAIN)
所以總結一下,PG 在處理比較大的字段上並沒有什麼問題,但涉及不合理的事情其實與能不能接受,
倒是無關,主要是數據庫種類這麼多,爲何非要在一個數據庫上“拼死拼活”, 不如找一個更合適字段處理特
別大的數據的數據庫,他不香嗎?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章