MySQL表的增删查改(提高篇)

上一篇:MySQL表的增删查改(基本篇)
接上一篇MySQL表基本的增删查改,下面看一下提高篇:

一、数据库约束

1、约束类型
NOT NULL:不为空约束。创建表时,可以指定某列不为空
UNIQUE :唯一约束。指定某列为唯一的、不重复的
DEFAULT :默认值约束。指定插入数据时,某列为空,设置默认值
PRIMARY KEY : 主键约束。NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更
容易更快速地找到表中的一个特定的记录。
FOREIGN KEY :外键约束。用于关联其他表的主键或唯一键,保证一个表中的数据匹配另一个表中的值的参照完整性。
CHECK :保证列中的值符合指定的条件。对于MySQL数据库,对CHECK子句进行分析,但是忽略CHECK子
句。

示例语句:

CREATE TABLE users (
	id INT PRIMARY KEY AUTO_INCREMENT,
	username VARCHAR(100) NOT NULL UNIQUE
);
CREATE TABLE articles (
	id INT PRIMARY KEY AUTO_INCREMENT,
	//指定id列为主键
	对于整数类型的主键,常配搭自增长auto_increment来使用。
	插入数据对应字段不给值时,使用最大值+1
	author_id INT NOT NULL,
	name VARCHAR(20) DEFAULT 'unkown'//指定插入数据时,name列为空,默认值unkown
	title VARCHAR(100) NOT NULL,
	content TEXT NOT NULL,
	published_at DATETIME NOT NULL

外键
定义:上述;
作用:让MySQL也知道了我们已经知道的表之间的关系,进而产生约束。

如下图:
在这里插入图片描述
DELETE FROM 班级表 WHERE id = 2;
如果直接删除,导致学生表中的昊天没有班级信息了,这就是因为没有给MySQL增加约束,MySQL不知道这两张表有直接关系。
为了解决这个情况,就增加了外键。
有了外键之后,在删除汽车班之后,有以下几种情况:
1、不允许删除,除非把昊天删除(默认);
2、瀑布下落(帮你把昊天删除);
3、把昊天的班级id改成null。
因为MySQL中的外键处理性能不是特别好,所以MySQL中一般不太推荐用外键

二、表的设计

  1. 整理需求
  2. E-R 图做辅助
  3. 根据需求填写字段(字段类型、约束关系)
  4. 数据库设计的三大范式(减少数据存储的冗余度的)一对一,一对多,多对多。
    a) 表中的每个字段都是原子的(一个字段不能即保存姓名又保存地址)
    b) 有主键,每个字段应该是和完整的主键有关系
    有主键,每个字段应该是和主键呈现直接关系,而不是间接关系
  5. 生成建表语句

三、新增

创建一张用户表,设计有name姓名、email邮箱、sex性别、mobile手机号字段。需要把已有的学生数据复
制进来,可以复制的字段为name、qq_mail

-- 创建用户表
DROP TABLE IF EXISTS test_user;
CREATE TABLE test_user (
id INT primary key auto_increment,
name VARCHAR(20) comment '姓名',
age INT comment '年龄',
email VARCHAR(20) comment '邮箱',
sex varchar(1) comment '性别',
mobile varchar(20) comment '手机号'
);
-- 将学生表中的所有数据复制到用户表
insert into test_user(name, email) select name, qq_mail from student;

四、复杂查询

聚合查询
GROUP BY 子句(可以独立出现)
HAVING 子句(必须跟在 GROUP BY 后边)

聚合查询:(统计每个人发表的文章数量,根据id要分组)
SELECT COUNT(*)FROM articles;
SELECT COUNT(*),author_id FROM articles GROUP BY author_id;
SELECT author_id,COUNT(*)count FROM articles GROUP BY author_id ORDER BY count;
SELECT author_id,COUNT(*)count FROM articles GROUP BY author_id HAVING count > 3 ORDER BY count;
  1. 聚合函数(独立于 GROUP BY 出现)
    a) COUNT
    b) SUM/AVG/MAX/MIN
    示例:
-- 统计班级共有多少同学
SELECT COUNT(*) FROM student;
SELECT COUNT(0) FROM student;
-- 统计班级收集的 qq_mail 有多少个,qq_mail 为 NULL 的数
SELECT COUNT(qq_mail) FROM student;
-- 统计数学成绩总分
SELECT SUM(math) FROM exam_result;
-- 不及格 < 60 的总分,没有结果,返回 NULL
SELECT SUM(math) FROM exam_result WHERE math < 60;
-- 统计平均总分
SELECT AVG(chinese + math + english) 平均总分 FROM e
-- 返回英语最高分
SELECT MAX(english) FROM exam_result;
-- 返回 > 70 分以上的数学最低分
SELECT MIN(math) FROM exam_result WHERE math > 70;
  1. GROUP BY
    a) 分组凭证
    b) 支持多个分组
    c) SELECT 子句有限制(MySQL 有例外):聚合函数 OR 分组凭证
