表关系
一对一:一张表的一条记录一定只能与另外一张表的一条记录进行对应,反之亦然
一对多:一张表(1)中有一条记录可以对应另外一张表(2)的多条记录,但是反过来另外一张表(2)的一条记录只能对应第一张表(1)的一条记录
多对多:一张A表中的一条记录,能够对应B表中的多条记录,同时B表中的一条记录也能对应A表中的多条记录
范式
范式是一种分层结构的规范,分为六层:
1)1NF、2NF、3NF、……6NF
2)1NF是最底层,要求最低
3)6NF是最高层,要求最严格
第一范式(1NF)
要求字段的数据具有原子性(也就是不可以再分,直接拿来用,而不是切割后用)
第二范式(2NF)
要解决表的设计不允许出现部分依赖
第三范式(3NF)
解决传递依赖的问题
逆规范化 磁盘利用率与效率的对抗
高级数据操作
新增数据
基本语法 insert into 表名【(字段列表)】 values(值列表)
主键冲突(Duplicate key)
当主键存在冲突的时候,可以选择性的进行处理,镜像更改和替换
更新操作 insert into 表名【(字段列表)】values(值列表)on duplicate key update 字段 = 新值
替换 replace insert into 表名【(字段列表)】 values(值列表)
表创建的高级操作
从已有表创建新表(复制表结构) create table 表名 like 数据库。表名
蠕虫复制
:先查出数据,让后将查询出的数据增一遍
insert into 表名【(字段列表)】 selert 字段列表/*from 数据表名
蠕虫复制的意义
从已有表拷贝数据到新表中
可以迅速地让表中的数据澎湃到一定的数据量,用来测试表的压力以及效率
更新数据
基本语法 update 表名set 字段 = 值【where条件】
高级语句 update 表名set 字段 = 值【where条件】【limit更新数量】
删除数据
deletefrom 表名 【where条件】【limit数量】
truncate 表名 先删除该表,后新增该表
查询数据
基本语句 select 字段列表/*from 表名 【where条件】
完整语法 select【选择】 字段列表【字段别名】/*from 数据源【where条件子句】【group by子句】【having子句】【order by 子句】【limit子句】
select 选项 :select 对查出来的结果的处理方式
all:默认值,保留所有结果
distinct : 去重,查出来的结果,将重复给去除
字段别名
字段名【as】别名
数据源:单表数据源 多表数据源 查询语句
单表数据源 select*from 表名
多表数据源 select*from 表名1 表名2
子查询 select*from(select语句)as别名
where子句 : 返回结果0 或1 ,0 代表false1代表true
判断条件
比较运算符 >,<, >=, <=, !=, <>, =,like, between, and , in/not in
逻辑运算符 &&(and) , ll(or) , !(not)
group by 子句
基本语法 group by 字段名 【asc|desc】
统计函数
count(): 统计分组后的记录数,每一组有多少记录
max(): 统计每组中最大值
min(): 统计每组中最小值
avg(): 统计平均数
sum(): 统计和
多字段排序
group_concat(字段)
回溯统计
with rollup
having子句
where和having的区别 磁盘where 内存having
having子句与where子句相同点:都是进行条件判断的
having能够使用字段别名
排序order by子句
基本语法 order by 字段名 【asc|desc】
排序不会出现交叉,内部还会重新排序
多字段排序,先排班级后排性别select*from my_student order bhy c_id ,sex desc;
desc代表倒叙,无desc代表正序
limit子句(限制结果语句)
方案一 只用来限制长度,即数据量:limit 数据量
查询前两个学生selset * from my_student limit 2
方案二 限制起始位置,限制数量: limit 起始位置,长度(从指定位置出发查询包含的长度)
从开始查询学生到被查询学生后面两位select * from my_student limit 0,2 可以用来页面分页
更改ID为班级的第一列 alter table my_id id int frist
limit offset length
length:每页显示数据量,基本不变
offset = (页码-1)*每页显示量
连接查询(join)
内链接,外链接,自然链接,交叉连接
使用方式 左表join右表
交叉连接(cross join)
select * from my_student cross join my_class --my_student cross join my_class 是数据源
基本语法:左表cross join 右表 等价于from 左表,右表
内连接([inner]join)
基本语法 左表【inner】 join 右表on左表.字段= 右表.字段
on表示连接条件
select * from my_student inner join my_class on my_student.c_id = my_class.id 等价于 select * from my_student inner join my_class on c_id = my_class.id(只有学生表才有c_id 所以可以省略my_student但是id不行,【建议不省略】)
字段和表 别名1.字段别名select s.*,c.name as c_name,c.room2.表别名from my_student as s inner join my_class as c on s.c_id = c.id
把学生表id 为5的记录的c_id 设置为NULLupdate my_student set c_id = null where id=5
不写on条件,就是笛卡尔积select s * ,c.name as c_name,c.room
from my_student as s inner join my_class as c
where代替on select s.*,c,name as c_name ,c.room (字段别名)
from my_student as s inner join my_class as c where s.c_id = c.id(表别名)
外连接(outer join)
left join:左外连接(左连接),以左表为主表
right join:右外连接(右连接),以右表为主表
基本语法:左表 left/right join 右表 on 左表.字段=右表.字段;
自然连接(natural join)
自然内连接:左表 natural join 右表;select * from my_student natural join my_calss 自然内链接 alter table my_class change name c_name varchar(20) not null修改班级表的name字段名为c_name
自然外连接:左表 natural left/right join 右表; 自然左外连接select *from my_student natural left join my_class
模拟自然连接:左表 left/right/inner join 右表 using(字段名); 外连接模拟自然外链接(using)select * from my_student left join my_class using(id)
外键
增加外键
创建表的时候增加外键:在所有的表字段之后,使用foreign key(外键字段) references 外部表(主键字段)
创建外键 create table my_foreignl(id int primary key auto_increment,name varchar(20) not null comment'学生姓名',--增加字段 foreign key(c_idrefernces my_class (id) )charset utf8
在新增表之后增加外键:修改表结构,使用alter table 表名 add [constraint 外键名字] foreign key(外键字段) references 父表(主键字段);
--增加外键alter table my_foreign2 add
--指定外键名constraint student_class_1
--指定外键字段foreign key(c_id) -
--引用父表主键references my_class(id)
修改外键&删除外键
alter table 表名 drop foreign key 外键名;
删除外键alter table my_foreignl drop foreign key my_foreignl_ibfk_1;
插入数据,外键字段在父表中不存在insert into my_foreign2 values(null,'郭富城',5) --没有5班级
insert into my_foreign2 values(null,'项羽',1)
insert into my_foreign2 values(null,'项羽',2)
insert into my_foreign2 values(null,'项羽',2)
更新父表元素update my_class set id = 5 where id=1; ---失败
原因:因为id=1 的记录是班级的已经被学生引用了
update my_class set in=5 where id =3 可以使用 没有引用
插入数据insert into my_foreignl values(null,'马超',3)
增加外键 alter table my_foreignl key(c_id) references my_class(id)
外键条件
外键要存在,首先必须保证表的存储引擎是innodb
列类型必须与父表的主键类型一致
一张表中的外键名字不能重复
增加外键的字段数据已经存在,必须保证数据与父表主键要求对应
外键约束
有三种约束模式
district:严格模式(默认的)
cascade:级联模式
set null:置空模式
语法:foreign key(外键字段) references 父表(主键字段) on delete 模式 on update 模式;