MySQL语句,体系结构等基础知识解析
MySQL作为工作中频繁使用的数据库,非常值得大家深入学习。
MySQL 是一种开源的关系型数据库管理系统(RDBMS),采用客户端-服务器架构,支持多用户并发访问。它以其高性能、可靠性和易用性著称,广泛应用于 Web 应用程序、数据仓库和嵌入式系统等领域。
SQL语句
结构化查询语言(Structured Query Language) 简称 SQL,是一种特殊目的的编程语言,是一种数据 库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。SQL 是关系数据库 系统的标准语言。 关系型数据库包括:MySQL, SQL Server, Oracle, Sybase, postgreSQL 以及 MS Access等; SQL 命令包括:DQL、DML、DDL、DCL以及TCL。
DQL
Data Query Language - 数据查询语言;
select :从一个或者多个表中检索特定的记录;
DML
Data Manipulate Language - 数据操作语言;
insert :插入记录;
update :更新记录;
delete :删除记录;
DDL
Data Define Languge - 数据定义语言;
create :创建一个新的表、表的视图、或者在数据库中的对象;
alter :修改现有的数据库对象,例如修改表的属性或者字段;
drop :删除表、数据库对象或者视图;
truncate
DCL
Data Control Language - 数据控制语言;
grant :授予用户权限;
revoke :收回用户权限;
TCL
Transaction Control Language - 事务控制语言;
commit :事务提交;
rollback :事务回滚;
数据库术语
数据库:数据库是一些关联表的集合;
数据表:表是数据的矩阵;
列:一列包含相同类型的数据;
行:或者称为记录是一组相关的数据;
主键:主键是唯一的;一个数据表只能包含一个主键;
外键:外键用来关联两个表,来保证参照完整性;MyISAM 存储引擎本身并不支持外键,只起到注 释作用;而 innoDB 完整支持外键;
复合键:或称组合键;将多个列作为一个索引键;
索引:用于快速访问数据表的数据;索引是对表中的一列或者多列的值进行排序的一种结构;
MySQL体系结构
我们接下来逐个介绍组件
MySQL connector
不同语言的代码程序和MySQL的交互。
MySQL 内部连接池
MySQL内部提供的最大连接数量是100多个,并不多所以内部给每一个连接分一个线程处理。
主线程负责接收客户端连接,然后为每个客户端 fd 分配一个连接线程,负责处理该客户端的 sql 命令处理。
SQL接口
SQL接口 将 SQL 语句解析生成相应对象;DML,DDL,存储过程,视图,触发器等。
查询解析器
将 SQL 对象交由解析器验证和解析,并生成语法树。
查询优化器
SQL 语句执行前使用查询优化器进行优化。
那么这里有个问题
执行一条select语句的过程是怎么样的?
首先MySQL接收连接,为这个客户端fd创建一个线程处理,先查询缓存里是否有select的内容,如果有,直接返回(但是这个已经在MySQL8.0删除),没有的话解析SQL语句,生成语法树,接下来进行优化,选择执行代价最小的方法,最后执行。
数据库设计三范式
范式一
保证每一列不可分
例如:地址列:广东省珠海市香洲区
这样的地址就是可分的,如果后续要查询各省数量则要分割字符串才行
范式二
在范式一基础上依赖主键,确保表中的每列都和主键完全依赖,而不能只与主键的某一部分依赖
订单编号 | 商品编号 | 商品名称 | 客户 | 电话 |
1 | 1 | 电脑 | 小张 | 123 |
1 | 2 | 手机 | 小张 | 123 |
2 | 3 | 平板 | 小王 | 321 |
如表格,客户栏依赖订单编号而商品名称依赖商品编号就是不符合的
订单编号 | 客户 | 电话 |
1 | 小张 | 123 |
2 | 小王 | 321 |
这样修改即符合范式
范式三
满足范式二的基础上,确保每列都和主键直接相关,而不是间接相关;减少数据冗余;
反范式
符合范式可以减少储存空间但是我们也有高效的需求,所以必要时基于性能考虑可以进行反范式设计。
五大约束
not null 非空约束
auto_increament 自增约束
unique 唯一约束
primary 主键约束(非空且唯一)
foreign 外键约束
基本语句
创建数据库
CREATE DATABASE `数据库名` DEFAULT CHARACTER SET utf8; # 字符集设置为 utf8
删除数据库
DROP DATABASE `数据库名`;
选择数据库
USE `数据库名`;
创建表
CREATE TABLE `table_name` (column_name column_type);CREATE TABLE IF NOT EXISTS `0voice_tbl` (`id` INT UNSIGNED AUTO_INCREMENT COMMENT '编号',`course` VARCHAR(100) NOT NULL COMMENT '课程',`teacher` VARCHAR(40) NOT NULL COMMENT '讲师',`price` DECIMAL(8,2) NOT NULL COMMENT '价格',PRIMARY KEY ( `id` ), ## not null unique)ENGINE=innoDB DEFAULT CHARSET=utf8 COMMENT = '课程表';
删除表
DROP TABLE `table_name`;
# 把数据和表都删除
清空数据表
TRUNCATE TABLE `table_name`; -- 截断表 以页为单位(至少有两行数据),有自增索引的话,从初始
值开始累加
DELETE TABLE `table_name`; -- 逐行删除,有自增索引的话,从之前值继续累加
增
INSERT INTO `table_name`(`field1`, `field2`, ..., `fieldn`) VALUES (value1,
value2, ..., valuen);
删
DELETE FROM `table_name` [WHERE Clause];
查
SELECT field1, field2,...fieldN FROM table_name[WHERE Clause]
改
UPDATE table_name SET field1=new_value1, field2=new_value2 [, fieldn=new_valuen]
高级查询
基础查询
-- 全部查询
SELECT * FROM student;
-- 只查询部分字段
SELECT `sname`, `class_id` FROM student;
-- 别名 列明 不要用关键字
SELECT `sname` AS '姓名' , `class_id` AS '班级ID' FROM student
;-- 把查询出来的结果的重复记录去掉
SELECT distinct `class_id` FROM student;
条件查询
-- 查询姓名为 邓洋洋 的学生信息
SELECT * FROM `student` WHERE `name` = '邓洋洋';
-- 查询性别为 男,并且班级为 2 的学生信息
SELECT * FROM `student` WHERE `gender`="男" AND `class_id`=2;
范围查询
-- 查询班级id 1 到 3 的学生的信息
SELECT * FROM `student` WHERE `class_id` BETWEEN 1 AND 3;
判空查询
# is null 判断造成索引失效
# 索引 B+ 树
SELECT * FROM `student` WHERE `class_id` IS NOT NULL; #判断不为空
SELECT * FROM `student` WHERE `class_id` IS NULL;
#判断为空
SELECT * FROM `student` WHERE `gender` <> '';
SELECT * FROM `student` WHERE `gender` = '';
#判断不为空字符串
#判断为空字符串
模糊查询
-- 使用 like关键字,"%"代表任意数量的字符,”_”代表占位符
-- 查询名字为 谢 开头的学生的信息
SELECT * FROM `teacher` WHERE `tname` LIKE '谢%';
-- 查询姓名里第二个字为 小 的学生的信息
SELECT * FROM `teacher` WHERE `tname` LIKE '_小%';
查询后排序
-- 关键字:order by field, asc:升序, desc:降序
SELECT * FROM `score` ORDER BY `num` ASC;
-- 按照多个字段排序
SELECT * FROM `score` ORDER BY `course_id` DESC, `num` DESC;
聚合查询
聚合函数 | 描述 |
sum() | 计算某列总和 |
avg() | 计算某列平均值 |
max() | 计算某列最大值 |
min() | 计算某列最小值 |
count() | 计算某列行数 |
SELECT sum(`num`) FROM `score`;SELECT avg(`num`) FROM `score`;SELECT max(`num`) FROM `score`;SELECT min(`num`) FROM `score`;SELECT count(`num`) FROM `score`;
分组查询
-- 分组加group_concatSELECT `gender`, group_concat(`age`) as ages FROM `student` GROUP BY `gender`;
-- 可以把查询出来的结果根据某个条件来分组显示
SELECT `gender` FROM `student` GROUP BY `gender`;
-- 分组加聚合
SELECT `gender`, count(*) as num FROM `student` GROUP BY `gender`;
-- 分组加条件
SELECT `gender`, count(*) as num FROM `student` GROUP BY `gender` HAVING num > 6;
联表查询
大体图如下
INNER JOIN
在内连接的基础上保留左表没有对应关系的记录
SELECTcidFROM`course`INNER JOIN `teacher` ON course.teacher_id = teacher.tid;
LEFT JOIN
在内连接的基础上保留右表没有对应关系的记录
SELECTcourse.cidFROM`course`LEFT JOIN `teacher` ON course.teacher_id = teacher.tid;
RIGHT JOIN
在内连接的基础上保留右表没有对应关系的记录
SELECTcourse.cidFROM`course`RIGHT JOIN `teacher` ON course.teacher_id = teacher.tid;
视图
视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。其内容由查询定义。 基表:用来创建视图的表叫做基表; 通过视图,可以展现基表的部分数据;视图数据来自定义视图的查询中使用的表,使用视图动态生成。
实例
最后我们实际完成一些问题
1.查询“语文”课程比“数学”课程成绩高的所有学生的学号;
select A.student_id
(select student_id num from score where course_id =
(select cid from course where cname = "语文")) as A
inner join
(select student_id num from score where course_id =
(select cid from course where cname = "数学")) as B
on A.student_id = B.student_id
where A.num > B.num ;//如果可以没有数学成绩select A.student_id
(select student_id num from score where course_id =
(select cid from course where cname = "语文")) as A
inner join
(select student_id num from score where course_id =
(select cid from course where cname = "数学")) as B
on A.student_id = B.student_id
where A.num > if(isnull(B.num),0,B.num);
2.查询平均成绩大于60分的同学的学号和平均成绩;
select student_id avg(num) as avg_num
from score
group by tudent_id
having avg_num > 60
更多资料在:https://github.com/0voice查询