Postgresql
為什麼 jsonb 使用更多的空間來儲存整數?
我做了一些小測試來嘗試這些數據類型,發現了一些令人費解的結果。
概括:
jsonb 為整數使用的空間比字元串多:
select pg_column_size('{"a":"1"}'::jsonb) as json_size
18
select pg_column_size('{"a":1}'::jsonb) as json_size
28
為什麼使用整數時 jsonb 的大小會膨脹?
長版:
我最初對使用整數數組感興趣,這裡是那些測試。在每對逗號分隔的數字中,第一個對應的是
json_size
(bytes),第二個數字是array_size
(bytes)。select pg_column_size('[]'::jsonb) as json_size, pg_column_size(array[]::smallint[]) as array_size
8,16
select pg_column_size('[1]'::jsonb) as json_size, pg_column_size(array[1]::smallint[]) as array_size
20,26
檢查 jsonb 是否真的將整數儲存為純文字;如果是這樣,那麼下一個應該為 jsonb 多使用 4 個字節:
select pg_column_size('[12345]'::jsonb) as json_size, pg_column_size(array[12345]::smallint[]) as array_size
22,26
奇怪,它多用了 2 個字節,不知道這意味著什麼。現在嘗試一些更實際和現實的數據:
select pg_column_size('[123,234,345,456,567,678,789,890]'::jsonb) as json_size, pg_column_size(array[123,234,345,456,567,678,789,890]::smallint[]) as array_size
104,40
這裡的jsonb怎麼了?是什麼導致它膨脹?也許如果我使用具有較少字元的較小數字……
select pg_column_size('[1,2,3,4,5,6,7,8]'::jsonb) as json_size, pg_column_size(array[1,2,3,4,5,6,7,8]::smallint[]) as array_size
104,40
沒有。字元串呢?
select pg_column_size('["1","2","3","4","5","6","7","8"]'::jsonb) as json_size, pg_column_size(array[1,2,3,4,5,6,7,8]::smallint[]) as array_size
48,40
似乎 jsonb 喜歡字元串而不是整數。
我很快就制定了一個經驗法則,即我應該只在 jsonb 中使用字元串,而對數字數據使用原生整數或數組,但我不知道這個規則是否被誤導或為什麼會發生這種異常。
這很簡單。JSON 沒有整數的概念,只有“數字”。從文件
在將文本 JSON 輸入轉換為 jsonb 時,RFC 7159 描述的原始類型有效地映射到原生 PostgreSQL 類型,如表 8-23 所示。
該表顯示一個 JSON“數字”被映射到一個數字。數字的最大精度是
小數點前最多 131072 位;小數點後最多 16383 位
但是,我認為它實際上並沒有儲存它。它確實儲存了某種數字。坦率地說,數字來源很難理解。
如果它適合您的工作負載,則使用 smallint 數組顯然會更好。它減少了用於打包的浪費空間,也減少了數據本身浪費的空間。
smallint[]
然而
- 不支持相同範圍的數字。
- 不支持嵌入不同類型。
- 根本不支持任何精度。
- 與網路客戶端不能很好地交流。