中超
uniqueconstraint(第 18 章:修改表结构 (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)

18.1 添加、删除、修改列

添加新列 (ADD COLUMN)

最常见的需求:给 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 列,并且表中所有现有行的该字段都会被自动填充为今天的日期。

删除列 (DROP COLUMN)

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

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

ALTER TABLE usersDROP COLUMN age;

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

修改列 (ALTER COLUMN)

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

1. 更改数据类型 (TYPE)
假设我们发现 phone_numberVARCHAr(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;

18.2 添加和删除约束

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

添加约束 (ADD CONSTRAINT)

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

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

ALTER TABLE usersADD ConSTRAINT unique_phone_number UNIQUE (phone_number);
  • unique_phone_number 是我们给这个约束起的名字。

2. 添加 CHECK 约束

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);

删除约束 (DROP CONSTRAINT)

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

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

18.3 重命名表和列

重命名列 (RENAME COLUMN)

ALTER TABLE usersRENAME COLUMN email TO email_address;

重命名表 (RENAME TO)

ALTER TABLE usersRENAME TO app_users;

本章小结

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

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

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

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


顶一下()     踩一下()

热门推荐

发表评论
0评