今日内容概要
今日内容详细
约束条件
返回
default默认值
返回
# 补充知识点 插入数据的时候可以指定字段
create table t1(
id int,
name char(10)
);
insert into t1(name,id) values('egon',1);
default默认值
create table t2(
id int,
name char(16),
gender enum('男','女') default '男'
);
insert into t2(id,name) values(1,'egon');
insert into t2 values(2,'刘杰','女');
unique唯一
返回
# 第一种:单列唯一
create table t3(
id int unique,
name char(16)
);
insert into t3 values(1,'jason'),(2,'egon'),(3,'tank');
insert into t3 values(1,'jason'),(1,'egon'),(3,'tank'); # 错误
# 第二种:联合唯一
"""
ip和port
单个都可以重复,但是加在一起必须是唯一的
"""
create table t4(
id int,
ip char(16),
port int,
unique(ip,port)
);
insert into t4 values(1,'127.0.0.1',8080);
insert into t4 values(2,'127.0.0.1',8000);
insert into t4 values(3,'127.0.0.2',8080);
insert into t4 values(4,'127.0.0.1',8080); # 报错
primary key主建
返回
"""
1、单单从约束效果上来看primary key等价于not null+unique
非空且唯一!!!
"""
create table t5(id int primary key);
insert into t5 values(null); # 报错
insert into t5 values(1),(1); # 报错
insert into t5 values(1),(2);
"""
2、它除了有约束效果之外,他还是Innodb存储引擎组织数据的依据
Innodb存储引擎在创建表的时候必须要有primary key
因为它类似于书的目录,能够帮助提升查询效率并且也是建表的依据
"""
# 1、一张表中有且只有一个主键,如果你没有设置主键,那么会从上往下搜索直到遇到一个非空且唯一的字段并将它升级为主键
create table t6(
id int,
name char(16),
age int not null unique,
addr char(32) not null unique
);
# 2、如果表中没有主键也没有其他任何的非空且唯一的字段,那么Inodb会采用自己内部提供的一个隐藏字段作为主键,隐藏意味着你无法使用它,就无法提升查询速度
# 3、一张表中通常都应该有一个主键字段,并且通常将ID字段作为主键
# 单个字段主键
create table t5(
id int primary key,
name char(16)
);
# 联合主键(多个字段联合起来作为表的主键,本质还是一个主键)
create table t7(
id int,
ip char(16),
port int,
primary key(ip,port)
);
"""
也就意味着,以后我们在创建表的时候ID字段一定要加primary key
"""
auto_increment自增
返回
# 当编号特别多的时候,人为的去维护太繁琐
create table t8(
id int primary key auto_increment,
name char(16)
);
insert into t8(name) values('jason'),('egon'),('刘杰');
# 注意auto_increment只通常都是加在key建上,不能给普通字段加
结论
返回
"""
以后在创建表的ID(数据的唯一标识)字段的时候
id int primary key auto_increment
"""
补充
返回
delete from 在删除表中数据的时候,主键的自增不会停止
truncate t 清空数据并且重置主键的自增
表与表之间建关系
返回
"""
定义了一张员工表,表中有很多字段
id name gender dep_name dep_desc
"""
# 1、该表的组织结构不是很清晰
# 2、浪费硬盘空间
# 3、数据的扩展性极差
# 如何优化?
将员工表拆分成员工表和部门表
外键
返回
"""
外键就是用来帮助我们建立表与表之间关系的
foregin key
"""
表关系
返回
"""
表与表之间最多只有四种关系
一对多关系
多对多关系
一对一关系
没有关系
"""
一对多
返回
"""
判断表与表关系的时候,在前期不熟悉的情况下,一定要按照以下思路来
换位思考 分别站在两张表的角度考虑
员工表与部门表为例
先站在员工表
思考一个员工是否能耐对应多个部门(一个员工数据对应多个部门数据)
不能
在站在部门表
思考一个部门表能否对应多个员工(一个部门数据能否对应多个员工数据)
能
得出结论
员工表与部门表表示单向的一对多
所以表关系就是一对多
"""
foregin key
1、一对多表关系,外键字段建在多的一方
2、在创建表的时候一定要先建被关联表
3、在录入数据的时候也必须先录入被关联表
# SQL语句建立表关系
create table dep(
id int primary key auto_increment,
dep_name char(16),
dep_desc char(32)
);
create table emp(
id int primary key auto_increment,
name char(16),
gender enum('male','female','others') default 'male',
dep_id int,
foreign key(dep_id) references dep(id)
);
insert into dep(dep_name,dep_desc) values('教学部','教书育人'),('外交部','建立外交关系'),('技术部','技术有限部门');
insert into emp(name,dep_id) values('刘杰',2),('宋嘉龙',3),('刘后晟',1);
# 修改dep里面的ID字段
update dep set id=200 where id=2; # 不行
# 删除dep表里面的数据
delete from dep; # 不行
# 1、先删除教学部对应的员工数据之后在删除部门
操作太繁琐
# 2、真正做到数据之间有关系
更新就同步更新
删除就同步删除
"""
级联更新
级联删除
"""
# 一对多表关系的完整语法
create table dep(
id int primary key auto_increment,
dep_name char(16),
dep_desc char(32)
);
create table emp(
id int primary key auto_increment,
name char(16),
gender enum('male','female','others') default 'male',
dep_id int,
foreign key(dep_id) references dep(id)
on update cascade # 同步更新
on delete cascade # 同步删除
);
insert into dep(dep_name,dep_desc) values('教学部','教书育人'),('外交部','建立外交关系'),('技术部','技术有限部门');
insert into emp(name,dep_id) values('刘杰',2),('宋嘉龙',3),('刘后晟',1);
多对多
返回
"""
图书表和作者表
"""
"""
其实我们只是想记录书籍和作者的关系
针对多对多字段表关系,不能在两张原有的表中创建外键
需要你单独在开设一张,专门用来存储两张表数据之间的关系
"""
create table book(
id int primary key auto_increment,
title varchar(32),
price int
);
create table author(
id int primary key auto_increment,
name varchar(32),
age int
);
create table book2author(
id int primary key auto_increment,
author_id int,
book_id int,
foreign key(author_id) references author(id)
on update cascade # 同步更新
on delete cascade, # 同步删除
foreign key(book_id) references book(id)
on update cascade # 同步更新
on delete cascade # 同步删除
);
一对一
返回
"""
如果一个表的字段特别多,每次查询又不是所有的字段都用的到
所以可以将表一分为二
用户表
用户表
ID name age
用户详情表
ID address phone hobby email...
站在用户表
一个用户能否对应多个用户详情 不能!!
站在详情表
一个详情表能否属于多个用户 不能!!
结论:单向的一对多都不成立,那么这个时候两者之间的表关系
就是一对一
或者没有关系(好判断)
"""
一对一外键字段在任意一方都可以,但是推荐你建在查询概率高的表中
create table studentdetail(
id int primary key auto_increment,
phone int,
addr varchar(64)
);
create table student(
id int primary key auto_increment,
name varchar(16),
age int,
studentdetail_id int unique,
foreign key(studentdetail_id) references studentdetail(id)
on update cascade # 同步更新
on delete cascade # 同步删除
);
总结
返回
"""
表关系的建立需要用到foreign key
一对多
外键字段建在多的一方
多对多
自己开设第三张表存储
一对一
建在任意一方都可以,但是推荐你建在查询概率高的表中
判断表之间关系的方式
换位思考
"""
修改表(了解)
返回
# MySQL对大小写是不敏感的
"""
1、修改表名
alter table 原来的表名 rename 新表名;
2、增加字段
alter table 表名 add 字段名 字段类型(宽度) 约束条件; # 默认添加在表的最后
alter table 表名 add 字段名 字段类型(宽度) 约束条件 first; # 添加在表的最前面
alter table 表名 add 字段名 字段类型(宽度) 约束条件 after 字段名; # 在选择字段后加
3、删除字段
alter table 表名 drop 字段名;
4、修改字段
alter table 表名 modify 字段名 字段类型(宽度)约束条件;
alter table 表名 change 旧字段名 新字段名 字段类型(宽度)约束条件;
"""
复制表(了解)
返回
"""
我们SQL语句查询的结果其实也是一张虚拟表
"""
create table 表名 select * from 已存在的表名; # 不能复制主键 外键等等
create table new_dep select * from dep where id>2;