1 DQL(数据查询语言)
1.1 语法
select
查询的列, 多列使用逗号分隔
[from
表名
where
过滤条件
group by
分组查询
having
分组后的过滤
order by
排序
limit
分页];
1.2 简单的条件查询
① 查询所有数据
select * from tb_student;
select id, gender, age, birthday, score, regtime, name from student;
② 带条件的查询,可以使用的条件有: >, >=, <, <=, =, !=, <>, between...and, and, or, not, is null, like, in
-- 查询编号为1004的学生
select name,birthday from tb_student where id = 1004;
-- 查询年龄大于18的学生
select * from tb_student where age>18;
-- 查询姓名为张三的成绩
select name ,age from tb_student where name ="张三";
-- 查询18-20岁的学生 between...and...
select * from tb_student where age>=18 and age<=20;
select * from tb_student where age between 18 and 20;
-- 查询除编号1003以外的学生
select * from tb_student where id != 1003;
select * from tb_student where id <> 1003;
-- 查询编号为1005 或者年龄为18的学生
select * from student where id=1005 or age=18;
-- 查询编号(不)为1003、1005、1007的信息 in
select * from tb_student where id in (1003,1005,1007);
select * from tb_student where id not in (1003,1005,1007);
-- 模糊查询 like ,通配符%(任意个任意字符) _(任意一个字符)
-- 查询所有名字含亚的学生信息
select * from tb_student where name like ‘张%’;
-- 查询所有第二个字为季的学生信息
select * from tb_student where name like ‘_季%’;
-- 查询参加考试的学生
select * from tb_student where score is not null;
select * from tb_student where not score is null;
③ select子句
select子句的作用是选择要查询的列. 还有以下的功能:
- 可以在select子句中进行运算;
- 可以使用distinct关键字去除重复行数据;
- 可以给列起别名;
-- 运算
-- null不参与运算, 结果都是null
select name, score, score+10 from student;
-- 可以给列定义别名, 使用as关键字, 可以省略
-- 别名最好不要出现特殊字符, 中文也不建议使用
select name, score, score+10 as new_score from student;
select name, score, score+10 new_score from student;
select name, score, score+10 '成 绩' from student;
-- ifnull函数, 类似于java中的三目运算符, 用于处理空值null, 使用给定的值进行替换null
select name, score, IFNULL(score,0)+10 new_score from student;
-- 查询所有学生的年龄
select distinct age from student;
④ 排序
使用order by 子句可以进行结果的排序,需要配合关键字使用。升序(默认):ASC(ascending);降序:DESC(descending)
-- 查询所有的学生信息,按照id进行升序排序
select * from tb_student order by id asc;
-- 查询年龄为20的学生信息,按照id降序排序
select * from tb_student where age=20 order by id desc;
-- 按照别名排序
-- 查询所有的学生的新成绩,按照新成绩排名
select name,score+10 new_score from tb_student order by new_score desc;
-- 根据第几列排序,不常用
select * from tb_student order by 6;
-- 查询所有学生的信息,按照年龄降序排序,如果年龄相同,再按照id降序排序
select * from tb_student order by age desc,id desc;
-- rand()函数,生成随机数,范围[0,1)
-- 配合rand函数可以进行数据随机排序,打乱数据
select * from tb_student order by rand();
⑤ 分组函数
分组函数用于对查询结果进行统计, 返回结果是一个值, 一共有5个:
- count(): 用于计数
- sum(): 用于求和
- max(): 求最大值
- min(): 求最小值
- avg(): 求平均数
-- 使用分组函数时,null不参与统计
-- 统计所有学生的人数
select count(*) from tb_student;
select count(id) from tb_student;
select count(score) from tb_student;
-- 查询总分,最低分数和最高分数以及平均分数
select sum(score), min(score), max(score), avg(score) from tb_student;
⑥ 分组查询
分组查询可以使用group by子句实现, 分组查询后, 需要注意以下几点:
- select子句只能查询分组字段和分组函数;
- 可以使用where子句在分组前进行条件过滤;
- 可以使用having子句在分组后进行过滤.
-- 按照性别进行分组,分别统计男女同学的人数和平均成绩
select gender,count(*) cnt,avg(score) avg_score from tb_student group by gender;
-- 按照性别进行分组,分别统计男女同学的人数和平均成绩,排除成绩低于70的学生信息
select gender,count(*) cnt,avg(score) avg_score from tb_student where score>70 group by gender;
-- where和having的区别在 having中可以使用分组函数,而where不能
-- 按照年龄进行分组,分别统计不同年龄的同学的人数和平均成绩,排除人数小于2的分组信息
select age,count(*) cnt,avg(score) avg_score from tb_student group by age having count(*)>=2;
select age,count(*) cnt,avg(score) avg_score from tb_student group by age having cnt>=2;
⑦ 分页查询
在MySQL中,可以通过limit关键字,实现分页查询!!!limit必须出现在SQL的末尾
两个参数 1)起始索引(从0开始)2)查询的记录数
-- 每页显示两条学生信息,完成显示
-- page:第几页
-- size:每页显示几条数据
-- select * from tb_student order by id limit (page-1)*size,size;
-- 第一页
select * from tb_student order by id limit 0,2;
-- 第二页
select * from tb_student order by id limit 2,2;
-- 第三页
select * from tb_student order by id limit 4,2;
2 约束
Constraints, 约束, 用来对数据库表格的数据进行约束, 保证数据的完整性, 一致性和正确性. 对约束的操作属于DDL的范畴, 但其实约束的操作针对的是表格. 我们可以在创建表格的同时添加约束, 也可以在表格创建成功后再去操作约束. 在MySQL中, 约束一共有四种
2.1 非空约束(NOT NULL)
表示一个字段的数据不能为null值 当前字段为必填项
-- 创建表格时设置非空值,并设置默认值
drop table if exists stu;
create table stu(
id int(10),
name varchar(10) not null default 'demo'
);
-- 建表后添加非空约束
drop table stu;
create table stu (
id int,
name varchar(20)
);
alter table stu modify name varchar(20) not null;
2.2 唯一约束
表示一个表格中某行数据的某个字段唯一, 与其他行不重复. 在MySQL中, null不做唯一限制.
-- unique 唯一约束
drop table if exists stu;
create table stu(
id int(5),
name varchar(20) not null,
email varchar(20) unique
);
-- 在表格创建成功后添加唯一约束
drop table stu;
create table stu(
id int,
name varchar(20) not null,
email varchar(20)
);
alter table stu modify email varchar(50) unique;
--删除唯一约束
drop index email on stu;
2.3 主键约束 primary key
非空并唯一, 用于唯一标识当前行数据. 某个字段既不能为null值, 也不允许和其他行的该字段重复.
-- 一个表只能有一个主键
-- 多个字段做主键称为联合主键
create table stu (
id int primary key,
name varchar(20) not null,
email varchar(50)
);
-- 修改表的阶段添加主键
drop table stu;
create table stu (
id int,
name varchar(20) not null,
email varchar(50)
);
alter table stu modify id int primary key;
-- 删除主键
alter table stu drop primary key;
-- 主键的自增, 使用关键字auto_increment
-- 该字段必须是数字
-- 表示该字段会从1开始自动递增, 添加的时候无需赋值
drop table stu;
create table stu (
id int primary key auto_increment,
name varchar(20) not null,
email varchar(50)
);
-- 如果创建时忘记添加主键自增
-- alter table 表名 modify 字段 类型 auto_increment primary key
insert into stu values (null, 'demo', 'wuyw2020@163.com');
insert into stu values (default, 'demo', 'wuyw2020@163.com');
2.4 外键约束(foreign key)
约束表和表之间的关系
-- 创建班级表
create table cls(
id int primary key auto_increment,
name varchar(10) not null,
room varchar(5)
);
-- 录入班级数据
-- 多行输入:shift + Alt + 鼠标左键 选中多行,同时输入(Navicat、idea中可用)
insert into cls values
(default,'软件工程1601','1-101'),
(default,'软件工程1602','1-102'),
(default,'软件工程1603','1-103');
-- 主表(父表) 被依赖的表,班级表
-- 从表(子表) 依赖主表的表,学生表
-- 外键添加到从表中,需要依赖主表的唯一字段,通常会使用主键
create table stu (
id int primary key auto_increment,
name varchar ( 20 ) not null,
email varchar ( 50 ) unique,
cid int,
-- ① foreign key(cid) references cls(id)
-- ② constraint fk_cid foreign key( cid ) references cls ( id )
);
-- 在修改表的时候添加外键
alter table stu add constraint fk_cid foreign key(cid) references cls(id);
删除外键
-- alter table 表名 drop foreign key 外键名;
-- 查看建表语句,可以找到外键名
-- ①的方式外键名默认,可以查询建表语句查看外键名
-- ②的方式创建外键可以自定义外键名
show create table stu;
-- 查询结果
CREATE TABLE `stu` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`NAME` varchar(20) NOT NULL,
`email` varchar(50) DEFAULT NULL,
`cid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
KEY `cid` (`cid`),
CONSTRAINT `stu_ibfk_1` FOREIGN KEY (`cid`) REFERENCES `cls` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
alter table stu drop foreign key stu_ibfk_1;
外键的级联操作
默认情况下,添加外键后,被依赖的字段不能修改和删除
如果需要删除,可以先删除从表相关的数据,然后再删除主表数据
或者不删除从表中的数据,先删除外键约束,再删除主表数据
mysql中的级联操作,包括修改和删除,已删除为例介绍
级联删除:当删除主表数据时,自动删除从表数据
CREATE TABLE stu (
id INT PRIMARY KEY auto_increment,
NAME VARCHAR ( 20 ) NOT NULL,
email VARCHAR ( 50 ) UNIQUE,
cid INT,
constraint fk_cid foreign key(cid) references cls(id) on delete cascade
);
级联设空:删除主表数据时,会将从表的外键字段设置为null
CREATE TABLE stu (
id INT PRIMARY KEY auto_increment,
NAME VARCHAR ( 20 ) NOT NULL,
email VARCHAR ( 50 ) UNIQUE,
cid INT,
constraint fk_cid foreign key(cid) references cls(id) on delete set null
);
3 表和表之间的关系
一对一、一对多、 多对多
4 数据库设计及三大范式
范式, 英文单词对应 Normal Form, 用于规范数据库的设计. 实际工作中, 表格的设计只要达到第三范式就已经可以满足生产需要了. 范式一定要灵活使用, 不要死板教条.
4.1 第一范式
所谓第一范式(1NF)是指在关系模型中,对于添加的一个规范要求,所有的域都应该是原子性的,即数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项。MySQL中自动遵守。
一句话总结: 第一范式要求列保证原子性.通俗理解,一张表中字段名不重复
4.1 第二范式
在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)
一句话总结: 第二范式用于限制多对多关系. 使用中间表配合联合主键.
4.1 第三范式
在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖).另外,根据情况适当增加重复字段,出现反第三范式的情况。
一话总结: 第三范式用于限制一对多(多对一)关系. 使用外键.