全书目录

第十八篇:MySQL 完全指南 —— 城市户籍总账宇宙

第四章:约束 —— 户籍柜台不能只靠工作人员自觉

1 分钟 237 字 第 339 / 962 个阅读单元

如果没有约束,数据库就像没有规章的柜台:

  • 姓名可以空着
  • 同一个身份证号可以登记两次
  • 市民可以挂到不存在的户号上
  • 状态字段随便填成 flying???done_ok

这显然不行。

MySQL 常见约束可以这样理解:

text
NOT NULL     -> 这栏不许空
DEFAULT      -> 没填时给默认值
UNIQUE       -> 这栏不许重号
PRIMARY KEY  -> 这份档案的总编号
CHECK        -> 这栏必须满足规则
FOREIGN KEY  -> 这份档案必须挂在另一份真实档案上

看一个更完整的例子:

sql
CREATE TABLE move_logs (
  move_id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
  citizen_id BIGINT UNSIGNED NOT NULL,
  from_household_id BIGINT UNSIGNED NOT NULL,
  to_household_id BIGINT UNSIGNED NOT NULL,
  moved_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  reason VARCHAR(100) NOT NULL,
  CONSTRAINT fk_move_logs_citizen
    FOREIGN KEY (citizen_id) REFERENCES citizens(citizen_id),
  CONSTRAINT fk_move_logs_from_household
    FOREIGN KEY (from_household_id) REFERENCES households(household_id),
  CONSTRAINT fk_move_logs_to_household
    FOREIGN KEY (to_household_id) REFERENCES households(household_id),
  CONSTRAINT chk_move_diff
    CHECK (from_household_id <> to_household_id)
) ENGINE=InnoDB;

这段建表语句表达的是:

  • 迁户日志必须属于某个真实市民
  • 迁出户号和迁入户号都必须真实存在
  • 迁出和迁入不能是同一个户号

数据库约束的核心原则是:

能交给数据库守住的规则,就不要只写在应用代码里。

因为应用代码会绕路,数据库里的硬规则不会。