约束
约束:对表中数据进行限定,保证数据的正确性,有效性,完整性。
非空约束 not null
非空约束:如果添加非空约束,则这个字段的值不能再为NULL
创建表的时候添加约束:只需要在创建的字段后面添加 NOT NULL
1 # 创建表时增加约束 2 CREATE TABLE student3 ( 3 id INT NOT NULL, 4 NAME VARCHAR(5) NOT NULL, 5 math DOUBLE(4,1) 6 );
表创建后添加约束
1 ALTER TABLE student3 MODIFY math DOUBLE(4,1) NOT NULL;
删除非空约束
1 ALTER TABLE student3 MODIFY math DOUBLE(4,1);
唯一约束 unique
唯一约束:添加了唯一约束的字段,值不能再出现重复
创建表的时候添加约束:只需要在创建的字段后面添加 unique
1 CREATE TABLE studetn4( 2 id INT UNIQUE, 3 NAME VARCHAR(5), 4 phone VARCHAR(11) UNIQUE 5 6 );
表创建后添加约束
1 ALTER TABLE student4 MODIFY NAME VARCHAR(5) UNIQUE;
删除唯一约束
1 # 删除唯一约束 2 ALTER TABLE student4 DROP INDEX NAME; 3 4 # ALTER TABLE student4 MODIFY NAME VARCHAR(5); 错误语法 5 # 注意:添加多个null不报错
注意:
1,对于唯一约束,添加多个null不报错
2,删除唯一约束不能使用 modify 的方法去删除
主键约束 primary key
主键约束:如果添加主键约束,则这个字段的值非空且唯一
创建表的时候添加主键约束:
1 #创建表时添加主键约束
2 CREATE TABLE student5(
3 id INT PRIMARY KEY,
4 NAME VARCHAR(5)
5 );
表创建后添加主键约束:
1 ALTER TABLE student5 MODIFY id INT PRIMARY KEY;
删除主键约束:
1 # 删除主键约束
2 ALTER TABLE student5 DROP PRIMARY KEY;
3
4 # alter table studetn5 modify id int; 错误语法
注意:
1,含义:非空且唯一
2,一张表智能有一个字段为主键
3,主键就是表中记录的唯一标识
4,删除主键约束,不能使用 modify
自动增长
定义:如果某一列是数值类型的,使用auto_increment可以来完成值得自动增长。每次添加时不给这一列主动赋值,让其每次增一
创建表时添加自动增长:在徐亚添加自动增长字段后面添加 auto_increment 即可
1 # 创建表的时候添加自动增长
2 CREATE TABLE student5(
3 id INT PRIMARY KEY AUTO_INCREMENT,
4 NAME VARCHAR(5)
5 );
表创建后添加自动增长:
1 # 创建表后添加自动增长
2 ALTER TABLE student5 MODIFY id INT AUTO_INCREMENT;
删除自动增长:
1 # 删除自动增长
2 ALTER TABLE student5 MODIFY id INT;
外键约束 foreing key
为什么需要外键约束:
下面的这个代码示例:下面的表不符合数据库的一些原则,部门名称和地址大量重复,那么就可以拆成两个表
1 CREATE TABLE emp( 2 id INT PRIMARY KEY AUTO_INCREMENT, 3 NAME VARCHAR(4), 4 age INT, 5 dep_name VARCHAR(5), 6 dep_location VARCHAR(4) 7 8 ); 9 10 INSERT INTO emp (NAME,age,dep_name,dep_location)VALUES (\'张三\',20,\'研发部\',\'广州\'); 11 INSERT INTO emp (NAME,age,dep_name,dep_location)VALUES (\'李四\',20,\'研发部\',\'广州\'); 12 INSERT INTO emp (NAME,age,dep_name,dep_location)VALUES (\'王五\',20,\'研发部\',\'广州\'); 13 INSERT INTO emp (NAME,age,dep_name,dep_location)VALUES (\'赵六\',20,\'销售部\',\'深圳\'); 14 INSERT INTO emp (NAME,age,dep_name,dep_location)VALUES (\'孙七\',20,\'销售部\',\'深圳\'); 15 INSERT INTO emp (NAME,age,dep_name,dep_location)VALUES (\'老八\',20,\'销售部\',\'深圳\'); 16 17 SELECT * FROM emp;
拆成两个表:
拆成两个表,虽然解决了代码重复的问题,但是存在两个表不关联。
例如:当我删除部门表的时候,只给部门表删了,但是属于部门表的员工,没有受到影响。这样是不合理的,部门都没有了,员工还怎么存在
当我增加一个员工时,对于他所在的部门也可以随便指定,这也是不合理,不能员工存在一个不存在的部门中
1 # 员工表 2 CREATE TABLE employe( 3 id INT PRIMARY KEY AUTO_INCREMENT, 4 NAME VARCHAR(4), 5 age INT, 6 7 dep_id INT 8 9 ); 10 11 CREATE TABLE department( 12 id INT PRIMARY KEY AUTO_INCREMENT, 13 dep_name VARCHAR(5), 14 dep_location VARCHAR(4) 15 ); 16 17 INSERT INTO department (dep_name,dep_location)VALUES (\'研发部\',\'广州\'); 18 INSERT INTO department (dep_name,dep_location)VALUES (\'销售部\',\'深圳\'); 19 20 SELECT * FROM department; 21 INSERT INTO employe (NAME,age,dep_id)VALUES (\'张三\',20,1); 22 INSERT INTO employe (NAME,age,dep_id)VALUES (\'李四\',20,1); 23 INSERT INTO employe (NAME,age,dep_id)VALUES (\'王五\',20,1); 24 INSERT INTO employe (NAME,age,dep_id)VALUES (\'赵六\',20,2); 25 INSERT INTO employe (NAME,age,dep_id)VALUES (\'孙七\',20,2); 26 INSERT INTO employe (NAME,age,dep_id)VALUES (\'老八\',20,2); 27 SELECT * FROM employe;
外键约束就解决了上面的两个问题
在拆成两个表后,给从表中添加外键约束,可以让两个表关联,这样就不会存在拆成两个表后的问题
表创建的时候添加外键
外键约束语法:
1 create table 表名( 2 # 表中的其他字段信息 3 …… 4 # 外键字段 5 外键列, 6 # 外键约束 7 constraint 外键名称 foreign key 外键列名称 references 主表名称(主表的列的名称) 8 );9
外键约束代码示例
1 1 CREATE TABLE department( 2 2 id INT PRIMARY KEY AUTO_INCREMENT, 3 3 dep_name VARCHAR(5), 4 4 dep_location VARCHAR(4) 5 5 ); 6 6 7 7 CREATE TABLE employe( 8 8 id INT PRIMARY KEY AUTO_INCREMENT, 9 9 NAME VARCHAR(4), 10 10 age INT, 11 11 dep_id INT,# 外键列 12 12 13 13 CONSTRAINT emp_dep_id FOREIGN KEY (dep_id) REFERENCES department(id) 14 14 15 15 ); 16 16 17 17 18 18 INSERT INTO department (dep_name,dep_location)VALUES (\'研发部\',\'广州\'); 19 19 INSERT INTO department (dep_name,dep_location)VALUES (\'销售部\',\'深圳\'); 20 20 21 21 SELECT * FROM department; 22 22 23 23 INSERT INTO employe (NAME,age,dep_id)VALUES (\'张三\',20,1); 24 24 INSERT INTO employe (NAME,age,dep_id)VALUES (\'李四\',20,1); 25 25 INSERT INTO employe (NAME,age,dep_id)VALUES (\'王五\',20,1); 26 26 INSERT INTO employe (NAME,age,dep_id)VALUES (\'赵六\',20,2); 27 27 INSERT INTO employe (NAME,age,dep_id)VALUES (\'孙七\',20,2); 28 28 INSERT INTO employe (NAME,age,dep_id)VALUES (\'老八\',20,2); 29 29 30 30 SELECT * FROM employe; 31 31 32 32 # 报错 33 33 #INSERT INTO employe (NAME,age,dep_id)VALUES (\'老八\',20,5); 34 34 #delete from department where id = 1;
表创建后添加外键
1 # 表创建后添加外键 2 ALTER TABLE employe ADD CONSTRAINT emp_dep_id FOREIGN KEY (dep_id) REFERENCES department(id);
删除外键
1 # 删除外键 2 ALTER TABLE employe DROP FOREIGN KEY emp_dep_id;
级联操作
添加外键后存在两个级联操作:
级联更新:只需要在外键的设置后面添加 ON UPDATE CASCADE
1 # 级联更新 2 ALTER TABLE employe ADD CONSTRAINT emp_dep_id FOREIGN KEY (dep_id) REFERENCES department(id) ON UPDATE CASCADE;
级联删除:只需要在外键的设置后面添加 ON DELETE CASCADE
1 # 级联删除 2 ALTER TABLE employe ADD CONSTRAINT emp_dep_id FOREIGN KEY (dep_id) REFERENCES department(id) ON DELETE CASCADE;
数据库设计
表与表的三种关系
1,一对一:(了解就行,很少使用,因为可创建成一张表)
例如:人和身份证
分析:一个人只有一个身份证,一个身份证只能对应一个人
2,一对多(多对一)
例如:部门和员工
分析:一个部门有多个员工,一个员工只能对应一个部门
3,多对多:
例如:学生和课程
分析:一个学生可以选择很多门课程,一个课程也可以被很多学生选择
三种关系怎么实现
1,一对一的实现(了解)
人和身份证
实现方式:一对一关系的实现,可以在任意一方添加唯一外键指向另一方的主键
2,一对多的实现
部门和员工
实现方式:在多方建立外键,指向一方的主键
3,多对多的实现
学生和课程
实现方式:多对多关系的实现需要借助第三张中间表。
中间表至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键
三种关系案例
1,一对一(不在举例):可以创建一个表即可
2,一对多案例
需求:一个旅游线路分类中有多个旅游线路
1 -- 创建旅游线路分类表tab_category 2 -- cid旅游线路分类主键,自动增长 3 -- cname旅游线路分类名称非空,唯一,字符串100 4 create table tab_category ( 5 cid int primary key auto_increment, 6 cname varchar(100) not null unique 7 ); 8 9 -- 添加旅游线路分类数据: 10 insert into tab_category (cname) values (\'周边游\'), (\'出境游\'), (\'国内游\'), (\'港澳游\'); 11 12 select * from tab_category; 13 14 -- 创建旅游线路表tab_route 15 /* 16 rid旅游线路主键,自动增长 17 rname旅游线路名称非空,唯一, 18 字符串100 19 price价格 20 rdate 上架时间, 21 日期类型 22 cid 外键, 23 所属分类 24 */ 25 create table tab_route( 26 rid int primary key auto_increment, 27 rname varchar(100) not null unique, 28 price double, 29 rdate date, 30 cid int, 31 foreign key (cid) references tab_category(cid) 32 ); 33 34 -- 添加旅游线路数据 35 INSERT INTO tab_route VALUES 36 (NULL, \'【厦门+鼓浪屿+南普陀寺+曾厝垵 高铁3天 惠贵团】尝味友鸭面线 住1晚鼓浪屿\', 1499, \'2018-01-27\', 1), 37 (NULL, \'【浪漫桂林 阳朔西街高铁3天纯玩 高级团】城徽象鼻山 兴坪漓江 西山公园\', 699, \'2018-0222\', 3), 38 (NULL, \'【爆款¥1699秒杀】泰国 曼谷 芭堤雅 金沙岛 杜拉拉水上市场 双飞六天【含送签费 泰风情 广州 往返 特价团】\', 1699, \'2018-01-27\', 2), 39 (NULL, \'【经典•狮航 ¥2399秒杀】巴厘岛双飞五天 抵玩【广州往返 特价团】\', 2399, \'2017-12-23\', 2), 40 (NULL, \'香港迪士尼乐园自由行2天【永东跨境巴士广东至迪士尼去程交通+迪士尼一日门票+香港如心海景酒店 暨会议中心标准房1晚住宿】\', 799, \'2018-04-10\', 4); 41 42 select * from tab_route;
3,多对多案例
需求:一个用户收藏多个线路,一个线路被多个用户收藏
1 /* 2 创建用户表tab_user uid用户主键,自增长 3 username用户名长度100,唯一,非空 4 password密码长度30,非空 5 name真实姓名长度100 6 birthday生日 7 sex性别,定长字符串1 8 telephone手机号,字符串11 9 email邮箱,字符串长度100 10 */ 11 create table tab_user ( 12 uid int primary key auto_increment, 13 username varchar(100) unique not null, 14 password varchar(30) not null, 15 name varchar(100), 16 birthday date, 17 sex char(1) default \'男\', 18 telephone varchar(11), 19 email varchar(100) 20 ); 21 22 -- 添加用户数据 23 INSERT INTO tab_user VALUES 24 (NULL, \'cz110\', 123456, \'老王\', \'1977-07-07\', \'男\', \'13888888888\', \'66666@qq.com\'), 25 (NULL, \'cz119\', 654321, \'小王\', \'1999-09-09\', \'男\', \'13999999999\', \'99999@qq.com\'); 26 27 select * from tab_user; 28 29 30 /* 31 创建收藏表tab_favorite 32 rid 旅游线路id,外键 33 date 收藏时间 34 uid用户id,外键 35 rid和uid不能重复,设置复合主键,同一个用户不能收藏同一个线路两次 36 */ 37 create table tab_favorite ( 38 rid int, 39 date datetime, 40 uid int, 41 -- 创建复合主键 42 primary key(rid,uid), 43 foreign key (rid) references tab_route(rid), 44 foreign key(uid) references tab_user(uid) 45 ); 46 47 48 -- 增加收藏表数据 49 INSERT INTO tab_favorite VALUES 50 (1, \'2018-01-01\', 1), -- 老王选择厦门 51 (2, \'2018-02-11\', 1), -- 老王选择桂林 52 (3, \'2018-03-21\', 1), -- 老王选择泰国 53 (2, \'2018-04-21\', 2), -- 小王选择桂林 54 (3, \'2018-05-08\', 2), -- 小王选择泰国 55 (5, \'2018-06-02\', 2); -- 小王选择迪士尼 56 57 select * from tab_favorite;
上面两个案例综合
1 -- 创建旅游线路分类表 tab_category 2 -- cid 旅游线路分类主键,自动增长 3 -- cname 旅游线路分类名称非空,唯一,字符串 100 4 create table tab_category ( 5 cid int primary key auto_increment, 6 cname varchar(100) not null unique 7 ) 8 9 10 -- 创建旅游线路表 tab_route 11 /* 12 rid 旅游线路主键,自动增长 13 rname 旅游线路名称非空,唯一,字符串 100 14 price 价格 15 rdate 上架时间,日期类型 16 cid 外键,所属分类 17 */ 18 19 create table tab_route( 20 rid int primary key auto_increment, 21 rname varchar(100) not null unique, 22 price double, 23 rdate date, 24 cid int, 25 foreign key (cid) references tab_category(cid) 26 ) 27 28 29 30 /* 31 创建用户表 tab_user 32 uid 用户主键,自增长 33 username 用户名长度 100,唯一,非空 34 password 密码长度 30,非空 35 name 真实姓名长度 100 36 birthday 生日 37 sex 性别,定长字符串 1 38 telephone 手机号,字符串 11 39 email 邮箱,字符串长度 100 40 */ 41 42 create table tab_user ( 43 uid int primary key auto_increment, 44 username varchar(100) unique not null, 45 password varchar(30) not null, 46 name varchar(100), 47 birthday date, 48 sex char(1) default \'男\', 49 telephone varchar(11), 50 email varchar(100) 51 ); 52 53 54 /* 55 创建收藏表 tab_favorite 56 rid 旅游线路 id,外键 57 date 收藏时间 58 uid 用户 id,外键 59 rid 和 uid 不能重复,设置复合主键,同一个用户不能收藏同一个线路两次 60 */ 61 62 create table tab_favorite ( 63 rid int, 64 date datetime, 65 uid int, 66 -- 创建复合主键 67 primary key(rid,uid), 68 foreign key (rid) references tab_route(rid), 69 foreign key(uid) references tab_user(uid) 70 );
数据库的设计范式
概念:设计数据库时,需要遵循的一些规范。要遵循后边的范式要求,必须先遵循前边所有的范式要求
设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。
目前数据库有六大范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯—科德范式(BCNF)、第四范式(4NF)、第五范式(5NF,又称完美范式)。
分类:
1,第一范式(1NF)
每一列都是不可分隔的原子数据项
2,第二范式(2NF)
在1NF的基础上,非码属性必须完全依赖于码(在1NF基础上消除非主属性对主码的部分函数依赖)
几个概念:
1,函数依赖:A——>B,如果通过A属性(属性组)的值,可以确定唯一B属性的值,则B依赖于A
例如:学号——>姓名(通过学号可以确定唯一的姓名属性)
(学号,课程名称)——>分数(属性组可以确定唯一的分数)
2,完全函数依赖:A——>B,如果A是一个属性组,则B属性值得确定要依赖A属性组中所有的属性值
例如:(学号,课程名称)——>分数
3,部分函数依赖:A——>B,如果A是一个属性组,则B属性值得确定只需要依赖A属性组中某一些值即可。
例如:(学号,课程名称)——>分数
4,传递函数依赖:A——>B,B——>C,如果通过A属性(属性组)的值,可以确定唯一B属性的值,在通过B属性(属性组)的值可以确定唯一C属性的值,
则称C传递函数依赖于A。
例如:
学号——>系名,系名——>系主任
5,码:如果在一张表中,一个属性或属性组,被其他所有属性组完全依赖,则称该属性或属性组为该表的码
例如:
该表中码为:(学号,课程名称)
主属性:码属性组中所有属性
非主属性:除过码属性组的属性
3,第三范式(3NF)
在2NF基础上,任何非主属性不依赖与其他非主属性(在2NF基础上消除传递依赖)
三大范式总结:
数据库的备份和还原
备份
语法:
mysqldump -u用户名 -p密码 需要备份数据库名称> 保存路径
注意:
1,命令行输入命令
2,不能登录mysql,直接输入上述命令
3,文件路径格式为 路径+文件名.sql
还原
1,登录数据库
2,创建数据库
3,使用数据库
4,执行文件。source 文件路径