Ⅰ 挖一挖:PostgreSQL Java里的double類型存儲到varchar精度丟失問題
前言
在使用Java JDBC將double類型數據插入到PostgreSQL資料庫的表中時,發現不同版本的PostgreSQL(11與12及後續版本)插入的數據結果不一致。本文將探討此問題的可能原因和解決方法。
分析
在Java代碼中,使用的是相同的JDBC驅動。問題可能出在驅動層根據伺服器端不同版本發送的數據不同,或伺服器端對於客戶端傳入的數據處理方式不同。為了尋找答案,我們查看了SQL日誌。
通過修改`postgresql.conf`文件,將`log_statement`設置為`all`,我們得以查看詳細的SQL日誌。結果表明,在伺服器端綁定參數值時,數據在PG11與PG12版本中發生了變化。進一步,檢查JDBC客戶端驅動層日誌,發現了關鍵信息。
在PG12的日誌中,我們注意到當`extra_float_digits`參數設置為3時,數據出現精度損失。而在PG11中,相同參數設置下,數據保留了較高的精度。這揭示了問題的根源在於伺服器端處理浮點數的方式在不同版本間存在差異。
總結與模擬重現
綜合分析,驅動層發送給伺服器端的指令在不同PostgreSQL版本間並未發生變化,問題在於伺服器端對於`extra_float_digits`參數值為3時,處理浮點數轉為`float8`(double precision)的機制不同。在PG11版本中,數據在轉換過程中保留了較高的精度,而在PG12及後續版本中,則出現了精度損失。
了解`extra_float_digits`參數用於控制浮點數值的顯示位數,對於理解問題的產生至關重要。該參數調整用於文本輸出浮點值的位數,不同設置影響了輸出的精度和易讀性。通過對比不同版本的處理方式,我們確認了問題原因在於伺服器端在處理浮點數時的精度控制不同。
總結,通過對比分析兩端的日誌信息,可以深入挖掘並解決此類問題。同時,通過簡單的SQL片段可以重現問題,有助於進一步驗證和理解問題的根源。
參考資源
本文基於以下資源撰寫:
enterprisedb.com/blog/j...
jdbc.postgresql.org/doc...
postgresqlco.nf/doc/zh/...