Skip to content

PostgreSQL 创建数据库学习笔记

创建数据库概述

在 PostgreSQL 中,数据库是一个独立的数据容器,用于组织和管理相关的表、视图、函数等数据库对象。每个数据库都是相互隔离的,这为多租户应用、开发测试环境隔离等场景提供了良好的支持。

创建数据库的基本方法

1. 使用 SQL 命令创建数据库

最基本的创建数据库方法是使用 CREATE DATABASE 命令:

sql
-- 基本语法
CREATE DATABASE name;

-- 实际示例:创建电商系统数据库
CREATE DATABASE ecommerce_db;

-- 创建带有特定编码的数据库
CREATE DATABASE crm_system 
    ENCODING = 'UTF8' 
    LC_COLLATE = 'zh_CN.UTF-8' 
    LC_CTYPE = 'zh_CN.UTF-8';

业务场景示例:多环境数据库管理

假设您正在管理一个电商平台,需要为开发、测试和生产环境创建独立的数据库:

sql
-- 开发环境数据库
CREATE DATABASE shop_dev 
    ENCODING = 'UTF8'
    CONNECTION LIMIT = 20;  -- 限制并发连接数

-- 测试环境数据库
CREATE DATABASE shop_test 
    ENCODING = 'UTF8'
    CONNECTION LIMIT = 10;

-- 生产环境数据库
CREATE DATABASE shop_prod 
    ENCODING = 'UTF8'
    CONNECTION LIMIT = 100;

2. 使用 createdb 工具

createdb 是一个命令行工具,提供了更便捷的数据库创建方式:

bash
# 基本用法 - 创建与当前用户同名的数据库
createdb

# 创建指定名称的数据库
createdb myapp_db

# 创建数据库并指定所有者
createdb -O alice alice_blog

# 创建数据库并添加注释
createdb -O developer -E UTF8 --locale=zh_CN.UTF-8 inventory_system -c "库存管理系统数据库"

完整示例:为微服务架构创建数据库

bash
#!/bin/bash
# 创建微服务架构所需的多个数据库

# 用户服务数据库
createdb -O microservice_user -E UTF8 user_service_db -c "用户认证与管理服务"

# 订单服务数据库
createdb -O microservice_order -E UTF8 order_service_db -c "订单处理服务"

# 库存服务数据库
createdb -O microservice_inventory -E UTF8 inventory_service_db -c "库存管理服务"

# 支付服务数据库
createdb -O microservice_payment -E UTF8 payment_service_db -c "支付处理服务"

echo "微服务数据库创建完成!"

数据库创建权限管理

权限要求

创建数据库需要特定的权限。以下是权限管理的核心概念:

权限管理示例

sql
-- 创建一个具有创建数据库权限的角色
CREATE ROLE developer WITH LOGIN PASSWORD 'dev123' CREATEDB;

-- 创建一个没有创建数据库权限的普通用户
CREATE ROLE app_user WITH LOGIN PASSWORD 'app123';

-- 授予现有用户创建数据库的权限
ALTER ROLE app_user CREATEDB;

-- 撤销创建数据库的权限
ALTER ROLE developer NOCREATEDB;

为其他用户创建数据库

在实际业务中,经常需要为不同的团队或应用创建独立的数据库:

sql
-- 场景1:为开发团队创建数据库
CREATE DATABASE dev_playground OWNER dev_team;

-- 场景2:为特定应用创建数据库,并设置连接限制
CREATE DATABASE mobile_app_db 
    OWNER mobile_team
    CONNECTION LIMIT 50
    ENCODING 'UTF8';

-- 场景3:创建数据库并立即授予权限
CREATE DATABASE analytics_db OWNER data_team;
GRANT CONNECT ON DATABASE analytics_db TO analyst_role;
GRANT CREATE ON DATABASE analytics_db TO data_engineer;

使用 createdb 工具为其他用户创建数据库:

bash
# 为用户 alice 创建博客数据库
createdb -O alice alice_blog_db

# 为团队创建项目数据库,指定模板和编码
createdb -O project_team -T template0 -E UTF8 project_mgmt_db

模板数据库的使用

PostgreSQL 使用模板数据库机制来创建新数据库,这提供了强大的定制能力:

template1 vs template0

INFO

template1:默认模板,可以自定义。新数据库默认从它克隆。

template0:原始模板,保持不变。用于创建"干净"的数据库。

实际应用示例:定制企业模板数据库

sql
-- 1. 连接到 template1
\c template1

-- 2. 创建企业标准扩展
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";     -- UUID 生成
CREATE EXTENSION IF NOT EXISTS "pgcrypto";      -- 加密功能
CREATE EXTENSION IF NOT EXISTS "pg_stat_statements"; -- 性能监控

-- 3. 创建审计日志表模板
CREATE TABLE audit_log_template (
    id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
    table_name VARCHAR(100) NOT NULL,
    action VARCHAR(10) NOT NULL,
    user_name VARCHAR(100) NOT NULL,
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    old_data JSONB,
    new_data JSONB
);

-- 4. 创建通用函数
CREATE OR REPLACE FUNCTION update_modified_time()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

