帮助中心/最新通知

质量为本、客户为根、勇于拼搏、务实创新

< 返回文章列表

【服务器相关】基于PostgreSQL和mysql数据类型对比兼容

发表时间:2025-06-16 03:46:00 小编:油条

1、数值类型

整数:

mysql中的整数类型和pg相比,两者有以下区别:

mysql:mysql中支持int 1,2,3,4,8 字节,同时支持有符号,无符号。并且mysql中支持在数值列中指定zerofill,用来将存储的数值通过填充0的方式达到指定数据类型的长度(mysql8开始不建议使用ZEROFILL属性,并且在将来的MySQL版本中将不再支持该属性)。

pg:pg支持 int 2,4,8 字节,且数值都是有符号的。

mysql整数类型:

pg整数类型:

那么对于mysql中的1,3字节整型,或者无符号整型以及zerofill特性,在pg中该如何实现呢?

在pg中我们可以使用domain来实现mysql中的1,3字节整数以及无符号整型。

创建uint8,8字节无符号整型

OraclePostgreSQLVarchar2varcharnumbernumericdatetimestamp/date/time不支持boolean,可通过0/1代替支持booleannullnull

2、基本函数差异

itemOraclePostgreSQL
系统当前时间SYSDATE

now()/CURRENT_TIMESTAMP/CURRENT_DATE/CURRENT_TIME

对时间或数字截取trunc()date_trunc()
to_char,to_number, to_date自动格式转换

需指定日期格式

eg:to_date(timejoin,’yyyy-MM-dd’)

判空操作nvl()coalesce()
条件判断decode()case…when…then
dual伪表支持不支持(查询常量不需要加from)

其他用法一致的常用函数:

mod(n2,n1) — n2除n1取余数; sign(n) — 判断n的符号;

floor(n) — 取小于等于n的正整数; ceil() — 取大于等于n的正整数;

round(n,integer) — 对n四舍五入,保留位数为integer; trunc(n,integer) — 对n截取,截取保留的位数为integer;

covert(char,dest_sest,source_set) — 字符集转换,例:convert(username, ‘ZHS16GBK’,’UTF8′);

cast(expr as type_name) — 数据类型转换,常用于数字与字符间转换,例:cast(id_no as varchar);

部分函数的使用简析:

(1)coalesce(COL1,COL2,COL3):返回参数中第一个非null字段值

例如:coalesce(COL1,0):如果COL1为null或‘’,则返回默认值0;否则返回COL1的值;

(2)extract(date):对日期特定部分提取(oracle和postgresql使用一致)

例如:


extract(year from now());>>>2018

extract(month from now());>>>9

extract(month from timestamp ‘2018-09-10 13:59:59’);>>>9

(3)对时间截取trunc()和date_trunc()

>>oracle–trunc()的用法:


trunc(sysdate,’yyyy’);//返回当前年的第一天>>>2018-01-01
trunc(sysdate, ‘mm’);//返回当前月的第一天>>>2018-09-01
trunc(sysdate, ‘dd’);//返回当前时间的年月日>>>2018-09-14
trunc(sysdate, ‘hh’);//返回当前小时>>>2018-09-14 13:30:50

>>postgreSQL–date_trunc()用法:


date_trunc(‘year’,now());//返回当前时间年的第一天>>>2018-01-01 00:00:00
date_trunc(‘month’,now());//返回当前月的第一天>>2018-09-01 00:00:00
date_trunc(‘day’,now()); //返回当前时间的年月日>>2018-09-14 00:00:00
date_trunc(‘second’,now()); //返回当前时间的年月日时分秒>>2018-09-14 13:30:50

(3)条件判断


Oracle:
Select DECODE (payments_info,’CR’,’Credit’,’DB’,’Debit’, null) FROM dual;
PostgreSQL:
Select CASE
WHEN foo = ‘CR’ THEN ‘Credit’
WHEN foo = ‘DB’ THEN ‘Debit’
ELSE ‘default’
END
FROM t2;

3、DDL语法差异

oracle和pgSQL操作表结构语法基本一致:

修改表名:alter table tbl_user rename tbl_user2;

添加约束:alter table 表名 add constraint 表名_列名_nn check (is not null)

添加列:alter table tbl_user add age number(3) default 18 not null;

alter table tbl_user add age number(3) default 18 not null after sex;(在指定列后添加列)

删除列:alter table tbl_user drop column age;

修改列:alter table tbl_user modify password default’000000′ not null;(修改约束)

修改列名:alter table tbl_user rename column password to pwd;

只有更改列的数据类型写法有些差异

Oracle:ALTER TABLE table_name modify column_name datatype;

PostgreSQL:ALTER TABLE table_name ALTER column_name TYPE datatype;

4、DML语法差异

oracle和pgSQL增删改查语法基本一致,只有upsert有差异

Oracle:有自带的merge into功能(一个强大的操作)

PostgreSQL:不支持merge操作,可以使用on conflict() do

例:


insert into TargetTable

select id,desc

from SourceTable

on conflict (id)

do update set

desc = exclude.desc

5、查询语句差异

(1)查询表中最新n条数据(Oracle有rownum,postgreSQL有limit)

postgreSQL:

select * from olc.olc_member_intebid_info order by create_time desc limit n;

注意:limit必须用于 order by 之后

Oracle:

写法一:

select t.* from (select * from nwd.tc_inte_bid_record order by create_time desc) t where rownum <= n;

写法二:

select * from(select t.*, row_number() over(order by create_time desc) rn from nwd.tc_inte_bid_record t) where rn <=n;

上述写法一为通用常规写法;写法二可以对分组后数据排序,分组语句写在over()中

(2)子查询

postgresql子查询要求比较严格,必须具有别名才可以

6、 Postgresql命令行常用操作(psql)

psql -d dbname -U username -p 5210 -h 172.0.0.1

–password ‘s&cws123’

如果不想输入密码,可以在.pgpass隐藏文件中添加密码,格式:

172.0.0.1:5210:dbname:username:password

注意.pgpass的权限问题:chmod 0600 ~/.pgpass


— 查询某个库下的所有表(\dt)
select * from pg_tables where schemaname = ‘idn_dw’;

— 查询某个存储过程(\df)
select proname,prosrc from pg_proc where proname = ‘func_dwd_customer_info’;

— 查询某个表下的字段(\d tablen_ame)
select table_schema,table_name,t.colname,string_agg(column_name,’,’) as COLS
from information_schema.columns
LEFT JOIN (select pg_class.relname as tablename,pg_attribute.attname as colname from
pg_constraint inner join pg_class
on pg_constraint.conrelid = pg_class.oid
inner join pg_attribute on pg_attribute.attrelid = pg_class.oid
and pg_attribute.attnum = pg_constraint.conkey[1]
where pg_constraint.contype=’p’) t
on table_name=t.tablename
where TABLE_NAME = ‘s10_anfd_rule’
group by table_schema,table_name,t.colname;

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。


联系我们
返回顶部