站在MySQL肩膀上快速入门PostgreSQL,开源社区最喜爱的关系数据库

PostgreSQL 是一个开源的关系型数据库管理系统,是最流行的开源关系型数据库管理系统之一,具有 strong SQL 兼容性,支持 ACID 事务,以及丰富的扩展功能。

本文主要包含以下内容:

  1. 我为什么选择PostgreSQL
  2. 基于 Docker Compose 快速安装 PostgreSQL
  3. 登录 PostgreSQL
  4. PostgreSQL与MySQL常用语法差异
  5. PostgreSQL管理Shell工具

1.我为什么选择PostgreSQL

公众号聊天窗口发送【数据库排名】可获取最新的数据管理系统排名资料,包含关系数据库、KV存储、时序数据库、缓存数据库、文档数据库、图数据库、向量数据库、搜索数据库、列数据库等。

由于 Oracle 和 SQL Server 是商业的数据库,很多开源项目在进行关系数据库选择时会选择默认支持 MySQL 和 PostgreSQL。 MySQL由于特殊的社区发展等原因,用户逐渐向 MariaDB 和 PostgreSQL 迁移。

藏云阁很多项目如 Harbor、Gitea、Keycloak、Umami、Discourse 默认都支持使用 PostgreSQL,所以在平台建设时也就选择了 PostgreSQL。

新用户从之前熟悉的 MySQL 切换成 PostgreSQL 并不困难,这篇文章的内容虽然不多但也基本能够支撑从MySQL切换成PostgreSQL。

由于SQL标准是一样,所以在进行数据库使用时,数据的增删改查的语法差异较小。但是对于数据库管理有差异较大,新手需要重点关注,也是本文的重点。

2.基于 Docker Compose 快速安装 PostgreSQL

PostgreSQL 有多种安装方式,这里以 Docker Compose 快速安装 PostgreSQL 为例。

如果安装 Docker 受阻可以参考文章:无法访问Docker官网,国内如何合规高效安装Docker软件[最佳实践]

yaml 复制代码
services:
  pgsql:
    image: harbor.cncfstack.com/docker.io/library/postgres:14.19
    container_name: pgsql
    restart: always
    environment:
      - POSTGRES_USER=user0001
      - POSTGRES_PASSWORD=pwd0001
      - POSTGRES_DB=myfirstdb
    volumes:
      - /etc/localtime:/etc/localtime
      - /data/postgressql-data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 4G

PostgreSQL默认的配置基本满足使用了,我就没有挂载配置文件。如果有特殊的配置需要调整,可以添加 command 和 volumes 配置。

yaml 复制代码
    command: ["postgres", "-c", "config_file=/etc/postgresql/postgresql.conf"]
...
    volumes:
      - /data/postgresql/conf/postgresql.conf:/etc/postgresql/postgresql.conf

启动容器使用 藏云阁镜像仓库 可以快速拉取,其他版本镜像可自行查找更换。

3.登录 PostgreSQL

使用容器的方式可以很便捷的登录到PostgreSQL中,不需要在宿主机上安装任何工具。

使用如下命令修改相关的账号密码地址信息后即可登录,在退出后由于 --rm 选项也会自动清理该容器。

bash 复制代码
# docker run -it --rm -e PGPASSWORD=pwd0001 --network host -v /etc/localtime:/etc/localtime  harbor.cncfstack.com/docker.io/library/postgres:14.19 psql -h 127.0.0.1 -U user0001 -p 5432 -d myfirstdb
psql (14.19 (Debian 14.19-1.pgdg13+1))
Type "help" for help.

myfirstdb=#

这里看上去命令比较长,文章末尾会提供一个封装好的 Shell 脚本,方便使用。

4.PostgreSQL与MySQL常用语法差异

基础信息及系统信息查询差异

在 PostgreSQL 中,很多管理相关的命令是使用指令的格式,比较精简但不太好记,需要多动手实操加深印象。

