1.基础操作
MySQL服务器->许多数据库->许多数据表->
指定表头,表头描述了列名和列类型->
每行为一个记录,每列为一个字段
数据类型:tinyint(1字节),smallint(2字节),int(4字节),bigint(8字节)
float(m,d),double(m,d);m为有效数字,d为小数位数
decimal(m,d);能够精确表示小数
datetime(8字节),timestamp(4字节)
注释:# 或者 --后面有个空格 快捷键:
终止输入键: ctrl+c
复制键:选中+enter 显示警告:show warnings;
2.库操作
显示数据库:show databases;
选中数据库: use 数据库名; use database1;
创建数据库:create database 数据库名; create database database1;
删除数据库:drop database 数据库名;drop database database1;
3.表操作
创建表:creat table 表名(列名 类型,列名 类型);
create table student(id int, namevarchar(50), age int, score double(3,1));
查看表:show tables;
查看表结构:desc 表名; desc student;
删除表:drop table 表名; drop table student;
4.SQL的操作CURD(增删查改) C创建 U修改 R查询 D删除
4.1 创建
插入数据:insert into 表名 values(列的值…),(列的值)…;
insert into exam_result values(1, ‘唐三藏’, 67, 98, 56),
(2, ‘孙悟空’, 87, 78, 77),
(3, ‘猪悟能’, 88, 98, 90),
(4, ‘曹孟德’, 82, 84, 67),
(5, ‘刘玄德’, 55, 85, 45),
(6, ‘孙权’, 70, 73,78.5),
(7, ‘宋公明’, 75, 65, 30);
插入部分列:inset into 表名(列名…) values(列的值);
insert into exam_result(id, name) values(7, ‘沙悟净’);
插入日期:
指定格式: insert into date values(1, ‘-02-13 21:03’);
now()函数:insert into date values(1, now());
4.2 查找
全列查找:select * from 表名;//*通配符
select * from exam_result;
指定列查找:select 列名,列名… from 表名;
select id, name from exam_result;
带表达式的查找:select 表达式 from 表名;//表达式是列和列的计算
select chinese + math + english from exam_result;
带别名的查找:select 表达式 as 别名 from 表名;//给表达式列起的别名
select chinese + math + english as total from exam_result;
查找结果去重:select distinct 列名 from 表名;
select distinct id from exam_result;
排序:select 列名 from 表名 order by 列名 asc/desc; 列名 asc、desc;//默认升序
select math, english from exam_result order by math desc, english desc;
根据别名排序:select 表达式 as 表达式别名 from 表名 order by 别名;
select english + math + chinese as total from exam_result order by total desc;
条件查询:select 列名 from 表名 where 条件;
//关于比较null;使用is null/is not null或者<=>null 不可使用=null!!
//where条件里不能用别名!
比较运算符:
>,>=,<,<=//比较大小
=,<=>//比较相等,区别=不能比较null,<=>可以比较
between a0 and a1//构成闭区间[a0,a1]
in(option, …)//通过()里给定固定的值,判断结果是否在这几个值里
is null/is not null//专门比较空值 like //模糊匹配 %代表任意个任意字符 _代表一个任意字符
and// 与&& 要注意表达式里同时有and和or,先计算and再计算or,如果想要打破优先级就得加()
or// 或||
not// 非!
使用实例:
查询英语不及格同学及英语成绩
select name,english from exam_result where english<60;
查询语文成绩好与英语成绩的同学 select name, chinese, english from exam_result
where chinese > english; //显示列和查询条件互不影响
查询总分在200以下的同学
select name, chinese + math + english as total from exam_result where chinese + math + english <200;
//显示列和查询条件互不影响,所以where这里不能用别名
查询语文成绩大于80分,且英语成绩大于80分的同学
select name, chinese, english from exam_result where chinese > 80 and english > 80;
查询语文成绩在[80,90]分的同学及语文成绩
select name, chinese from exam_result where chinese between 80 and 90;
select name, chinese from exam_result where chinese >= 80 and chinese <= 90;
查询数学成绩是58或者59或者98或者99分的同学及成绩
select name, math from exam_result where math in(58, 59, 98, 99);
select name, math from exam_result where math = 58 or math = 59 or math = 98 or math = 99;
查找姓孙的同学的成绩
select name, chinese, math, english from exam_result where name like ‘孙%’;
查找姓孙的名字是两个汉字的同学的成绩 select name, chinese, math, english from
exam_result where name like ‘孙_’;
查询语文成绩为空的同学信息
select * from exam_result where chinese is null;
select * from exam_result where chinese <=> null;
分页查询:SQL中可以通过limit来实现分页查询
使用实例:(假设一页只显示3条记录)
select * from exam_result limit 3; //这是第一页的记录,也可在最后加上offset 0 select *
from exam_result limit 3 offset 3; //这是第二页的记录 select * from
exam_result limit 3 offset 6; //这是第三页的记录
4.3 修改
update 表名 set 列名 = 值, 列名 = 值 where 条件;
//对符合条件的进行修改
//order by 和 limit都是可以使用的
//update是会修改原始数据的
使用实例:
将孙悟空同学的数学成绩变为80分
update exam_result set math = 80 where name = ‘孙悟空’;
将曹孟德的数学成绩变成60,语文成绩变为70
update exam_result set math = 60, chinese = 70 where name = ‘曹孟德’;
将总成绩倒数前三的3位成绩的数学成绩加上30分
update exam_result set math = math + 30 order by chinese + math + english limit 3;
将所有同学的语文成绩更新为原来的0.5
update exam_result set chinese = chinese * 0.5;
4.4 删除
delete from 表名 where 条件; //删除表的所有记录是得到一个空表,drop table是表也没有了
delete from exam_result where name = ‘沙悟净’;
5.SQL的约束
not null//指示某列不能存储null值
create table people(id int not null, name varchar(20));
unique//保证某列的每行必须有唯一的值,插入重复的数据会报错
create table people1(id int unique, name varchar(20));
default//规定没有给列赋值时的默认值,mysql默认的默认值时null
create table people2(id int, name varchar(20) default ‘匿名’);
primary key//not null 和 unqiue的结合
create table people3(id int primary key, name varchar(20));
primary key auto_increment //自增主键
5.2 外键约束
举例:学生表依赖了班级表,学生表称为子表,班级表称为父表
foreign key//针对两张表
create table student(studentId int primary key auto_increment, name varchar(20), classId int, foreign key (classId) references class(classId));
//foreign key (classId) references class(classId)
//前者classId为该表的一列,references为引用,class(classId)中class为引用的父表,classId为引用的父表的列,重名可以这样写
//注意1:外键约束时会先查询是否符合约束,查询是个耗时的操作,因此要求父表该列必须要有索引,所以引用父表的列必须是primary key或者unique!
//注意2:新增和修改时,子表的该列都受约束
6.数据库设计
6.1 实体关系表示
一对一关系表示:
1.两个实体用一张表来表示
2.用两张表表示,其中一张表表包含另一张表的id
一对多的关系表示:(以一个学生处于一个班级,一个班级可以有多个学生举例)
1.在班级表中增加一列表示这个班级学生id都有啥
2.班级不变在学生表中增加一列classId
多对多的关系表示:(以一个学生可以选多个课程,一个课程可以包含多学生举例)
1.创建关联表表示两个实体间的关系,例如学生课程表(学号,课程编号)
7. 查询结合新增操作
insert into B select * from A; insert into B select name, id from A;
//在这个语句中会先进行A查找操作,把结果插入B中
//需要注意的是A表和B表列数和类型要匹配
8.聚合查询
定义:把多个行数据惊醒了关联操作,注意:带表达式的查找是属于列和列之间的关联运算。
8.1 计算行数
select count(*) from exam_result; select count(chinese) from exam_result;
//指定列
8.2 求和
select sum(price) from book;
//只能针对数字,不可针对字符串
select sum(chinese + english + math) from exam_result;
//聚合函数也是表达式的一部分
8.3 分组操作
select role, max(salary) from emp group by role;
//也可别名max(salary) as max
group by字句分组之后可以使用having过滤结果,值得注意的是where使用在分组之前的,having是分组之后的
举例:
select role, avg(salary) from emp where name != ‘马云’ group by role;
select role, avg(salary) from emp group by role having avg(salary) < 10000;
9. 联合查询
定义:把多个表合并到一起,使用笛卡尔积实现多表查询。
方法1:
笛卡尔积:任意两张表之间的运算,及A表对应的每一行和B表的每一行进行拼接。此时笛卡尔积的列数就是A+B,行数就是A*B.
select * from student, class where student.classId = class.classId;
//如果笛卡尔积中列名相同,可以通过表名.列名方式访问
方法2:
select * from 表1 join 表2 on 条件 join 表3 on 条件;
方法1写法叫做内连接,join on的写法吉克表示内连接叶可表示外连接。针对列内容不匹配的时候内连接会导致数据丢失,比如一个学生表的classId列有1,2,3但是班级表只有1,2这就会导致3的数据丢失。使用外连接就不会导致数据丢失。
select 列 from 表1 inner join 表2 on 条件;
//inner join表示内连接,其中inner可以省略
select 列 from 表1 left join 表2 on 条件;
//左外连接
select 列 from 表1 right join 表2 on 条件;
//右外连接 内连接的记录就只包含两个表中同时拥有的记录。
左外连接就是以左侧标为主,左侧标的每一个记录都在左外连接中体现。右边表没有的就填成null; 右外连接同理。
10. 自连接
定义:自己和自己进行笛卡尔积,本质是把行和行的比较条件变成列和列的。
select * from score as s1, score as s2 where s1.student_id = s2.student_id;
11.子查询
定义:把多个select合并成一个,套娃 select name from student where class_id = (select class_id from student where name = ‘不想毕业’);
//有时候子查询可能会查询出多条记录,不能直接使用=,可以使用in
12. 合并查询
union和union all
定义:就是把多个查询结果给合并到了一起,合并前提是两个sql查询的列是对应的,or也是可以实现的但是or只能针对一张表。union操作会自动去重,union all则不会。
select* from course where name = ‘英文’ union select * from course where id < 3;
13. 索引和事务
13.1 索引
定义:相当于一本书的目录,根据目录中对应章节的页码就能找到相应章节。索引就是为了进行查找,提高找效率。能够提高查找的速度,但是占用了更多的空间且拖慢了增删改的速度。适用于需要经常查找不经常修改的场景。
查看索引:show index from 表名;
//一般索引为主键约束带来的,unique也带
创建索引:create index 索引名字 on 表名(列名);
删除索引:drop index 索引名字 on 表名;
索引背后的数据结构:多叉搜索树(B+树)
B树:N个key值换分出N+1个区间,每个区间对应一颗子树。与二叉搜索树相比高度是少了但是每个节点比较次数多了,相比于比较次数来说,IO次数更是关键。
B+树:B+树也是一个N叉搜索树,每个节点都包含N个key值,每个节点又会分为N个区间。父亲节点中的值会作为子节点中的最大值(最小值),最下面的叶子结点就是用链表进行顺序连接。
特点:
1.父节点的值都会在子节点中体现
2.非叶子节点的值都会在叶子节点中体现
3.最下面叶子节点使用链表进行按顺序连接做为索引的优势:整体IO次数少
4. 所有查询最终都会落在叶子节点,查询IO次数都是差不多的因此查询素速度稳定
5.叶子结点用链表连接以后非常适合进行范围查找,例如找 >= 5 且 <= 11的值
6.所有数据的存储都是放在叶子节点上的,非叶结点只需要保存key值即可,非叶节点占用空间小甚至可以缓存到内存中,这时磁盘IO几乎就没了