本节摘要:CREATE 建数据库和表。本节讲建库、建表的列定义、数据类型、常用约束(主键、非空、唯一、默认值、外键),让你能建出结构合理的表。
阅读完本节,你应当能够:
CREATE DATABASE Shop;
可加字符集等选项(因 DBMS 而异):
CREATE DATABASE Shop CHARACTER SET utf8mb4;
建完用 USE Shop; 切到该库,后续操作在该库下。
CREATE TABLE Customers ( CustomerID INT PRIMARY KEY, FirstName VARCHAR(50) NOT NULL, LastName VARCHAR(50), City VARCHAR(50) DEFAULT '未知', Email VARCHAR(100) UNIQUE, Age INT CHECK (Age >= 0) );
每列:列名 + 数据类型 + 约束。约束保证数据质量。

| 约束 | 作用 | 示例 |
|---|---|---|
| PRIMARY KEY | 主键,唯一+非空 | CustomerID INT PRIMARY KEY |
| NOT NULL | 非空 | FirstName VARCHAR(50) NOT NULL |
| UNIQUE | 唯一 | Email VARCHAR(100) UNIQUE |
| DEFAULT | 默认值 | City VARCHAR(50) DEFAULT '未知' |
| CHECK | 条件检查 | Age INT CHECK (Age >= 0) |
| FOREIGN KEY | 外键 | 见下 |
约束在写入时校验,违反的 INSERT/UPDATE 被拒绝,从源头保证数据质量。
外键通常作为表级约束定义:
CREATE TABLE Orders ( OrderID INT PRIMARY KEY, CustomerID INT, Amount DECIMAL(10,2), FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID) );
可加级联规则:
FOREIGN KEY (CustomerID) REFERENCES Customers(CustomerID) ON DELETE CASCADE -- 删客户连带删订单(慎用) ON UPDATE CASCADE -- 改客户ID连带改订单
⚠️ 常见坑:建表时不加约束,脏数据混进来后再清理代价大。建表时就把主键、非空、唯一、CHECK 想清楚,从源头保证数据质量。
💡 关键直觉:建表是设计数据质量的第一道关。列类型选紧、必填加 NOT NULL、唯一加 UNIQUE、主键必选、金额 DECIMAL——这些约束在写入时挡住脏数据,比事后清理省事得多。
CREATE DATABASE 库名,可加字符集。CREATE TABLE 表名 (列定义...),每列 = 列名+类型+约束。下一节讲 ALTER——建完表后怎么改结构。
Q1:CREATE TABLE 里列定义顺序有讲究吗?
有实践讲究:主键、常用查询列放前面,大字段(TEXT/BLOB)放最后(某些引擎对行存储顺序敏感)。但逻辑上列顺序不影响查询(查询按列名引用),所以不用过分纠结,先求"类型和约束正确"。
Q2:VARCHAR 和 CHAR 到底怎么选?
长度固定(如国家代码、身份证号 18 位)用 CHAR;长度可变(姓名、地址)用 VARCHAR。CHAR 固定长度会有空格补齐问题,VARCHAR 可变长省空间。现代数据库用 VARCHAR 更普遍,CHAR 用于固定长度标识符。
Q3:主键用自增还是 UUID?
小规模系统自增整数足够:短、有序、索引高效。UUID 优势是分布式不冲突、不暴露业务量,缺点是占空间(36 字符)、乱序(影响索引插入性能)。推荐顺序:自增大于 UUID(v4 用二进制存储优化)。别自己拼接业务字符串当主键。
Q4:外键约束建在表里还是建表后 ALTER?
两种都行。建议建表时一并声明,结构清晰;想后补就用 ALTER TABLE ADD CONSTRAINT。重要的是别一直不建外键——关系靠外键兜底才能保证一致性。
Q5:建表后还能改字符集/引擎吗?
能,ALTER TABLE ... CONVERT TO CHARACTER SET、ENGINE=。但涉及全表重写,大表耗时耗锁。所以建库建表前把字符集(utf8mb4 覆盖中文和 emoji)、引擎(InnoDB 支持事务)一次定对,省得返工。
Q6:建表时怎么预留扩展?
关键不是加一堆空字段,而是:1) 类型选够(金额 DECIMAL、时间 DATETIME);2) 必填加 NOT NULL + DEFAULT;3) 预留 created_at/updated_at 这类通用字段;4) 用扩展表(key-value)而非盲目加列。设计是取舍,别过度设计。
建表是把设计落到实处的第一步,建议完整走一遍"设计到建表"的流程。
第一步,设想一个小需求,比如一个图书借阅系统,需要管理图书、读者、借阅记录三类信息。
第二步,在纸上列出每类信息包含哪些字段,每个字段选什么类型、要不要限制非空、要不要设默认值。
第三步,把设计翻译成建表语句:建一个数据库,然后分别创建图书表、读者表、借阅记录表,把主键、外键、非空、唯一这些约束都加上。
第四步,故意写错一处约束,比如把某个必填字段漏掉非空限制,然后往表里插入一条不完整的数据,观察数据库会不会放行——你就理解了约束的价值。
第五步,查看建好的表结构,对照设计稿逐列核对,确认类型、约束、键都符合预期。
这五步做完,你就有了一张亲手设计、亲手建出来的完整表结构。建表能力是后端开发的基本功,这份完整的动手体验,远比背十条建表规则更有价值。
建库是划出一块空间,建表是在空间里搭好架子。列的类型决定能存什么,约束决定数据的质量底线,主外键把表织成关系网。设计先想清楚,建表才能一次到位。