课程 › 第 5 章 › 实验一
第 5 章 · 实验一 · 在第三节之后

创建数据表与约束

在一个空数据库中建出学生表、课程表和选课表,给它们加上约束,再插入几条数据检验约束是否起作用。

环 境

MySQL 8.0 和 MySQL Workbench,机房电脑已装好。所有语句在 Workbench 的 SQL 编辑区中执行。

执 行

Ctrl+Enter 执行光标所在的一句,Ctrl+Shift+Enter 执行全部。Mac 上把 Ctrl 换成 ⌘。

注 意

输入法切到英文。表名、字段名不加引号,字符串值才用单引号。

本次实验的顺序 后一个实验用到前一个的结果

  1. 实验 1-1建学生表 s
  2. 实验 1-2建课程表 c
  3. 实验 1-3建选课表 sc,连起两张表
  4. 实验 1-4插入数据,检验约束
第一步

数据准备(必做)

新建一个空的练习库 ch05_lab。第一次执行时第一句会有一条警告(库不存在),不影响。

整段复制,全部执行下载 .sql
-- 新建练习用的数据库 ch05_lab
DROP DATABASE IF EXISTS ch05_lab;
CREATE DATABASE ch05_lab DEFAULT CHARACTER SET utf8mb4;
-- 切换到这个数据库,后面建的表都放在这里
USE ch05_lab;
1-1

建立学生表 s

讲义 · 建表语句讲义 · ENUM 与 SET讲义 · 主键约束
目的
用 CREATE TABLE 建表,为字段选择数据类型,定义主键、非空和默认值。
前提
已执行数据准备,当前数据库是 ch05_lab。
字段含义数据类型要求
sno学号CHAR(10)主键
sn姓名VARCHAR(45)不能为空
sex性别ENUM('男','女')不能为空,默认为男
age年龄INT不能为空
maj专业VARCHAR(45)不能为空
dept院系VARCHAR(45)不能为空

参考答案

可以直接复制到 Workbench 执行
CREATE TABLE s (
  sno  CHAR(10)    NOT NULL,                -- 学号,固定 10 个字符
  sn   VARCHAR(45) NOT NULL,                -- 姓名,最多 45 个字符
  sex  ENUM('男','女') NOT NULL DEFAULT '男',  -- 性别,只能取男或女,不填时为男
  age  INT         NOT NULL,                -- 年龄,整数
  maj  VARCHAR(45) NOT NULL,                -- 专业
  dept VARCHAR(45) NOT NULL,                -- 院系
  PRIMARY KEY (sno)                         -- 学号做主键
);
-- 查看表结构,检查是否建对
DESC s;

语句解释

CREATE TABLE s ( … );建一张名为 s 的表。括号里每行一个字段,字段之间用逗号隔开,最后一行后面不加逗号
CHAR(10) VARCHAR(45)字符串类型。CHAR 长度固定,VARCHAR 按实际长度存,括号里是最多能存的字符数
ENUM('男','女')只能从列表中取一个值
NOT NULL这个字段不能为空
DEFAULT '男'插入数据时不给值,就自动填“男”
PRIMARY KEY (sno)学号做主键,不能为空,也不能重复
DESC s;查看表 s 的结构
执行后看:DESC 的结果中,sno 的 Key 一栏是 PRI,sex 的 Default 一栏是 男。
1-2

建立课程表 c

讲义 · 唯一约束讲义 · 主键与唯一
目的
定义唯一约束,保证课程名不重复。
前提
已完成实验 1-1。
字段含义数据类型要求
cno课程号CHAR(10)主键
cn课程名VARCHAR(45)不能为空,不能重复
ct课时INT可以为空

参考答案

可以直接复制到 Workbench 执行
CREATE TABLE c (
  cno CHAR(10)    NOT NULL,           -- 课程号
  cn  VARCHAR(45) NOT NULL UNIQUE,    -- 课程名,不能为空,也不能重复
  ct  INT,                            -- 课时,可以为空
  PRIMARY KEY (cno)                   -- 课程号做主键
);
-- 查看表结构
DESC c;

语句解释

UNIQUE唯一约束,这个字段的值不能重复
ct INT没有写 NOT NULL,这个字段允许为空
主键与 UNIQUE两者都不允许重复。一张表只能有一个主键,UNIQUE 可以有多个,而且 UNIQUE 字段可以为空
执行后看:DESC 的结果中,cno 的 Key 一栏是 PRI,cn 的 Key 一栏是 UNI。
1-3

