某学校要设计一个数据库,学校的业务规则概括如下:
学校内班级若干,每个班级内又有学生若干。
学校开设课程若干,只有某些特定的班级能上指定的课程。
学生选修某些课程,但是在自身班级下的课程是必修。
学校定期组织考试,成绩囊括所有学生所有课程的考试成绩。
要求根据上述需求,完成E-R图的构建,并通过三大范式的规范设计出数据库模型图。
解答
实体 系 科目 学生 成绩 属性 系:系编号(PK) 系名称 科目:科目编号(PK) 科目名称 学习时长 系编号 学生:学号(PK) 密码 姓名 性别 系编号 联系电话 生日 邮箱 身份证号码 住址 成绩:学号(FK) 科目号(FK) 考试日期 考试成绩 关系 1系>>>N学生 主从关系 1系>>>N科目 1学生>>>N成绩 1科目>>>N成绩 =========================> N学生<<<>>>N科目 1:建库 MySchool_db CREATE DATABASE Myschool_db; 2:建表(先主后从) 2.1创建年级表 CREATE TABLE grade( GradeID INT NOT NULL AUTO_INCREMENT COMMENT '年级编号', GradeName VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '年级名称', PRIMARY KEY (GradeID) ) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci; 2.2创建科目表 DROP TABLE IF EXISTS subject; CREATE TABLE subject ( SubjectNo int NOT NULL AUTO_INCREMENT COMMENT '课程编号', SubjectName varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '课程名称', ClassHour int NULL DEFAULT NULL COMMENT '学时', GradeID int NULL DEFAULT NULL COMMENT '年级编号', PRIMARY KEY (SubjectNo) ) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci 2.3创建学生表 DROP TABLE IF EXISTS student; CREATE TABLE student ( StudentNo int(0) NOT NULL COMMENT '学号', LoginPwd varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, StudentName varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '学生姓名', Sex tinyint(1) NULL DEFAULT NULL COMMENT '性别,取值0或1', GradeId int(0) NULL DEFAULT NULL COMMENT '年级编号', Phone varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '联系电话,允许为空,即可选输入', Address varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '地址,允许为空,即可选输入', BornDate datetime(0) NULL DEFAULT NULL COMMENT '出生时间', Email varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '邮箱账号,允许为空,即可选输入', IdentityCard varchar(18) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '身份证号', PRIMARY KEY (StudentNo) USING BTREE, UNIQUE INDEX IdentityCard(IdentityCard) USING BTREE, INDEX Email(Email) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci; 2.4创建成绩表 CREATE TABLE `result` ( `StudentNo` int(0) NOT NULL COMMENT '学号', `SubjectNo` int(0) NOT NULL COMMENT '课程编号', `ExamDate` datetime(0) NOT NULL COMMENT '考试日期', `StudentResult` int(0) NOT NULL COMMENT '考试成绩', INDEX `SubjectNo`(`SubjectNo`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci >>>>>> 为subject表添加外键约束 ALTER TABLE subject ADD CONSTRAINT fk_subgra FOREIGN KEY (GradeID) REFERENCES grade (GradeID); 为student表添加外键约束 ALTER TABLE student ADD CONSTRAINT fk_stugra FOREIGN KEY (GradeID) REFERENCES grade (GradeID);
建表的语法
标准的建表(table)语法(列定义之间以英文逗号,隔开): 数据表的每行称为一条记录(record),每一列称为一个字段(field): 主键(字段)列:唯一标识某一行的列: CREATE TABLE 表名( 列名(字段名) 类型, 列名(字段名) 类型, 列名(字段名) 类型, 列名(字段名) 类型, 列名(字段名) 类型 ) ENGINE = 存储结构; 表名采用大驼峰命名如 >>> Students Subject StudentResult 表名采用小驼峰命名如 >>> studentName subjectName resultDate
MyISAM || InnoDB(默认) 存储列相关信息,描述表结构文件,字段长度等 如果采用共存储模式的,数据信息和索引信息都存储在ibdata1中, 如果采用分区存储,还会有一个t.par文件(用来存储分区信息)。
在mysql中,常用数据类型有三种:1、文本类型 2、数字类型 3、日期/时间类型
文本类型类型:
数据类型 | 描述 |
---|---|
CHAR(size) | 保存固定长度的字符串(可包含字母、数字以及特殊字 符)。在括号中指定字符串的长度。最多 255 个字符。 |
VARCHAR(size) | 保存可变长度的字符串(可包含字母、数字以及特殊字 符)。在括号中指定字符串的最大长度。最多 255 个字 符。如果size>255,则类型会自动转换为TEXT类型。 |
TEXT | 存放最大长度为 65,535 个字符的字符串。 |
TINYTEXT | 存放最大长度为 255 个字符的字符串。 |
MEDIUMTEXT | 存放最大长度为 16,777,215 个字符的字符串。 |
LONGTEXT | 存放最大长度为 4,294,967,295 个字符的字符串。 |
BLOB | 用于 BLOBs (Binary Large OBjects)。存放最多 65,535 字节的数据。 |
MEDIUMBLOB | 用于 BLOBs (Binary Large OBjects)。存放最多 16,777,215 字节的数据。 |
LONGBLOB | 用于 BLOBs (Binary Large OBjects)。存放最多 4,294,967,295 字节的数据。 |
ENUM | 枚举类型 |
数字类型:
数据类型 | 描述 |
---|---|
TINYINT(size) | -128 到 127 常规。 0 到 255 无符号*。在括号中规定最 大位数 |
SMALLINT(size) | -32768 到 32767 常规。 0 到 65535 无符号*。在括号中 规定最大位数。 |
MEDIUMINT(size) | -8388608 到 8388607 普通。 0 到 16777215 无符号*。在 括号中规定最大位数。 |
INT(size) | -2147483648 到 2147483647 常规。 0 到 4294967295 无 符号*。在括号中规定最大位数。 |
BIGINT(size) | -9223372036854775808 到 9223372036854775807 常规。 |
FLOAT(size,d) | 带有浮动小数点的小数字。在括号中规定最大位数。在 d 参数中规定小数点右侧的最大位数。 |
DOUBLE(size,d) | 带有浮动小数点的大数字。在括号中规定最大位数。在 d 参数中规定小数点右侧的最大位数。 |
DECIMAL(size,d) | 作为字符串存储的 DOUBLE 类型,允许固定的小数点。 |
时间\日期类型:
数据类型 | 描述 |
---|---|
DATE() | 日期。格式:YYYY-MM-DD 取值范围 '1000-01-01' <<<>>> '9999-12-31' |
DATETIME() | 日期和时间的组合。格式: YYYY-MM-DD HH:MM:SS 注释:支持的范围是'1000-01-01 00:00:00' <<<>>> '9999-12- 31 23:59:59' |
TIMESTAMP() | 时间戳。 TIMESTAMP 值使用 Unix 纪元('1970-01-01 00:00:00' UTC) 至今的描述来存储。格式: YYYY-MM-DD HH:MM:SS 注释:支持的范围是从 '1970-01-01 00:00:01' UTC 到 '2038-01-09 03:14:07' UTC |
TIME() | 时间。格式: HH:MM:SS 注释:支持的范围是从 '-838:59:59' 到 '838:59:59' |
YEAR() | 2 位或 4 位格式的年。 注释: 4 位格式所允许的值: 1901 到 2155。 2 位格式所允许 的值: 70 到69,表示从 1970 到 2069 |
常用数据类型:
SHOW命令
语法:
SHOW TABLES [FROM 数据库名] [LIKE wild];
查看表结构:
SHOW COLUMNS FROM 表名
DROP TABLE [IF EXISTS] 表名
示例:
#创建学生表 CREATE TABLE Students( studentNo INT(5), studentName VARCHAR(50), studentBirth DATE, studentAddress VARCHAR(100), studentTel VARCHAR(11), studentEmail VARCHAR(50) ) ENGINE = InnoDB; #查看表结构 SHOW COLUMNS FROM Students; #删除表 DROP TABLE [IF EXISTS] Student;
修改列类型 ALTER TABLE 表名 MODIFY 列名 列类型; >>> ALTER TABLE Students MODIFY studentEmail TEXT; 添加列 ALTER TABLE 表名 ADD 列名 列类型; >>> ALTER TABLE Students ADD studentGender CHAR(2); 删除列 ALTER TABLE 表名 DROP 列名; 删除时注意数据完整性 >>> ALTER TABLE Students DROP studentGender; 改列名 ALTER TABLE 表名 CHANGE 旧列名 新列名 列类型; >>> ALTER TABLE Students CHANGE studentEmail studentEma VARCHAR(50); 改表名 ALTER TABLE 表名 RENAME 新表名; RENAME TABLE 表名 TO 新表名;
复制表的结构有两种手段 方式1: 在 CREATE TABLE 语句的末尾加入 LIKE 源表; >>> CREATE TABLE Students1 LIKE Students; 方式2: 在 CREATE TABLE 语句末尾添加 SELECT 关键字; >>> CREATE TABLE Students2 SELECT * FROM Students; 方法3: 如果已经有一张表了(结构一定要和源表一样) >>> INSERT INTO 表名 SELECT * FROM 源表;
由 information_schema 数据库负责维护 tables-存放数据库里所有的数据表、以及每个表所在数据库。 schemata-存放数据库里所有的数据库信息 views-存放数据库里所有的视图信息。 columns-存放数据库里所有的列信息。 triggers-存放数据库里所有的触发器。 routines-存放数据库里所有存储过程和函数。 key_column_usage-存放数据库所有的主外键 table_constraints-存放数据库全部约束。 statistics-存放了数据表的索引。
是在表上强制执行的数据校验规则。约束主要用于保证数据库的完整性。当表中数据有相互依赖性时,可以保护相关的数据不被删除。大部分数据库支持下面五类完整性约束:
非空约束 NOT NULL 唯一性约束 UNIQUE KEY 主键约束(非空+唯一) PRIMARY KEY 外键约束 FOREIGN KEY 检查约束 CHECK 检查语法 默认值约束 DEFAULT ....... 加入约束的三种时机 1,建表时期加入,直接符在声明的列后。 2,建表时期加入,所有列声明完成后,单独去重新声明列的约束性。 3,建表后加入,语法参考修改列类型语法完成约束的添加。 >>>>>>>> 约束作为数据库对象,存放在系统表中,也有自己的名字 创建约束的时机 在建表的同时创建 建表后创建(修改表) 可定义列级或表级约束 有单列约束和多列约束 定义约束的语法 方式1:列级约束:在定义列的同时定义约束 语法:列定义 约束类型, 方式2:表级约束:在定义了所有列之后定义的约束 语法: 列定义 [CONSTRAINT 约束名] 约束类型(列名) 约束名的取名规则 推荐采用:表名_列名_约束类型简介 方式3:约束可以在创建表时就定义,也可以在创建完后再添加 语法: ALTER TABLE 表名 ADD CONSTRAINT 约束名 约束类型(要约束的列名)
表的约束示例
1、非空约束(NOT NULL) 列级约束,只能使用列级约束语法定义。 确保字段值不允许为空 只能在字段级定义 >>> CREATE TABLE Students( studentNo INT PRIMARY KEY AUTO_INCREMENT, studentName VARCHAR(50) NOT NULL ); 2、唯一约束 唯一性约束条件确保所在的字段或者字段组合不出现重复值 唯一性约束条件的字段允许出现多个NULL 同一张表内可建多个唯一约束 唯一约束可由多列组合而成 建唯一约束时MySQL会为之建立对应的索引。 如果不给唯一约束起名,该唯一约束默认与列名相同。 CREATE TABLE Students( studentNo INT PRIMARY KEY AUTO_INCREMENT, studentName VARCHAR(18) UNIQUE NOT NULL ); 3、主键约束 主键从功能上看相当于非空且唯一 一个表中只允许一个主键 主键是表中唯一确定一行数据的字段 删除表的约束 自动增长和默认值 存储引擎 主键字段可以是单字段或者是多字段的组合 当建立主键约束时,MySQL为主键创建对应的索引 主键约束名总为PRIMARY。 CREATE TABLE tb_student( studentNo INT PRIMARY KEY AUTO_INCREMENT, studentName VARCHAR(18) ) 4、外键约束 外键是构建于一个表的两个字段或者两个表的两个字段之间的关系 外键确保了相关的两个字段的两个关系: 子(从)表外键列的值必须在主表参照列值的范围内,或者为空(也可以加非空约束,强制不允许为空)。 当主表的记录被子表参照时,主表记录不允许被删除。 外键参照的只能是主表主键或者唯一键,保证子表记录可以准确定位到被参照的记录。 格式FOREIGN KEY (外键列名)REFERENCES 主表(参照列) #部门 CREATE TABLE tb_dept( dept_id INT PRIMARY KEY, NAME VARCHAR(18), description VARCHAR(255) ); #员工 CREATE TABLE tb_employee( employee_id INT PRIMARY KEY, NAME VARCHAR(18), gender VARCHAR(10), dept_id INT REFERENCES tb_dept(dept_id), address VARCHAR(255) ); 5、检查约束 #注意检查约束在8.0之前,MySQL默认但不会强制的遵循check约束(写不报错,但是不生效,需要通触发器完成) # 8之后就开始正式支持这个约束了。 create table t3( id int, age int check(age > 18), gender char(1) check(gender in ('M','F')) ); 6、自动增长 auto_increment :自动增长 为新的行产生唯一的标识 一个表只能有一个auto_increment,且该属性必须为主键的一部分。auto_increment的属性可以是任何整数类型 7、默认值 default : 默认值 综合实践: # 默认值 可以使用default关键字设置每一个字段的默认值。 -- 创建一张user表 CREATE TABLE User( id INT(11) NOT NULL AUTO_INCREMENT COMMENT 'id', name VARCHAR(225) COMMENT '姓名', sex TINYINT(1) DEFAULT 1 COMMENT '性别 1男 0女', PRIMARY KEY (id) ) ENGINE=INNODB CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;