背景
据说 如果你熟悉 MySQL,切换到 PostgreSQL 就像从 Windows 切换到 macOS:都是电脑,比较简单,
但是 但操作习惯不同。
老是不习惯 写篇文章对比一下吧 给其他小伙伴
基础连接对比
MySQL
bash
# 连接数据库
mysql -u root -p
# 进入后
mysql> SHOW DATABASES;
mysql> USE database_name;
mysql> SHOW TABLES;
PostgreSQL
bash
# 连接数据库
psql -U postgres -d database_name
# 进入后
postgres=# \l -- 相当于 SHOW DATABASES
postgres=# \c database_name -- 相当于 USE database_name
postgres=# \dt -- 相当于 SHOW TABLES
常用操作对照表
| 操作 | MySQL | PostgreSQL | 解释 |
|---|---|---|---|
| 查看所有数据库 | SHOW DATABASES; |
\l |
PostgreSQL 用反斜杠命令 |
| 使用数据库 | USE dbname; |
\c dbname |
切换当前数据库 |
| 查看所有表 | SHOW TABLES; |
\dt |
注意:是 \dt 不是 /dt |
| 查看表结构 | DESC table_name; |
\d table_name |
PostgreSQL 的 \d 更强大 |
| 查看表详情 | SHOW CREATE TABLE table_name; |
\d+ table_name |
显示索引、约束等 |
| 退出客户端 | exit; 或 quit; |
\q |
简单一个字母 |
| 执行SQL文件 | source file.sql; |
\i file.sql |
导入外部SQL |
| 查看帮助 | help; |
\? |
元命令帮助 |
SQL语法关键差异
1. 限制查询结果
sql
-- MySQL
SELECT * FROM user LIMIT 10;
-- PostgreSQL
SELECT * FROM "user" LIMIT 10;
-- 或更标准的
SELECT * FROM "user" FETCH FIRST 10 ROWS ONLY;
2. 自增ID
sql
-- MySQL
CREATE TABLE user (
id INT AUTO_INCREMENT PRIMARY KEY
);
-- PostgreSQL
CREATE TABLE "user" (
id SERIAL PRIMARY KEY
);
-- 或(现代方式)
CREATE TABLE "user" (
id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY
);
3. 字符串连接
sql
-- MySQL
SELECT CONCAT(name, ' (', phone, ')') FROM user;
-- PostgreSQL
SELECT name || ' (' || phone || ')' FROM "user";
-- 或
SELECT CONCAT(name, ' (', phone, ')') FROM "user";
4. 当前时间
sql
-- MySQL
SELECT NOW(); -- 2025-01-15 10:30:00
SELECT CURDATE(); -- 2025-01-15
-- PostgreSQL
SELECT NOW(); -- 2025-01-15 10:30:00.123456+08
SELECT CURRENT_DATE; -- 2025-01-15 (注意:没有括号)
实战示例:用户表操作
创建用户表
sql
-- MySQL
CREATE TABLE user (
id VARCHAR(20) PRIMARY KEY,
phone VARCHAR(15) UNIQUE NOT NULL,
password VARCHAR(128),
name VARCHAR(50),
age INT,
created_at BIGINT DEFAULT UNIX_TIMESTAMP(),
updated_at BIGINT DEFAULT UNIX_TIMESTAMP() ON UPDATE UNIX_TIMESTAMP()
);
-- PostgreSQL
CREATE TABLE "user" (
id VARCHAR(20) PRIMARY KEY,
phone VARCHAR(15) UNIQUE NOT NULL,
password VARCHAR(128),
name VARCHAR(50),
age INT,
created_at BIGINT DEFAULT EXTRACT(EPOCH FROM NOW()),
updated_at BIGINT DEFAULT EXTRACT(EPOCH FROM NOW())
);
-- PostgreSQL 需要创建触发器来更新 updated_at
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = EXTRACT(EPOCH FROM NOW());
RETURN NEW;
END;
$$ language 'plpgsql';
CREATE TRIGGER update_user_updated_at
BEFORE UPDATE ON "user"
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
查询用户数据
sql
-- 两者通用(PostgreSQL 表名需要引号)
SELECT * FROM "user" WHERE phone = '13634759152';
-- 时间戳转换(PostgreSQL 更强大)
-- MySQL
SELECT FROM_UNIXTIME(created_at) FROM user;
-- PostgreSQL
SELECT TO_TIMESTAMP(created_at) FROM "user";
SELECT created_at * INTERVAL '1 second' FROM "user";
为什么会有这些差异?
- 历史原因:两个数据库独立发展30+年
- 标准遵循:PostgreSQL 更遵循 SQL 标准
- 设计理念 :
- MySQL:简单快速,"够用就好"
- PostgreSQL:功能完备,"严格标准"
迁移时需要改什么?
代码层面
-
连接字符串:
python# MySQL "mysql+pymysql://user:pass@localhost/db" # PostgreSQL "postgresql+psycopg2://user:pass@localhost/db" -
ORM配置:
python# SQLAlchemy 中 # MySQL 可以用 AUTO_INCREMENT # PostgreSQL 用 SERIAL 或 IDENTITY
运维层面
-
备份恢复:
bash# MySQL mysqldump -u root db > backup.sql mysql -u root db < backup.sql # PostgreSQL pg_dump -U postgres db > backup.sql psql -U postgres db < backup.sql -
权限管理:PostgreSQL 更细粒度,也更复杂 但是主流推荐
你应该选择哪个?
选 MySQL 如果:
- 需要简单快速上手
- 项目主要是读操作
- 团队熟悉 MySQL 生态
- 使用 WordPress、Laravel 等框架
选 PostgreSQL 如果:
- 需要复杂查询和事务
- 数据一致性要求高
- 需要 JSON、GIS、全文搜索等高级功能
- 项目会长期发展,需要扩展性
常见坑点提醒
- 表名大小写 :PostgreSQL 默认小写,如果创建了
"User",查询必须用引号 - 反斜杠 vs 正斜杠 :
\dt✓,/dt✗ - 命令结束符 :两者都用
;,但 PostgreSQL 的元命令不用 - 时间处理:PostgreSQL 时区处理更严格
一句话建议
把 PostgreSQL 当成一个全新的数据库来学 ,不要尝试把 MySQL 的习惯带过去。掌握 \ 开头的元命令,理解严格的大小写和类型系统,你会发现 PostgreSQL 的强大之处。
据说 :如果你用 Docker,两者的差异会更明显。PostgreSQL 的数据卷需要正确配置权限,而 MySQL 通常 "just works"。
