关于MySQL和PostgreSQL一些差异分析

相关背景:

假设我在 mysql 的数据库中新写了一个建表语句如下:

create table emp(
    id int comment '编号',
    workno varchar(10) comment '工号',
    name varchar(10) comment '姓名',
    gender char(1) comment '性别',
    age tinyint unsigned comment '年龄',
    idcard char(18) comment '身份证号',
    workaddress varchar(50) comment '工作地址',
    entrydate date comment '入职时间'
) comment '员工表';

建表语句的相关解释:

这是一个创建数据库表的SQL语句,用于创建一个名为 emp(员工)的表。下面是对语句中各个部分的解释:

  • id int comment '编号':定义一个 id 列,数据类型为 int,用于存储员工编号,并附有注释 "编号"。
  • workno varchar(10) comment '工号':定义一个 workno 列,数据类型为 varchar(10),表示员工的工号,最多可存储 10 个字符,并有注释 "工号"。
  • name varchar(10) comment '姓名':定义一个 name 列,数据类型为 varchar(10),表示员工姓名,最多可存储 10 个字符,并附有注释 "姓名"。
  • gender char(1) comment '性别':定义一个 gender 列,数据类型为 char(1),表示员工的性别,存储1个字符(例如 'M' 或 'F'),并附有注释 "性别"。
  • age tinyint unsigned comment '年龄':定义一个 age 列,数据类型为 tinyint unsigned,表示员工的年龄,tinyint 是一个较小的整数类型,unsigned 表示不能为负数,并有注释 "年龄"。
  • idcard char(18) comment '身份证号':定义一个 idcard 列,数据类型为 char(18),表示员工的身份证号码,固定长度为 18,并附有注释 "身份证号"。
  • workaddress varchar(50) comment '工作地址':定义一个 workaddress 列,数据类型为 varchar(50),表示员工的工作地址,最多可存储 50 个字符,并附有注释 "工作地址"。
  • entrydate date comment '入职时间':定义一个 entrydate 列,数据类型为 date,表示员工的入职日期,并附有注释 "入职时间"。

将这个建表语句移植到PostgreSQL上:

如果同样的操作,放在PostgreSQL上应该如何操作呢?

create table emp(
    id int,
    workno varchar(10),
    name varchar(10),
    gender char(1),
    age smallint check (age >= 0), -- 使用 smallint 并限制非负数
    idcard char(18),
    workaddress varchar(50),
    entrydate date
);

-- 添加列注释
comment on column emp.id is '编号';
comment on column emp.workno is '工号';
comment on column emp.name is '姓名';
comment on column emp.gender is '性别';
comment on column emp.age is '年龄';
comment on column emp.idcard is '身份证号';
comment on column emp.workaddress is '工作地址';
comment on column emp.entrydate is '入职时间';

-- 添加表注释
comment on table emp is '员工表';

相关的更改说明:

在 PostgreSQL 中,原始的 SQL 语句大部分可以兼容,但有几个需要注意的地方,因为 PostgreSQL 和 MySQL 存在一些细微差别。主要需要调整的地方如下:

  1. comment 语法:PostgreSQL 不支持在字段定义时直接使用 comment 语句。需要在创建表后使用 COMMENT ON COLUMN 语句来添加注释。
  2. tinyint 数据类型:PostgreSQL 不支持 tinyint,但可以用 smallint 替代,或使用 integer 数据类型并限制其范围。
  3. unsigned 修饰符:PostgreSQL 不支持 unsigned 修饰符。你可以通过增加约束来防止负数插入,或者使用 check 约束。

按照上面的规则修改,在 PostgreSQL 中运行,保持了相同的功能,下面是在 DataGrip 执行示意截图。

插入数据的相关操作:

insert into emp (id, workno, name, gender, age, idcard, workaddress, entrydate)
values
(1, '1', '柳岩', '女', 20, '123456789012345678', '北京', '2000-01-01'),
(2, '2', '张无忌', '男', 18, '123456789012345670', '北京', '2005-09-01'),
(3, '3', '韦一笑', '男', 38, '123456789712345670', '上海', '2005-08-01'),
(4, '4', '赵敏', '女', 18, '123456757123845670', '北京', '2009-12-01'),
(5, '5', '小昭', '女', 16, '123456769012345678', '上海', '2007-07-01'),
(6, '6', '杨逍', '男', 28, '12345678931234567X', '北京', '2006-01-01'),
(7, '7', '范瑶', '男', 40, '123456789123456789', '北京', '2005-05-01'),
(8, '8', '黛绮丝', '女', 38, '12345615712345670', '天津', '2015-05-01'),
(9, '9', '范凉凉', '女', 45, '123456789012345678', '北京', '2010-04-01'),
(10, '10', '陈友谅', '男', 53, '123456789012345670', '上海', '2011-01-01'),
(11, '11', '张士诚', '男', 55, '123456789712345670', '江苏', '2015-05-01'),
(12, '12', '常遇春', '男', 32, '123456757152345670', '北京', '2004-02-01'),
(13, '13', '张三丰', '男', 88, '123656789012345678', '江苏', '2020-11-01'),
(14, '14', '灭绝', '女', 65, '123456791012345670', '西安', '2019-05-01'),
(15, '15', '胡青牛', '男', 70, '123456749012345670', '西安', '2018-04-01'),
(16, '16', '周芷若', '女', 18, null, '北京', '2012-06-01');

这是在 mysql 中原始的插入数据的 sql 语句,并且能够正常运行,尝试在PostgreSQL中执行这个语句,

从上面截图可以看出来,已经执行成功。

一些基本查询的区别:

mysql的基本查询

# mysql的基本查询

# 1、查询员工的编号和姓名
select workno, name from emp;

# 2、查询所有的员工信息
select * from emp;

# 3、查询所有员工的工作地址并且起别名
select workaddress as '工作地址' from emp;

# 4、查询员工的工作地址,不要重复
select DISTINCT emp.workaddress  from emp;

PostgreSQL的基本查询你的 MySQL 查询语句几乎可以直接在 PostgreSQL 中使用,只有一些细节需要稍作调整:

  1. 单引号问题:在 PostgreSQL 中,单引号 ' 通常用于字符串,而双引号 " 用于别名或标识符。因此,你需要将别名中的单引号改为双引号。
  2. emp 表名前缀:PostgreSQL 支持省略表名前缀,除非在多表查询中避免歧义,单表查询时可以省略。

以下是将你的 MySQL 查询语句转换为适合 PostgreSQL 的版本:

1. 查询员工的编号和姓名

select workno, name from emp;

不需要修改,PostgreSQL 完全兼容。

2. 查询所有的员工信息

select * from emp;

也不需要修改,PostgreSQL 兼容此查询。

3. 查询所有员工的工作地址并且起别名

在 PostgreSQL 中使用双引号来为别名起名字:

select workaddress as "工作地址" from emp;

4. 查询员工的工作地址,不要重复

PostgreSQL 也支持 DISTINCT 关键字:

select DISTINCT workaddress from emp;

表名前缀可以省略,除非有多表需要区别字段时才用。

全部评论(0)