数据库是结构化信息或数据的有组织的集合,通常以电子方式存储在计算机系统中。数据库通常由数据库管理系统(DBMS)来控制。数据、DBMS及其关联应用一起被称为数据库系统,通常简称为数据库。——甲骨文官网
非结构化数据:例如文本数据、视频数据等;半结构化数据:例如JSON格式的数据、html文档等;结构化数据:例如mysql中存储的每行数据。 也就是说,结构化数据是固定的字段,并且字段的数值类型也是固定的。而JSON之所以叫做半结构化数据,是因为它的字段数值类型不是固定的。 Mysql 就是一款数据管理系统,即DBMS,再辅助上存储的数据和其生态应用,统称为 Mysql 数据库。再来看下 MySQL 的官网介绍: MySQL, the most popular Open Source SQL database management systemmysql是关系型数据库 通过将每张表看成是一个集合,也就是更抽象一层,我们就能够利用集合中的交并补等运算来进行操作,也就是将具体的数据表上升到了数学理论的高度。这个数学理论就是集合论,而关系型数据库的理论基础就是集合论。我们执行的各种增删改查操作,实际上都可以抽象的看成是对于集合(关系)的各种操作。 理论中的关系(即集合)对应的就是数据表,元组对应的就是每条记录,域对应的就是每列字段。基于这样理论基础的数据库就叫做关系型数据库。关系代表我们在操作这些数据的时候,把这些数据看成一个个集合,然后用集合之间的运算执行操作,只是这些操作或者这些数据与集合对应是有着坚实的数学理论基础。
**Mysql是数据库、关系型数据库的子集。**但是mysql有自己独有的特性:
Uses multi-layered server design with independent modules. 同样是分层思想的体现Provides transactional and nontransactional storage engines. 两个关键词:事务、存储引擎Executes very fast joins using an optimized nested-loop join. 关键词:嵌套循环关联An EXPLAIN statement to show how the optimizer resolves a query. 关键词:explain语句The Connector/J interface provides MySQL support for Java client programs that use JDBC connections JDBC连接采用的是 Connector/J 接口These include both command-line programs such as mysqldump and mysqladmin, and graphical programs such as** MySQL Workbench**. 关键词:一些工具MySQL Server has built-in support for SQL statements to check, optimize, and repair tables. These statements are available from the command line through the mysqlcheck. 关键词:mysqlcheck 工具集MySQL programs can be invoked with the --help or -? option to obtain online assistance 可以使用 --help 来访问在线助手服务器端的主要模块有:
Connections/Thread handling:这就是处理连接的线程(池) 客户端通过JDBC驱动向 Mysql 服务端发起连接,并携带上账号密码以及需要访问的数据库IP和名称,并且可以携带一些URL参数来传递其他信息,最终服务端将连接建立好以后,我们就获得了表示这个连接通路的 Connetction 对象。 服务器端的Connection handling的核心功能有: 1)建立并管理与客户端的连接; 2)验证:验证账号密码,验证URL中的其他配置等,比如开启了SSL认证,则需要进行证书认证。Query Cache:查询缓存 5.7.20之后的版本被废弃了。其原本的设计功能:对于 select 语句的查询结果进行缓存,当再次收到相同的 select 语句后,直接将结果返回,不进行下面的步骤。 这个功能有诸多限制和缺点,分类如下: 1)Queries must be exactly the same (byte for byte) to be seen as identical,也就是 字符串需要完全相同,并且语句中所有信息是确定的,比如包含了函数 NOW() 的语句其查询结果就不会被缓存下来 。下面这两个语句就会判断成两个查询语句: SELECT * FROM tbl_name select * from tbl_name 2)另外一种限制是缓存的失效情景非常多,比如增删改等各种操作。这就导致了缓存命中率非常低,也就是程序花费了额外的时间来执行查询缓存,结果命中率低,导致性价比不高。 3)查询缓存是存储在内存中的,所以对于内存的影响也很大;而且从存储、更新到删除都会消耗性能。 其实,为什么一定要在服务端缓存数据呢?客户端照样可以,所以大家都会接触到比如 mybatis 的二级缓存、redis缓存等。Parser:解析器 这里的解析器实际上起到了我们编程中编译器的作用。对于 SELECT * FROM tbl_name 这样一个字符串,需要经过下面的几个过程,程序才能完整的理解: 1)词法分析:比如 SELECT 是关键字, tb1_name 是表名等 2)语法分析:比如这个是查询语句,其格式满足 sql 格式 3)语义分析:这里的语义分析实际上等同于 预处理器 ,这个预处理器也可归纳到解析器中。预处理器会检查数据列等是否存在,别名是否有歧义,并进行权限验证(是否有执行 select 的权限等) 在 语法分析后,就会生成一棵解析树,类似于编译原理中的 AST(抽象语法树)。Optimizer:优化器 优化器的最终目的是按照一定的指标(优化目标)生成它认为最佳的执行计划。这里的执行计划指的是,比如 A 表和 B 表关联查询,则先查询A表中符合条件的还是先查询B表中符合条件的,这就相当于两种不同的执行计划。这里面有三个关键点:优化指标如何考量?对什么进行优化?优化指标中的一些信息如何获取? mysql的优化策略也分为两种: 1)编译时优化(静态优化):就是对于解析树分析并优化; 2)运行时优化(动态优化):比如查询数据时索引的选择;Storage Engines:存储引擎 首图中没有标明执行引擎,因为是逻辑结构,所以也可以将执行引擎和存储引擎归为一类,他们都属于执行阶段。 在这个阶段,就非常简单了。好比设计师规划好了图纸和方案,工人们只需要按部就班执行即可。 存储引擎对外提供了一些基本的接口,通过这些功能接口的调用组合,可以实现任何数据的增删改查等操作。而执行引擎就是根据优化器提供的执行计划来逐步执行。其他的 cache/buffer 缓存其他过程不再赘述,只提一下数据返回。 Mysql 将结果集返回给客户端是增量、逐步返回的过程,并不是等到全部结果查好再一起返回。
insert into course (c_id,c_name,t_id) values (‘01’,‘语文’,‘02’), (‘02’,‘数学’,‘01’), (‘03’,‘英语’,‘03’);
insert into teacher (t_id,t_name) values (‘01’,‘张维逸’), (‘02’,‘许传科’), (‘03’,‘王明’);
insert into score (s_id,c_id,score) values (‘01’,‘01’,‘80’), (‘01’,‘02’,‘90’), (‘01’,‘03’,‘99’), (‘02’,‘01’,‘70’), (‘02’,‘02’,‘60’), (‘02’,‘03’,‘80’), (‘03’,‘01’,‘80’), (‘03’,‘02’,‘80’), (‘03’,‘03’,‘80’), (‘04’,‘01’,‘60’), (‘04’,‘02’,‘50’), (‘04’,‘03’,‘40’), (‘05’,‘01’,‘58’), (‘05’,‘02’,‘47’), (‘05’,‘03’,‘50’), (‘06’,‘01’,‘99’), (‘06’,‘02’,‘100’), (‘06’,‘03’,‘95’), (‘07’,‘01’,‘90’), (‘07’,‘02’,‘98’), (‘07’,‘03’,‘100’); 4. 创建一张总表 create table total( select a.s_id as s_id,a.s_name as s_name,a.s_age as s_age,a.s_sex as s_sex, b.c_id as c_id,b.score as score,c.t_id as t_id,d.t_name as t_name from student a left join score b on a.s_id=b.s_id left join course c on b.c_id=c.c_id left join teacher d on c.t_id=d.t_id ); select * from total;
SQL语句执行顺序:
1、查询"01"课程比"02"课程成绩高的学生的信息及课程分数 select a.s_id as s_id, score1,score2 from (select s_id, score as score1 from score where c_id=‘01’) a inner join (select s_id, score as score2 from score where c_id=‘02’) b on a.s_id=b.s_id where score1>score2;
2、查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩 select student.s_id as s_id,student.s_name as s_name,b.avg_score as avg_score from student right join (select s_id,avg(score) as avg_score from score group by s_id having avg_score>60) b on student.s_id=b.s_id;
3、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩 select s_id,s_name,count(c_id) as c_num,sum(score) as total_score from total group by s_id;
4、查询“李”姓老师的数量 select count(t_name) from teacher where t_name like ‘李%’;
5、查询学过“王明”老师授课的同学的信息 select distinct s_id,s_name,s_age,s_sex from total where t_name=‘王明’;
6、查询没学过“王明”老师授课的同学的信息 select * from student where s_id not in (select distinct s_id from total where t_name=‘王明’);
7、查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息 select * from student where s_id in (select s_id from score where c_id=‘01’) and s_id in (select s_id from score where c_id=‘02’);
8、查询学过编号为"01"但没有学过编号为"02"的课程的同学的信息 select * from student where s_id in (select s_id from score where c_id=‘01’) and s_id not in (select s_id from score where c_id=‘02’);
9、查询没有学全所有课程的同学的信息 select s_id,s_name,s_age,s_sex from total group by s_id having count(c_id)❤️;
10、查询至少有一门课与学号为"01"的同学所学相同的同学的信息 思路:先找出‘01’同学学过的c_id,再找出学过任一门的s_id,再根据s_id在student找学生信息。 select * from student where s_id in (select distinct s_id from score where c_id in (select c_id from score where s_id=‘01’));
11、查询和"01"号的同学学习的课程完全相同的其他同学的信息 思路:先找学过‘01’同学学过的课程的学生,然后通过group by找这些人里面学的课程数和‘01’相同的人。比如下面,表a是‘01’同学学过的课程,b则是所有学过‘01’同学学过的任一门课程的人。