第 18 章:修改表结构 (ALTER TABLE) 🔧 - PostgreSQL入门

360影视 动漫周边 2025-08-05 19:42 3

摘要:当遇到这些情况时,我们总不能删掉原来的表再重建一个吧?(那数据就全丢了!)这时,ALTER TABLE 命令就成了我们的救星。

在理想世界里,我们会在项目开始时就完美地设计好所有数据表,然后一劳永逸。但现实是,需求总在不断变化。

“我们需要给用户增加一个手机号字段。”
“订单表需要记录发货状态。”
“我们决定 username 不再需要唯一了。”

当遇到这些情况时,我们总不能删掉原来的表再重建一个吧?(那数据就全丢了!)这时,ALTER TABLE 命令就成了我们的救星。

ALTER TABLE 是一个功能极其丰富的命令集,它允许我们在不丢失数据的前提下,对现有表的结构进行各种“外科手术”:添加、删除、修改列,甚至是添加和删除约束。

警告 ⚠️:在生产环境的数据库上执行 ALTER TABLE 是一个高风险操作。根据操作的类型和表的大小,它可能会锁定表,导致应用暂时无法访问,甚至可能需要很长的执行时间。在执行前,请务必了解其影响,并最好在业务低峰期进行。

我们继续使用上一章创建的 users 表。

-- 回顾一下 users 表的结构-- \d users (在 psql 中)-- Table "public.users"-- Column | Type | Collation | NULLable | Default-- ++++ user_id | integer | | not null | nextval('users_user_id_seq'::regclass)-- username | character varying(50) | | not null |-- email | character varying(100) | | not null |-- age | integer | | |-- Indexes:-- "users_pkey" PRIMARY KEY, btree (user_id)-- "users_email_key" UNIQUE CONSTRAINT, btree (email)-- "users_username_key" UNIQUE CONSTRAINT, btree (username)-- Check constraints:-- "users_age_check" CHECK (age >= 18)

最常见的需求:给 users 表增加一个 phone_number 字段。

ALTER TABLE usersADD COLUMN phone_number VARCHAR(20);

执行后,users 表的每一行都会多出一个 phone_number 列,其默认值为 NULL。

你也可以在添加列的同时,为它指定一个默认值 (DEFAULT)。这对于那些已经有数据的表非常有用。

ALTER TABLE usersADD COLUMN registration_date DATE DEFAULT CURRENT_DATE;

这条命令会添加一个 registration_date 列,并且表中所有现有行的该字段都会被自动填充为今天的日期。

这是一个危险操作! 删除列会永久地移除该列及其所有数据,且通常无法恢复。

假设我们后来觉得 age 这个字段不合适,决定去掉它。

ALTER TABLE usersDROP COLUMN age;

执行后,age 列以及与之关联的 CHECK (age >= 18) 约束都会被一并删除。

修改列可以做很多事,比如更改数据类型、设置/删除默认值、添加/删除 NOT NULL 约束。

1. 更改数据类型 (TYPE)
假设我们发现 phone_number 的 VARCHAR(20) 不够用,想改成 VARCHAR(30)。

ALTER TABLE usersALTER COLUMN phone_number TYPE VARCHAR(30);

注意:不是所有类型之间都能随意转换的。比如,将一个包含文本的 VARCHAR 列转成 INT 列通常会失败。

2. 添加 NOT NULL 约束
我们决定 phone_number 必须是必填项。

-- 首先,确保所有现有行的 phone_number 都不是 NULLUPDATE users SET phone_number = 'N/A' WHERE phone_number IS NULL;-- 然后,添加 NOT NULL 约束ALTER TABLE usersALTER COLUMN phone_number SET NOT NULL;

如果表里已经有 NULL 值,直接添加 NOT NULL 会失败。

3. 删除 NOT NULL 约束

ALTER TABLE usersALTER COLUMN phone_number DROP NOT NULL;

4. 设置/删除默认值 (DEFAULT)

-- 设置默认值ALTER TABLE usersALTER COLUMN age SET DEFAULT 18;-- 删除默认值ALTER TABLE usersALTER COLUMN age DROP DEFAULT;

我们也可以在表创建后,动态地添加和删除约束。

给约束起一个明确的名字是一个非常好的习惯。

1. 添加 UNIQUE 约束
假设我们想给 phone_number 也加上唯一约束。

ALTER TABLE usersADD CONSTRAINT unique_phone_number UNIQUE (phone_number);unique_phone_number 是我们给这个约束起的名字。ALTER TABLE usersADD CONSTRAINT check_username_length CHECK (length(username) > 3);

3. 添加 FOREIGN KEY 约束

ALTER TABLE ordersADD CONSTRAINT fk_orders_users FOREIGN KEY (user_id) REFERENCES users(user_id);

删除约束就需要用到我们给它起的名字了。

-- 删除我们刚刚创建的唯一约束ALTER TABLE usersDROP CONSTRAINT unique_phone_number;-- 删除主键约束(不常用,但可以做到)-- ALTER TABLE users DROP CONSTRAINT users_pkey;ALTER TABLE usersRENAME TO app_users;

本章小结

你已经掌握了像一个经验丰富的数据库管理员(DBA)一样,对数据库结构进行维护和演进的技能。

我们学会了用 ADD COLUMN, DROP COLUMN, ALTER COLUMN 来灵活地管理表的列。学会了用 ADD CONSTRAINT 和 DROP CONSTRAINT 来动态地调整表的规则。还学会了如何重命名表和列。

ALTER TABLE 是一个强大但需要谨慎使用的工具。理解它的能力和潜在风险,是保证数据库能够随着业务发展而平滑演进的关键。

在下一章,我们将学习一个非常有趣的概念——视图 (Views)。它像一个虚拟的、只读的表,可以用来简化复杂的查询、封装业务逻辑,并提供一个安全的数据访问层。准备好学习如何创建你自己的“数据窗口”了吗?我们下一章见!

来源:linux运维菜

相关推荐