第35讲 Docker创建PostgreSQL数据库的表,并且设置自增
本讲基于视频实际讲解内容整理
一、本讲概述
上一讲装好了 PostgreSQL 容器。本讲在容器里的数据库中建表,重点是 PostgreSQL 的自增主键做法,以及为 BBS 设计 users(用户表)和 posts(帖子表)两张核心表。
二、连接数据库
进入 Docker 容器里的 psql:
Shell
docker exec -it my-postgres psql -U admin -d bbs
后续 SQL 都在这个交互环境里执行。
三、PostgreSQL 的自增
3.1 SERIAL(最常用的自增)
PostgreSQL 用 SERIAL / BIGSERIAL 实现自增,底层是序列(sequence):
SQL
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL
);
SERIAL→ 4 字节整数(约 21 亿上限)BIGSERIAL→ 8 字节,范围更大(推荐用于可能大量增长的表)
插入时不用给 id,数据库自动生成:
SQL
INSERT INTO users (username) VALUES ('张三');
-- id 会自动变成 1、2、3...
3.2 GENERATED AS IDENTITY(更现代,推荐)
PostgreSQL 10+ 支持标准 SQL 的标识列:
SQL
CREATE TABLE users (
id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
username VARCHAR(50) NOT NULL
);
老师说明:
SERIAL简单好用,但本质是"语法糖 + 序列",存在被手动覆盖的风险;GENERATED AS IDENTITY是标准写法,更严谨。两种本讲都会演示,项目中能跑通即可。
四、设计 BBS 核心表
4.1 用户表 users
SQL
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
| 字段 | 说明 |
|---|---|
id |
自增主键 |
username |
用户名,唯一、不为空 |
password |
密码(实际存储密文,见第38讲 MD5) |
created_at |
注册时间,默认当前时间 |
4.2 帖子表 posts
SQL
CREATE TABLE posts (
id SERIAL PRIMARY KEY,
title VARCHAR(200) NOT NULL,
content TEXT,
user_id INTEGER REFERENCES users(id),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
老师强调:
user_id INTEGER REFERENCES users(id)是外键,把帖子和作者关联起来。建表顺序要注意:先建users,再建posts(被引用的表必须先存在)。
4.3 验证表结构
SQL
\d users -- 查看 users 表结构
\d posts -- 查看 posts 表结构
\dt -- 列出所有表
五、插入与查询示例
SQL
-- 插入用户
INSERT INTO users (username, password) VALUES ('张三', '密文');
-- 查询
SELECT * FROM users;
-- 插入帖子(关联用户 id=1)
INSERT INTO posts (title, content, user_id)
VALUES ('第一帖', '大家好', 1);
-- 连表查询:帖子标题 + 作者名
SELECT p.title, u.username
FROM posts p
JOIN users u ON p.user_id = u.id;
六、本讲小结
| 知识点 | 要点 |
|---|---|
| 连接 | docker exec -it 容器 psql -U 用户 -d 库 |
| 自增 | SERIAL / BIGSERIAL 或 GENERATED AS IDENTITY |
| 不插 id | 自增列插入时不用给值 |
| 外键 | 字段 REFERENCES 表(列) 关联 |
| 建表顺序 | 先建被引用的表 |
| 查看结构 | \d 表名、\dt |
七、课后练习
- 进入 postgres 容器,创建
users表(id 自增、username 唯一) - 用
BIGSERIAL再建一张posts表,含外键关联users.id - 插入几条用户和帖子数据
- 用
SELECT ... JOIN查出"帖子标题 + 作者名" - 尝试把
id改成GENERATED ALWAYS AS IDENTITY写法再建一张测试表 - 思考:如果先建
posts再建users,外键会报什么错?为什么?