-- 现在创建的新数据库都会包含这些对象
CREATE DATABASE app_with_standards;

使用 template0 创建干净数据库

当需要创建不包含任何自定义内容的数据库时:

sql
-- 使用 template0 创建数据库
CREATE DATABASE clean_db TEMPLATE template0 ENCODING 'UTF8';

-- 或使用 createdb
-- createdb -T template0 -E UTF8 clean_database

第一个数据库的创建流程

理解 PostgreSQL 如何创建第一个数据库对于系统管理很重要:

初始化和创建第一个用户数据库的完整流程

bash
# 1. 初始化数据库集群(通常在安装时自动完成)
initdb -D /var/lib/postgresql/data -E UTF8 --locale=zh_CN.UTF-8

# 2. 启动 PostgreSQL 服务
pg_ctl -D /var/lib/postgresql/data start

# 3. 连接到默认的 postgres 数据库
psql -U postgres

# 4. 在 psql 中创建第一个应用数据库
CREATE DATABASE my_first_app;

# 5. 创建应用用户并授权
CREATE USER app_user WITH PASSWORD 'secure_password';
GRANT ALL PRIVILEGES ON DATABASE my_first_app TO app_user;

常见问题和解决方案

问题 1:ERROR: database already exists

sql
-- 问题重现
CREATE DATABASE test_db;
CREATE DATABASE test_db;  -- ERROR: database "test_db" already exists

-- 解决方案1:先删除再创建
DROP DATABASE IF EXISTS test_db;
CREATE DATABASE test_db;

-- 解决方案2:使用条件创建(需要自定义函数)
CREATE OR REPLACE FUNCTION create_database_if_not_exists(dbname text) 
RETURNS void AS $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_database WHERE datname = dbname) THEN
        EXECUTE format('CREATE DATABASE %I', dbname);
    END IF;
END;
$$ LANGUAGE plpgsql;

-- 使用函数
SELECT create_database_if_not_exists('test_db');

问题 2:ERROR: permission denied to create database

bash
# 检查当前用户权限
psql -U current_user -c "\du"

# 解决方案:使用有权限的用户授权
psql -U postgres << EOF
ALTER USER current_user CREATEDB;
EOF

# 或者让超级用户创建数据库
psql -U postgres -c "CREATE DATABASE needed_db OWNER current_user;"

问题 3:连接数限制问题

sql
-- 查看数据库连接限制
SELECT datname, datconnlimit 
FROM pg_database 
WHERE datname NOT LIKE 'template%';

-- 修改连接限制
ALTER DATABASE myapp_db CONNECTION LIMIT 200;

-- 无限制连接(-1 表示无限制)
ALTER DATABASE myapp_db CONNECTION LIMIT -1;

最佳实践总结

TIP

  1. 命名规范:使用小写字母和下划线,避免特殊字符
  2. 编码设置:始终指定 UTF8 编码以支持多语言
  3. 权限最小化:只授予必要的权限
  4. 模板定制:为企业标准创建自定义模板
  5. 监控连接:合理设置连接限制,避免资源耗尽

企业级数据库创建脚本示例

bash
#!/bin/bash
# 企业标准数据库创建脚本

DB_NAME=$1
DB_OWNER=$2
DB_ENV=$3  # dev, test, prod

if [ -z "$DB_NAME" ] || [ -z "$DB_OWNER" ] || [ -z "$DB_ENV" ]; then
    echo "Usage: $0 <db_name> <db_owner> <environment>"
    exit 1
fi

# 根据环境设置连接限制
case $DB_ENV in
    dev)
        CONN_LIMIT=20
        ;;
    test)
        CONN_LIMIT=50
        ;;
    prod)
        CONN_LIMIT=200
        ;;
    *)
        echo "Invalid environment. Use: dev, test, or prod"
        exit 1
        ;;
esac

# 创建数据库
psql -U postgres << EOF
-- 创建数据库
CREATE DATABASE ${DB_NAME}_${DB_ENV}
    OWNER ${DB_OWNER}
    ENCODING 'UTF8'
    LC_COLLATE = 'zh_CN.UTF-8'
    LC_CTYPE = 'zh_CN.UTF-8'
    CONNECTION LIMIT = ${CONN_LIMIT};

-- 添加注释
COMMENT ON DATABASE ${DB_NAME}_${DB_ENV} IS '${DB_NAME} - ${DB_ENV} 环境';

-- 设置默认权限
GRANT CONNECT ON DATABASE ${DB_NAME}_${DB_ENV} TO ${DB_OWNER};
GRANT CREATE ON DATABASE ${DB_NAME}_${DB_ENV} TO ${DB_OWNER};

-- 创建审计模式
\c ${DB_NAME}_${DB_ENV}
CREATE SCHEMA IF NOT EXISTS audit;
GRANT ALL ON SCHEMA audit TO ${DB_OWNER};

EOF

echo "数据库 ${DB_NAME}_${DB_ENV} 创建成功!"

通过掌握这些数据库创建技术,您可以高效地管理 PostgreSQL 数据库环境,满足各种业务需求。