建立选课表 sc,把两张表联系起来

讲义 · 主键约束讲义 · 外键约束讲义 · 检查约束
目的
用两个字段组成主键,用外键引用学生表和课程表,用 CHECK 限定成绩范围。
前提
已完成实验 1-1、1-2。外键要引用的 s 表和 c 表必须先存在。
字段含义数据类型要求
sno学号CHAR(10)不能为空
cno课程号CHAR(10)不能为空
score成绩DECIMAL(5,2)可以为空
  1. 学号和课程号合起来做主键
  2. sno 引用 s 表的 sno,cno 引用 c 表的 cno
  3. 成绩只能在 0 到 100 之间,这个约束命名为 ck_score(实验二要用到这个名字)

参考答案

可以直接复制到 Workbench 执行
CREATE TABLE sc (
  sno   CHAR(10)     NOT NULL,        -- 学号
  cno   CHAR(10)     NOT NULL,        -- 课程号
  score DECIMAL(5,2),                 -- 成绩,共 5 位数字,其中 2 位小数
  PRIMARY KEY (sno, cno),             -- 学号和课程号合起来做主键
  FOREIGN KEY (sno) REFERENCES s (sno),    -- 学号必须在学生表中存在
  FOREIGN KEY (cno) REFERENCES c (cno),    -- 课程号必须在课程表中存在
  CONSTRAINT ck_score CHECK (score >= 0 AND score <= 100)  -- 成绩在 0 到 100 之间
);
-- 查看完整的建表语句
SHOW CREATE TABLE sc;

语句解释

DECIMAL(5,2)精确小数,共 5 位数字,其中 2 位是小数,最大 999.99
PRIMARY KEY (sno, cno)学号和课程号合起来不能重复。单看学号可以重复,因为一个学生可以选多门课
FOREIGN KEY (sno) REFERENCES s (sno)外键。sc 中的学号必须是 s 表中已有的学号
CONSTRAINT ck_score CHECK (…)检查约束,名字叫 ck_score,条件不成立的成绩不能写入
SHOW CREATE TABLE sc;查看完整的建表语句,能看到主键、外键和检查约束
执行后看:如果报错 1824,说明 s 表或 c 表还没有建,先完成实验 1-1、1-2。
1-4

插入数据,检验约束

讲义 · 约束概述讲义 · NOT NULL讲义 · 唯一约束
目的
插入几条数据,看每一种约束怎样拦住不符合规则的数据。
前提
已完成实验 1-1 到 1-3。

把下面的语句复制到 Workbench,一句一句执行(光标放在语句上按 Ctrl+Enter),判断每一句是成功还是报错,报错是哪一种约束在起作用。INSERT 的写法第六节再讲,这里照着执行即可。

要执行的语句
-- (1)
INSERT INTO s VALUES ('s1', '王彤', '女', 18, '计算机', '信息学院');
-- (2)
INSERT INTO s (sno, sn, age, maj, dept) VALUES ('s2', '苏乐', 20, '信息', '信息学院');
-- (3)
INSERT INTO s (sn, age, maj, dept) VALUES ('林欣怡', 19, '信息', '信息学院');
-- (4)
INSERT INTO s VALUES ('s1', '陶然', '男', 19, '自动化', '工学院');
-- (5)
INSERT INTO c VALUES ('c1', '数据库系统', 56), ('c2', '数据结构', 64);
-- (6)
INSERT INTO c VALUES ('c3', '数据库系统', 48);
-- (7)
INSERT INTO sc VALUES ('s1', 'c1', 90.5);
-- (8)
INSERT INTO sc VALUES ('s9', 'c1', 80);
-- (9)
INSERT INTO sc VALUES ('s2', 'c2', 180);
-- (10)
SELECT * FROM s;

结果与原因

语句结果原因
(1)成功各字段都符合要求
(2)成功没给性别,DEFAULT 自动填为 男
(3)报错 1364没给学号,主键字段不能为空
(4)报错 1062学号 s1 已经存在,主键不能重复
(5)成功一次插入两门课程
(6)报错 1062课程名 数据库系统 已经存在,UNIQUE 不允许重复
(7)成功s1 和 c1 都存在
(8)报错 1452学生表中没有 s9,外键不允许
(9)报错 3819成绩 180 超过 100,违反 CHECK 约束 ck_score
(10)显示两名学生s2 的性别是 男,由默认值填入
保山学院·人工智能教研室·曹鼎鼎