MySQL切換PostgreSQL注意事項
# 切換流程
postgres相比mysql多了一層模式(Schema)的概念, 一個數(shù)據(jù)庫下可以有多個模式。 這里的模型名等價于以前的mysql的數(shù)據(jù)庫名。如果不指定默認是public。
# 注意事項
1、參數(shù)值不能用雙引號,需用單引號
2、字段名不能用``包起來,直接去掉就可以
3、json字段處理語法不同:mysql是用 -> '$.xxx'的語法去選取的, 而 postgreSQL 得用 ->>'xx' 語法選擇屬性
4、postgreSQL沒有convert函數(shù),用CAST函數(shù)替換
5、mysql可以使用force index強制走索引, postgres沒有,建議去掉
6、postgreSQL沒有ifnull函數(shù),用COALESCE函數(shù)替換
7、postgreSQL沒有date_format函數(shù),用to_char函數(shù)替換。例子:
to_char(time,'YYYY-MM-DD') => DATE_FORMAT(time,'%Y-%m-%d')
to_char(time,'YYYY-MM') => DATE_FORMAT(time,'%Y-%m')
to_char(time,'YYYYMMDDHH24MISS') => DATE_FORMAT(time,'%Y%m%d%H%i%s')
8、postgreSQL 的 select的字段必須是group by的字段里的 或者使用了聚合函數(shù)。mysql則沒有這個要求,非聚合列會隨機取值
錯誤例子
select name, age, count(*)from user group by age, score
這時 select name 是錯誤的, 應為group by里沒有這個字段,要么加上,要么變成select min(name)
9、Postgres數(shù)據(jù)庫中,同一事務中如果某次數(shù)據(jù)庫操作中出錯的話,那這個事務以后的數(shù)據(jù)庫操作都會出錯。如果有人去捕獲了事務異常后又去執(zhí)行數(shù)據(jù)庫操作就會導致這個問題。mysql貌似不會有這個問題,解決方法用if else替代異常
10、mysql是支持自動類型轉換的,postgreSQL是強數(shù)據(jù)類型,字段類型和參數(shù)值類型之間必須一樣否則就會拋出異常。
解決辦法一般有兩種:手動修改代碼里的字段類型和傳參類型保證 或者 postgreSQL表字段類型,反正保證雙方一一對應;手動添加自動隱式轉換函數(shù),達到類似mysql的效果
不要亂添加隱式轉換函數(shù),可能導致 Could not choose a best candidate operator 異常 和 # operator is not unique 異常 就是在操作符比較的時候有多個轉換邏輯不知道用哪個了,死循環(huán)了
11、postgreSQL輔助腳本
select name, age, count(*)from usergroup by age, score
9、Postgres數(shù)據(jù)庫中,同一事務中如果某次數(shù)據(jù)庫操作中出錯的話,那這個事務以后的數(shù)據(jù)庫操作都會出錯。如果有人去捕獲了事務異常后又去執(zhí)行數(shù)據(jù)庫操作就會導致這個問題。mysql貌似不會有這個問題,解決方法用if else替代異常
10、mysql是支持自動類型轉換的,postgreSQL是強數(shù)據(jù)類型,字段類型和參數(shù)值類型之間必須一樣否則就會拋出異常。
不要亂添加隱式轉換函數(shù),可能導致 Could not choose a best candidate operator 異常 和 # operator is not unique 異常 就是在操作符比較的時候有多個轉換邏輯不知道用哪個了,死循環(huán)了
11、postgreSQL輔助腳本
①批量修改timestamptz腳本,修改表字段類型 timestamptz 為 timestamp, 因為我們說過前者無法與LocalDateTime對應上
timestamp without time zone 就是 timestamp;timestamp with time zone 就是 timestamptz
DO $$DECLARE rec RECORD;BEGIN FOR rec IN SELECT table_name, column_name,data_type FROM information_schema.columns where table_schema = '要處理的模式名' AND data_type = 'timestamp with time zone' LOOP EXECUTE 'ALTER TABLE ' || rec.table_name || ' ALTER COLUMN ' || rec.column_name || ' TYPE timestamp'; END LOOP;END $$;
②批量修改模式名下的所有字段類型為timestamp的并且字段名為 create_time 或者 update_time的字段的默認值為 CURRENT_TIMESTAMP-- 注意 || 號拼接的后面的字符串前面要有一個空格
-- 注意 || 號拼接的后面的字符串前面要有一個空格DO $$DECLARE rec RECORD;BEGIN FOR rec IN SELECT table_name, column_name,data_type FROM information_schema.columns where table_schema = '要處理的模式名' AND data_type = 'timestamp without time zone' -- 修改的字段名 and column_name in ('create_time','update_time') LOOP EXECUTE 'ALTER TABLE ' || rec.table_name || ' ALTER COLUMN ' || rec.column_name || ' SET DEFAULT CURRENT_TIMESTAMP;'; END LOOP;END $$;
timestamp without time zone 就是 timestamp;timestamp with time zone 就是 timestamptz
DO $$DECLARErec RECORD;BEGINFOR rec IN SELECT table_name, column_name,data_typeFROM information_schema.columnswhere table_schema = '要處理的模式名'AND data_type = 'timestamp with time zone'LOOPEXECUTE 'ALTER TABLE ' || rec.table_name || ' ALTER COLUMN ' || rec.column_name || ' TYPE timestamp';END LOOP;END $$;
②批量修改模式名下的所有字段類型為timestamp的并且字段名為 create_time 或者 update_time的字段的默認值為 CURRENT_TIMESTAMP-- 注意 || 號拼接的后面的字符串前面要有一個空格
-- 注意 || 號拼接的后面的字符串前面要有一個空格DO $$DECLARErec RECORD;BEGINFOR rec IN SELECT table_name, column_name,data_typeFROM information_schema.columnswhere table_schema = '要處理的模式名'AND data_type = 'timestamp without time zone'-- 修改的字段名and column_name in ('create_time','update_time')LOOPEXECUTE 'ALTER TABLE ' || rec.table_name || ' ALTER COLUMN ' || rec.column_name || ' SET DEFAULT CURRENT_TIMESTAMP;';END LOOP;END $$;
posted on 2024-07-15 17:52 Benjamin 閱讀(91) 評論(0) 編輯 收藏 引用 所屬分類: 數(shù)據(jù)庫

