前言
最近遇到一個問題就是字段名過長,會被pg給截斷,導致原始字段和下游用的的字段不一樣,就會報錯。當然,小伙伴可能會說為什么會用那么長的字段名,每個應用程序里面處理不一樣,我們數據字段每次被使用就會加一個后綴,用來標識它是在哪一層里面被使用的,隨著被使用的越來越多,就會超長。報錯類似于下面這樣(字段名是為了測試這個名字故意這樣取的,實際不會這樣用):
test=# ALTER TABLE "test1" RENAME TO "123456789_123456789_123456789_123456789_123456789_123456789_123456789_";ERROR: relation "test1" does not existNOTICE: identifier "123456789_123456789_123456789_123456789_123456789_123456789_123456789_" will be truncated to "123456789_123456789_123456789_123456789_123456789_123456789_123"
這只是這個NOTICE,在命令行里面可以報出來,但是如果是在Java程序里面,執行的時候是不會報這個錯,只會在最后執行失敗的時候拋出字段不存在的異常。
解決方式
1.查找資料后發現,pg的默認長度是NAMEDATALEN - 1 ,就是NAMEDATALEN 默認是64,所以字段最大長度是63。
下面這個來自于官方文檔:
The system uses no more than NAMEDATALEN-1 bytes of an identifier; longer names can be written in commands, but they will be truncated. By default, NAMEDATALEN is 64 so the maximum identifier length is 63 bytes. If this limit is problematic, it can be raised by changing the NAMEDATALEN constant in src/include/pg_config_manual.h.
這個文檔也說了,如果想修改的話需要修改src/include/pg_config_manual.h的NAMEDATALEN常量,也就是說想把這個長度改長的話,得修改源碼在重新編譯pg才行。而且這個長度不僅僅是字段名,包括表名也是一樣,都不能超過63,創建表超過也會給你截斷掉,這個比較坑的就是在應用程序里面不報錯,只有當使用到這個表時才發現對不上。
2.如果你不想重新編譯pg,那就只能從程序里面去處理最大長度問題,可以在生成字段或者表名里面加一個判斷函數,如果超過了63,會被修改為一個比較短的名字,是否需要儲存原來超長的字段名也可以根據場景來控制,假設要儲存,中間加一張映射表,解決長名字和短名字之間的映射問題。
參考資料:
https://eichisanden.hateblo.jp/entry/2018/10/06/231210
https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
https://www.postgresql.org/docs/9.4/sql-syntax-lexical.html
https://til.hashrocket.com/posts/8f87c65a0a-postgresqls-max-identifier-length-is-63-bytes