功能 / 特性 MySQL PostgreSQL
获取帮助信息 HELP 'contents'; \?
查看命令历史 不支持 \s
退出登录 exitquit\q \q
单行注释 #-- --
字符串引用 单引号 ' 或双引号 " 只使用单引号 ' (双引号用于标识符)
标识符引用 反引号 ````` 双引号 "
大小写敏感性 默认不敏感 默认敏感
执行外部文件 SOURCE file_name; \i filename
查看版本信息 SELECT VERSION(); SELECT version();
查看当前用户 SELECT USER(); SELECT current_user;
查看所有用户 SELECT user FROM mysql.user; \duSELECT usename FROM pg_user;
查看表空间 SHOW VARIABLES LIKE 'datadir'; \dbSELECT * FROM pg_tablespace;
查看扩展/插件 SHOW PLUGINS; \dxSELECT * FROM pg_extension;

数据库相关操作差异

功能 / 特性 MySQL PostgreSQL
列出所有数据库 SHOW DATABASES; \l
连接到数据库 USE database_name; \c database_name
查看当前数据库 SELECT DATABASE(); SELECT current_database();
查看数据库信息 SHOW CREATE DATABASE db_name; \l+ db_name
查看连接信息 SHOW PROCESSLIST; SELECT * FROM pg_stat_activity;

表相关操作差异

功能 / 特性 MySQL PostgreSQL
列出所有表 SHOW TABLES; \dt
列出所有表(含系统表) SHOW FULL TABLES; \dt+ *.*
查看表结构 DESCRIBE table_name; \d table_name
查看详细表信息 SHOW CREATE TABLE table_name; \d+ table_name
查看表索引 SHOW INDEX FROM table_name; \d table_name
查看列信息 SHOW COLUMNS FROM table_name; \d table_name

模式(Schema)相关操作差异

功能 / 特性 MySQL PostgreSQL
列出所有模式 SHOW DATABASES; \dn
查看当前模式 SELECT DATABASE(); SELECT current_schema();
切换模式 USE database_name; SET search_path TO schema_name;

功能语法差异

功能 / 特性 MySQL PostgreSQL
自增主键 AUTO_INCREMENT SERIALGENERATED ... AS IDENTITY (更新版本)
获取最后自增值 3092147 使用 INSERT ... RETURNING id;CURRVAL()
分页查询 LIMIT size OFFSET offsetLIMIT offset, size LIMIT size OFFSET offset
检查 NULL 值 IS NULLIS NOT NULL (不推荐使用 = NULL) 必须使用 IS NULLIS NOT NULL (= NULL 总是返回假)
正则表达式 REGEXP ~ (区分大小写) 或 ~* (不区分大小写)
获取当前时间 NOW() CURRENT_TIMESTAMP
日期增减 DATE_ADD(date, INTERVAL expr unit) date + INTERVAL 'expr unit'
IFNULL 等效函数 IFNULL(expr, fallback) COALESCE(expr, fallback)
类型转换 CAST(expr AS type)CONVERT(expr, type) CAST(expr AS type)expr::type
公共表表达式 8.0+ 版本支持 支持
窗口函数 8.0+ 版本支持 支持
JSON 支持 JSON 类型 (5.7+) JSONB (二进制,性能更优)
GIS 支持 空间数据类型 PostGIS 扩展 (功能强大)

5.PostgreSQL管理Shell工具

在容器使用时,为了更高效的使用 PostgreSQL,可以封装一个 PostgreSQL 管理工具,方便使用。

这里是我封装的工具,一个配置文件 env 和一个脚本 pgtools.sh 文件,该脚本主要提供了4个功能:登录、创建数据库、备份数据库、恢复数据库。

bash 复制代码
./pgtools.sh
Must have option,example: ./pgtools.sh login postgres
./pgtools.sh login <dbname>
./pgtools.sh createdb <dbname>
./pgtools.sh backup <dbname>
./pgtools.sh restore <dbname>
  • env配置文件

env配置文件主要是一些敏感信息和动态信息,直接写死在脚本中会导致脚本的兼容性差,所以可以独立配置,方便后续修改。

bash 复制代码
export PG_IP=`ip addr show eth0 |grep "inet\ "|awk -F'/' '{print $1}'|awk '{print $2}'`
export PG_PASSWORD='pwd0001'
export PG_USER=user0001
export PG_PORT=5432

脚本中直接有一个字符串 YOUR_OSS_BUCKET 需要修改为自己的OSS存储桶名称。

在脚本准备完成后,可以添加可执行权限并将 PATH 添加到环境变量中,方便使用。

详细的脚本内容

bash 复制代码
#!/bin/bash

SUBCMD=$1
DBNAME=$2

if [ $# -ne 2 ];then
    echo "MUST have option,example: $0 login postgres"
    echo "$0 login <dbname>"
    echo "$0 createdb <dbname>"
    echo "$0 backup <dbname>"
    echo "$0 restore <dbname>"
    exit 1
fi

source `dirname $0`/env

DATETIME=`date +%Y%m%d-%H%M%S`

BAK_DIR="/data/backup/postgresql"
if [ ! -d $BAK_DIR ];then
    mkdir -p $BAK_DIR
fi

BAK_FILE=${BAK_DIR}/${DBNAME}/${DBNAME}-${PG_IP}-${DATETIME}.sql
if [ ! -d ${BAK_DIR}/${DBNAME} ];then
     mkdir -p ${BAK_DIR}/${DBNAME}
fi

PGCLI_RM="docker run -it --rm -e POSTGRES_PASSWORD=$PG_PASSWORD -e PGPASSWORD=$PG_PASSWORD -v /data/backup:/data/backup -v /etc/localtime:/etc/localtime  harbor.cncfstack.com/docker.io/library/postgres:14.19 "

login(){
    $PGCLI_RM psql -h $PG_IP -U $PG_USER -p $PG_PORT -d $DBNAME
}

createdb(){
    $PGCLI_RM createdb -h $PG_IP -U $PG_USER -p $PG_PORT $DBNAME
}

backup(){
  $PGCLI_RM pg_dump -h $PG_IP -p $PG_PORT -U cygpgsql -d $DBNAME -f $BAK_FILE
  ossutil cp -f $BAK_FILE oss://YOUR_OSS_BUCKET/postgresql/${DBNAME}/${DBNAME}-${PG_IP}-${DATETIME}.sql
}

restore(){
   $PGCLI_RM psql -h $PG_IP -p $PG_PORT -U $PG_USER -d $DBNAME -f /data/backup/${DBNAME}.sql
}

if [ $SUBCMD = "login" ];then
    login
elif [ $SUBCMD = "createdb" ];then
    createdb
elif [ $SUBCMD = "backup" ];then
    backup
elif [ $SUBCMD = "restore" ];then
    restore
else
    echo "Unkonw SUBCMD"
    exit 2
fi
相关推荐
Gold Steps.2 小时前
数据库正常运行但是端口变成了0?
数据库·mysql
愤怒的苹果ext3 小时前
MySQL JSON查询与索引
mysql·json·虚拟列·多值索引
翻斗花园牛图图-4 小时前
MySQL——库的操作
数据库·mysql
-指短琴长-4 小时前
MySQL快速入门——内置函数
android·数据库·mysql
蒲公英源码6 小时前
uniapp开源ERP多仓库管理系统
mysql·elementui·uni-app·php
小码过河.6 小时前
告别 mysqldump 痛点!用 mydumper 实现 MySQL 高效备份与恢复
数据库·mysql
是2的10次方啊6 小时前
MySQL索引优化实战:原则速查与踩坑案例(实战篇)
mysql
EllenShen1238 小时前
(Azure)PGSQL和redis 连通性测试 --code 备份
redis·postgresql·azure
Hello.Reader10 小时前
基于 Flink CDC 的 MySQL → Kafka Streaming ELT 实战
mysql·flink·kafka