select role,max(salary),min(salary),avg(salary) from emp group by role;
  1. HAVING
    a) 和 WHERE 对比:WHERE 对聚合前的数据进行过滤;HAVING 对聚合后的数据进行过滤
select role,max(salary),min(salary),avg(salary) from emp group by role having
avg(salary)<1500;

联表查询
实际开发中往往数据来自不同的表,所以需要多表联合查询。多表查询是对多张表的数据取笛卡尔积。多张表之间进行联系的查询,不加筛选条件,出现的结果就是一个笛卡儿积。一般都要使用联系字段进行过滤,例如:文章中的作者 id,评论中的作者id,评论中的文章id

内连接(inner join) vs 外连接(outer join)
全外联(MySQL 不支持 Full Join)
注意:关联查询可以对关联表使用别名

SELECT
	articles.id,author_id,title,content,
	users.id,username
FROM
	articles,users
WHERE author_id = users.id //可加可不加AND articles.id = 1;

内连接


//常用的内联查询:
SELECT classes.name, classes.`desc`, student.name FROM classes, student WHERE classes.id = student.classes_id;

SELECT classes.name, student.name FROM classes INNER JOIN student ON classes.id = student.classes_id;

SELECT classes.name,student.name FROM classes JOIN student ON classes.id = student.classes_id;

//内联查询 班级名称、学生姓名、课程名称、该课程的成绩
SELECT 
c.name, s.name, co.name, sc.score 
FROM classes c, student s, course co, score sc 
WHERE c.id = s.classes_id AND s.id = sc.student_id AND co.id = sc.course_id;

外连接
外连接分为左外连接和右外连接。如果联合查询,左侧的表完全显示我们就说是左外连接;右侧的表完全显示我们就说是右外连接。

//左外联:
SELECT classes.name, student.name FROM classes LEFT JOIN student ON classes.id = student.classes_id;

//右外联:
SELECT classes.name, student.name FROM classes RIGHT JOIN student ON classes.id = student.classes_id;

自连接
自连接是指在同一张表连接自身进行查询。
因为是同一张表联表,所以必须起不同的别名以作区分

SELECT * FROM score s1 WHERE course_id = 1;
SELECT * FROM score s2 WHERE course_id = 3;
SELECT s1.* FROM score s1,score s2 WHERE s1.course_id = 1 AND s2.course_id = 3 AND s1.score < s2.score;

子查询
子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询。
先通过一个 SELECT 查询,得到一组结果集。利用这个结果集做第二次查询

  1. 把第一次的结果集看作一张表做新的查询
  2. 把第一次的结果集作为过滤条件查询
//子查询:
select classes_id from student where name = '不想毕业';
select * from student where classes_id = 1 AND name != '不想毕业';
//合并以上两句话:
select * from student where classes_id = (SELECT classes_id FROM student WHERE name = '不想毕业') AND name != '不想毕业';

  1. [NOT] IN关键字
SELECT * FROM course WHERE name IN("语文","英文");
 SELECT * FROM score WHERE course_id IN(4,6);
 SELECT * FROM score WHERE course_id IN(SELECT id FROM course WHERE name IN('语文','英文'));
  1. [NOT] EXISTS关键字:
 select * 
from score sco
where exists (
    select sco.score from course cou where (name='语文' or name='英文') and cou.id = sco.course_id
);

select * 
from score sco 
where not exists (
    select sco.score 
    from course cou where (name!='语文' and name!='英文') and cou.id = sco.course_id
);

合并查询
在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all。使用UNION和UNION ALL时,前后查询的结果集中,字段需要一致。
UNION vs UNION ALL
UNION 会进行合并重复项
UNION ALL 不会合并重复项

//union
select * from course where id<3
union
select * from course where name='英文';
-- 或者使用or来实现
select * from course where id<3 or name='英文';
//union all
-- 可以看到结果集中出现重复数据Java
select * from course where id<3
union all
lect * from course where name='英文'

在这里插入图片描述

发布了43 篇原创文章 · 获赞 41 · 访问量 1762

猜你喜欢

转载自blog.csdn.net/weixin_45662626/article/details/104309539
今日推荐