目录
数据库
类型
- 网状数据库
- 层次数据库
- 关系型数据库,硬盘(Oracle、DB2、SQL Server、MySQL)
- 非关系型数据库NOSQL ,存在内存(Memecached、MongoDB<Json字符串>、redis、HBase)
MySQL层次 :不同项目对应不同的数据库,不同数据库中有不同的表,每张表中存储的是数据
任何数据和NULL进行算术运算结果都为NULL
SQL语言
通用语法
SQL(Structured Query Language),结构化查询语言,一门操作关系型数据库的编程语言,定义操作所有的关系型数据库的统一标准
SQL语句可以单行或多行书写,以分号为结尾,而且不区分大小写,关键字建议使用大写
注释:
- 单行注释: – 注释内容(–后一定要跟个空格再写注释内容) 或 #注释内容(MySQL特有)
- 多行注释:/* 注释 */
语言分类的操作
DDL
(Data Definition Language)数据定义语言,用来定义数据库对象(数据库、表、索引、视图、触发器、存储过程、函数)
DDL操作数据库
- 查询
SHOW:展示
SHOW DATABASES #查询存在的所有的数据库名
SHOW CREATE TABLE <表名> ; #查看建表语句
- 创建
CREATE DATABASE [数据库名] #创建数据库
CREATE DATABASE IF NOT EXISTS [数据库名称] #创建数据库(判断,如果不存在则创建)
CREATE TABLE <表名> (字段名 类型(显示长度),字段名 类型(显示长度),…) ;
- 删除
DROP DATABASE [数据库名称] #删除数据库
DROP DATABASE IF EXISTS [数据库名] #删除数据库(判断,如果存在则删除)
DROP TABLE <表名> ;
- 使用
SELECT DATABASE(); #查看当前使用的数据库,DATABASE后跟个()代表是函数的意思
USE [数据库名] #使用数据库
ALTER:修改
ALTER TABLE <表名> (ADD增加 / DROP删除 / MODIFY修改列的类型,不改变列名字 / CHANGE修改列名和列的类型定义) <列名 数据类型> (FIRST首位 / AFTER <字段名>放在某个字段之后);
DDL操作表(CRUD)
- 查询(Retrieve)
SHOW TABLES; #查询当前数据库下所有表名称
DESC [表名]; #查询表结构
- 创建(Create)
CREATE TABLE [表名] (
字段1 数据类型1,
字段2 数据类型2,
……
字n 数据类型n
); #注意:最后一行末尾,不能加逗号
- 删除(Delete)
DROP TABLE [表名]; #删除表
DROP TABLE IF EXISTS [表名]; #删除表(判断,如果存在则删除)
- 修改(Update)
ALTER TABLE [表名] RENAME TO [新的表名]; #修改表名
ALTER TABLE [表名] ADD [列名] [数据类型]; #添加一行
ALTER TABLE [表名] MODIFY [列名] [新的数据类型]; #修改数据类型
ALTER TABLE [表名] CHANGE [列名] [新的列名] [新的数据类型]; #修改列名和数据类型
ALTER TABLE [表名] DROP [列名]; #删除列
DML
(Data Manipulation Language)数据操作语言,用来对数据库中的数据进行增删改
- 添加(insert)
INSERT INTO [表名(列名1,列名2,……)] VALUES(值1,值2,……); #给指定列添加数据,如果是给所有列添加数据,列名可以省略
INSERT INTO [表名] VALUES(值1,值2,……); #给全部列添加数据
#批量添加数据
INSERT INTO [表名(列名1,列名2,……)] VALUES(值1,值2,……),(值1,值2,……),(值1,值2,……)……;
INSERT INTO [表名] VALUES(值1,值2,……),(值1,值2,……),(值1,值2,……)……;
- 修改(update)
UPDATE [表名] SET [列名1=值1,列名2=值2,……] [WHERE 条件]; #修改表数据
#注意:修改语句中如果不加条件,则将表中所有数据都修改
- 删除(delete)
DELETE FROM [表名] [WHRER 条件]; #删除 数据
#注意:删除语句中如果不加条件,则将表中所有数据都删除
DQL
(Data Query Language)数据查询语言,用来用来查询数据库中表的记录(数据)
SELECT:查询 distinct(去重关键字)
SELECT <*表示全字段,可以用个别字段名替代> as(可省略) 别名(别名里面如果有特殊符号时候必须给别名带上单引号或者双引号,不可省略,其余情况可以省略) FROM <表名> ;
WHERE:筛选限制(分组前过滤),binary(区分大小写关键字)
-
加关系运算符(>、<、>=、<=、<>、!=)
-
加逻辑运算符
-
与关系(&&、and 都是双向开区间、between 是双向闭区间)
-
或关系(or、||、in),注意:and和or一起用,一般是先and后or
-
模糊查询(like %任意多个字符、_任意一个字符)
-
NULL(is null ,is not null)
-
-
order by:排序(默认是asc升序,desc是降序)
-
group by:分组
-
having:分组后进行二次查询
#select语句总结:
SELECT
字段列表
FROM
表名列表
WHERE
条件列表
GROUP BY
分组字段
HAVING
分组后条件
ORDER BY
排序字段
LIMIT
分页限定
#注意:顺序固定,不可改变顺序
执行顺序:from -> where -> group by ->select -> having -> order by
基础查询
- 查询多个字段
SELECT [字段列表] FROM [表名];
SELECT * FROM [表名]; #查询所有数据
- 去除重复数据
SELECT DISTINCT [字段列表] FROM [表名];
- 起别名
AS:AS也可以省略
条件查询(WHERE)
语法:
SELECT [字段列表] FROM [表名] WHERE [条件列表];
条件:
排序查询(ORDER BY)
语法:
SELECT [字段列表] FROM [表名] ORDER BY [排序字段名1 排序方式1,排序字段名2 排序方式2,……];
排序方式:
- ASC:升序排列(默认值)
- DESC:降序排列
注意: 如果有多个排序条件,当前边条件值一样时,才会根据第二条件进行排序
聚合函数
将一列数据作为一个整体,进行纵向计算
分类:
语法:
SELECT [聚合函数名(列名)] FROM [表];
注意: null值不参与所有聚合函数的运算
分组查询(GROUP BY)
语法:
SELECT [字段列表] FROM [表名] {WHERE [分组前条件限定]} GROUP BY [分组字段名] {HAVING [分组后条件过滤]};
注意: 分组之后,查询的字段为聚合函数和分组字段,查询其他字段无任何意义
where和having的区别:
- 执行时机不一样:where是分组之前进行限定的,不满足where条件,则不参与分组,而having是分组之后对结果进行过滤
- 可判断的条件不一样:where不能对聚合函数进行判断,having可以
执行顺序:where > 聚合函数 > having
分页查询(LIMIT)
语法:
SELECT [字段列表] FROM [表名] LIMIT [起始索引] , [查询条目数];
- 起始索引:从0开始
计算公式:起始索引 = (当前页码数 - 1)*每页显示的条数
tips:
- 分页查询 limit 是MySQL数据库的“方言”
- Oracle分页查询使用 rownumber
- SQL Server分页查询使用top
DCL
(Data Control Language)数据控制语言,用来定义数据库的访问权限和安全级别,及创建用户,回收或授予数据库权限
- GRANT:授予用户权限
- REVOKE:回收权限
- 事务控制语言(Transation Control Language,TCL):
- START TRANSACTION:开启事务
- COMMIT:提交
- ROLLBACK:回滚
- SET TRANSACTION:设置
快速添加:
-
复制(结构+数据):create table <新创建的表名> as select * from <要复制的表名> ;
-
复制(仅结构):create table <新创建的表名> as select * from <要复制的表名> where 1=2 ;
-
复制 (部分列部分数据):create table <新创建的表名> as select <需要的复制表的字段> from <要复制的表名> where <筛选条件> ;
删除数据:
- delete from <要删除数据的表名> ;
- truncate table <要删除数据的表名> ;
delete和truncate区别:
- DELETE为数据操作语言(DML),TRUNCATE为数据定义语言(DDL)
- DELETE操作是将表中所有记录一条一条删除直到删完位置,TRUNCATE保留了表结构,重新构造了表,所有状态相当于新表,所以TRUNCATE操作效率更高
- DELETE操作可以回滚,TRUNCATE操作会导致隐式提交,不能回滚
- DELETE操作执行成功会返回已删除的行数,截断操作则不会,DELETE操作删除数据后再添加新数据的时候会继续使用之前的主键自增到的值,TRUNCATE操作则重新从1开始自增。
约束
约束的概念:
- 约束是作用于表中列上的规则,用于限制加入表的数据
- 约束的存在保证了数据库中数据的正确性、有效性和完整性
约束的分类:
添加方式:
- 建表时
CREATE TABLE 表名(
列名1 数据类型 NOT NUll,
列名2 数据类型 [约束类型],
……
);
- 建表后
ALTER TABLE [表名] MODIFY [字段名] [数据类型] [约束类型]; #添加约束
ALTER TABLE [表名] MODIFY [字段名] [数据类型]; #删除约束
Tips: MySQL中不支持检查约束
外键约束:
概念:用来让两个表的数据之间建立连接,保证数据一致性和完整性
语法:
- 建表时
CREATE TABLE 表名 (
列名1 数据类型,
列名2 数据类型,
……,
[CONSTRAINT] [自己起的外键名称] FOREIGN KEY(外键列名) REFERENCES [主表(主表列名)]
); #创建表时添加约束
- 建表后
ALTER TABLE [表名] ADD CONSTRAINT [外键名称] FORREIGN KEY(外键字段名称) REFERENCES [主表(主表列名)]; #建表后添加外键约束
ALTER TABLE [(从)表名] DROP FORREIGN KEY [自己起的外键名称]; #建表后删除外键约束
数据库设计
概念:
- 数据库设计就是根据业务系统的具体需求,结合DBMS,为这个业务系统构造出最优的数据存储模型
- 建立数据库中表结构以及表与表之间的关联关系的过程
- 有哪些表?表里有哪些字段?表和表之间有什么关系?
步骤:
- 需求分析(数据是什么?数据具有哪些属性?数据与属性的特点是什么)
- 逻辑分析(通过ER图对数据库进行逻辑建模,不需要考虑所选用的DBMS)
- 物理设计(根据数据库自身的特点把逻辑设计转换为物理设计)
- 维护设计(1.对新的需求进行建表;2.表优化)
表关系
-
一对一:(用户和用户详情)
- 实现方式:在任意一方加入外键,关联另一方主键,并且设置外键为唯一(UNIQUE)
-
一对多(多对一):部门和员工(一个部门对应多个员工,一个员工对应一个部门)
- 实现方式:在多的一方建立外键,指向一 的一方的主键
-
多对多:商品和订单(一个商品对应多个订单,一个订单包含多个商品)
- 实现方式:建立第三张中间表,中间表至少包含两个外键,分别是关联两方主键
多表查询
多表查询:从多张表查询数据,使用笛卡尔积的形式进行组合展示
笛卡尔积:取A、B集合所有组合情况
连接查询
内连接:相当于A、B交接数据
-
隐式内连接:
-
SELECT [字段列表] FROM [表1,表2……] WHERE [条件];
-
-
显示外连接:
-
SELECT [字段列表] FROM 表1 [INNER] JOIN 表2 ON [条件];
-
外连接:
-
左外连接:相当于查询A表所有数据和交集部分数据
-
SELECT [字段列表] FROM 表1 LEFT [OUTER] JOIN 表2 ON [条件];
-
-
右外连接:相当于查询B表所有数据和交集部分数据
-
SELECT [字段列表] FROM 表1 RIGHT [OUTER] JOIN 表2 ON [条件];
-
-
全外连接:查询A、B所有数据
子查询
概念:查询中嵌套查询,称嵌套查询为子查询
子查询根据查询结果的不同,作用不同:
-
单行单列:作为条件值,使用=、!=、>、<等进行条件判断
-
SELECT [字段列表] FROM [表] WHERE [字段名] = (子查询);
-
-
多行单列:作为条件值,使用
in
等关键字进行条件判断-
SELECT [字段列表] FROM [表] WHERE [字段名] in (子查询);
-
-
多行多列:作为虚拟表
-
SELECT [字段列表] FROM (子查询) WHERE [条件];
-
数据类型
数值类型
- 整数类型
整数类型 | 大小 | 作用 |
---|---|---|
TINYINT | 1字节 | 小整数值 |
SAMALLINT | 2字节 | 大整数值 |
MEDIUMINT | 3字节 | 大整数值 |
INT | 4字节 | 大整数值 |
BIGINT | 8字节 | 极大整数值 |
MySQL支持选择在该类型关键字后面的括号内指定整数值的显示宽度,显示宽度并不限制可以在列内保存的值的范围,也不限制超过列的指定宽度的值的显示。
- 浮点数类型
浮点数类型 | 大小 | 作用 |
---|---|---|
FLOAT | 4字节 | 单精度浮点数 |
DOUBLE | 8字节 | 双精度浮点数 |
浮点数类型的宽度不会自动扩充,如:score double(4,1),小数部分为1位,总宽度为4位,并且不会自动扩充。
字符串类型
字符串类型 | 大小 | 描述 |
---|---|---|
CHAR(M) | 0~255字符 | 允许长度0~M个字符的定长字符串 |
VARCHAR | 0~65535字符 | 允许长度0~M个字符的变长字符串 |
TEXT | 0-65,535字节 | 长文本数据 |
BLOLB | 0-65,535字节 | 二进制形式的长文本数据(音频、视频) |
字符串不区分单引号和双引号
日期和时间类型
类型 | 格式 | 取值范围 | 0值 |
---|---|---|---|
DATE | “YYYY-MM-DD” | 年月日 | “0000-00-00” |
DATETIME | “YYYY-MM-DD HH-MM-SS” | 年月日 时分秒 | “0000-00-00 00:00:00” |
TIMESTAMP | “YYYY-MM-DD HH-MM-SS” | 时间戳 | “0000-00-00 00:00:00” |
插入时间方式多样’2023-08-08’ “2023/08/08” “2023.08.08” ,插入当前时间用now()、sysdate()、CURRENT_DATE()
TIMESTEMP类型数据指定方式与DATETIME基本相同,两者的不同之处在于以下几点:
- 数据的取值范围不同,TIMESTEMP类型的取值范围更小
- 如果未对TIMESTAMP类型字段赋值或者赋值为NULL,MySQL自动将字段赋值为系统当前的日期与时间
- TIMESTAMP类型还可以使用CURRENT_TIMESTAMP来获取系统当前时间
- TIMESTAMP类型可以根据时区显示
DML使用时的一些注意事项:
- 关键字、表名、字段名不区分大小写
- 默认情况下,内容不区分大小写
- 删除操作from关键字不可少
- 修改,删除操作需加限制条件,不然影响数据库全部数据
- 字段名内容、数据内容等字符串不区分大小写
表的完整性约束:
保证数据库中数据的准确性和一致性
约束从作用上分为:
- 表级约束:约束表中任意一个或多个字段,与列定义相互独立,不包含在列定义中,与定义用’,'(逗号)分割,必须要指出约束列的名称
-- 创建表时的SQL:
create table t_student(
sno int(6) auto_increment,
sname varchar(5) not null,
sex char(1) default '男',
age int(3),
enterdate date,
classname varchar(15),
email varchar(15),
constraint pk_stu primary key(sno), -- pk_stu主键约束的名字
constraint ck_stu_sex check(sex = '男' || sex = '女'),
constraint ck_stu_age check(age >= 18 || age <= 50),
constraint uq_stu_email unique(email)
);
-- 创建数据库
drop table if exists t_student;
create table t_student(
sno int(6),
sname varchar(5) not null,
sex char(1) default '男',
age int(3),
enterdate date,
classname varchar(10),
email varchar(15)
);
-- 创建表后添加约束
alter table t_student add constraint pk_stu primary key (sno);
alter table t_student modify sno int(6) auto_increment;
alter table t_student add constraint ck_stu_sex check(sex = '男' || sex = '女');
alter table t_student add constraint ck_stu_age check(age >= 18 || age <= 50);
alter table t_student add constraint uq_stu_email unique(email);
- 列级约束:包含在列定义中,直接跟在该列的其他定义之后,用空格分隔,不必指定列名
约束条件 | 约束描述 |
---|---|
PRIMARY KEY | 主键约束(非空 + 唯一,如果是整数要自增 auto_increment) |
NOT NULL | 非空约束 |
UNIQUE | 唯一约束 |
CHECK(8之后有) | 检查约束 |
DEFAULT | 默认值约束 |
AUTO_INCREMENT | 自动增加约束 |
FOREIGN KEY | 外键约束,约束表与表之间的关系 |
如果插入的SQL报错,会浪费掉一个主键的值,之后的主键不连号继续递增
外键约束:指表中的某个字段的值依赖于另一张表中某个字段的值,被依赖的字段必须具有主键约束或者唯一约束,被依赖的叫父表或主表,设置外键约束的表称为子表或者从表。外键约束只有表级约束,没有列级约束。
-- 创建班级表
drop table if exists t_class;
create table t_class (
cno int(4) primary key auto_increment,
cname varchar(10) not null,
room char(4)
);
insert into t_class values(null,'java101','10403');
insert into t_class values(null,'java101','10203');
insert into t_class values(null,'测试101','09403');
-- 一行插入多组数据
insert into t_class values(null,'测试101','09403'),(null,'java101','10203'),(null,'java101','10403');
drop table if exists t_student;
-- 创建表时添加外键
create table s_student(
sno int(6) primary key auto_increment,
sname varchar(5) not null,
classno int(4),
constraint fk_stu_classno foreign key (classno) references t_class(cno)
);
-- 创建表后添加外键
alter table t_student add constraint fk_stu_classno foreign key (classno) references t_class(cno);
外键策略:
-
no action:修改从表中与主表关联的字段的内容(全部,也就是说从表中与主表没有关联信息),然后再操作主表对应字段的对应条件
-
cascade(级联操作):删除之前的外键约束,再重新添加新的外键约束,会导致直接把从表中和主表关联的数据删除
-
alter table t_student drop foreign key fk_stu_classon; -- 删除之前的外键约束 alter table t_student add constraint fk_stu_classno foreign key (classno) references t_class (cno) on update cascade on delete cascade; -- 添加新的外键约束
-
-
set null 置空操作:删除之前的外键约束,再重新添加新的外键约束,会导致直接把从表中和主表关联的数据置为NULL
-
alter table t_student drop foreign key fk_stu_classon; -- 删除之前的外键约束 alter table t_student add constraint fk_stu_classno foreign key (classno) references t_class (cno) on update set null on delete set null; -- 添加新的外键约束
-
-
cascade 和 set null 混合使用
函数
函数是对特定功能进行的封装,函数只是把真实数据进行了加工然后展现出来,并没有改变数据内容
单行函数: 对每一条输入值进行计算得到相对应的计算结果
多行函数: 对一组数据进行运算,只返回一个结果
除了多行函数都是单行函数,多行函数仅有(max、min、count、sum、avg)
select abs(-5) 绝对值,cell(5.3) 向上取整,floor(5.9) 向下取整, round(3,14) 四舍五入 from dual ;
-- 如果没有where条件可以不用加from dual(伪表)
-- 时间函数
select curdate() 年月日,curtime() 时分秒;
select now() 当前时间,sysdate() 函数执行的的日期时间,sleep(3),now() ,sysdate() from dual;
-- 流程函数
-- if相关
select sno , if(sno>=2600,'高工资','低工资') as '薪资等级' from s_student ;-- if-else双分支
select sno , ifnull(sno,0) from s_student ; -- 如果sno是null,则取值为0,否则取本身的值
select nullif(1,2) , nullif(1,1) from dual; -- 如果两值相等,返回null,不过不相等,返回第一个值
-- case 相关
-- case 等值判断
select empno,ename,job,
case job
when 'CLERK' then '店员'
when 'SALESMAN' then '销售'
when 'MANNAGER' then '经理'
else '其他'
end '岗位',
sal from emp ;
-- 区间判断
select empno,ename,sal,
case
when sal<=1000 then 'A'
when sal<=2000 then 'B'
when sal<=3000 then 'C'
else 'D'
end '工资等级',
sal from emp ;
-- 其他函数
select database(),user(),version() from dual ;
多表查询
99语法:
- **交叉连接:**笛卡尔积查询,通过where筛选数据
select (*) from <表1> cross join <表2> ;(cross在MySQL中可以省略)
- 自然连接:优点也是缺点:自动匹配所有同名列
select *
from <表1>
natural join <表2> ;
-- 优化查询效率,指定字段查询
select 表1.字段名A , 表1.字段名B , 表2.字段名A , ....
from <表1>
natural join <表2> ;
-- 优化字段名多,起别名
select 1.字段名A , 1.字段名B , 2.字段名A , ....
from <表1> 1
natural join <表2> 2;
- **内连接:**显示不同表中不同名或相同名字段都有数据的匹配信息(其中一条无数据则直接不显示)
-- 相对自然连接的多个同名列,使用using子句
select *
from 表1
inner join 表2 -- inner可以不写
using(指定表1和表2的 同名 列字段);
-- 优化不同表中不同名的字段,on子句
select *
from 表1
inner join 表2 -- inner可以不写
on 表1.字段名 = 表2.字段名;
- **外连接(outer可省略):**相对内连接的只显示都有数据时候匹配到的信息之外,其中有个表中无数据也可以进行匹配显示
-- 左外连接 left outer join 左边表的信息哪怕不匹配也可以显示匹配信息
select *
from 表1
left outer join 表2
on 表1.字段名 = 表2.字段名;
-- 右外连接 right outer join 右边表的信息哪怕不匹配也可以显示匹配信息
select *
from 表1
right outer join 表2
on 表1.字段名 = 表2.字段名;
-- 全外连接 在MySQL中不支持,但是在oracle中支持 (展示左右表全部不匹配信息)
select *
from 表1
full outer join 表2
on 表1.字段名 = 表2.字段名;
-- MySQL 中不支持全外连接的解决方案:union 并集
select *
from 表1
left outer join 表2
on 表1.字段名 = 表2.字段名;
union -- 并集(union去重,union all不去重),将左外连接结果和右外连接结果取并集
select *
from 表1
right outer join 表2
on 表1.字段名 = 表2.字段名;
- **自连接:**自己的某个字段和自己的另一个字段有关联
92语法
- **相当于99语法的交叉连接:**笛卡尔积查询,通过where筛选数据
select * -- 可用字段替代
from 表1 , 表2 ;
- 相当于99语法的自然连接
select * -- 可用字段替代
from 表1 , 表2
where 表1.字段 = 表2.字段 and 筛选条件;
-- where后面是连接条件,and后面是筛选条件
子查询
一条SQL语句中含有多个select,先执行子查询,在执行外查询。
- 单行子查询:查询结果只有一行
- 多行子查询:查询结果有多行(条件筛选可以使用in、any、=)
- 不相关子查询:子查询可以单独执行
- 相关子查询:子查询不能单独执行
事务
简介:
- 数据库中的事务(Transaction)是一种机制、一个操作序列,包含了一组数据库操作命令
- 事务把所有的命令作为一个整体一起向系统提交或撤销操作请求,即这一组数据库命令要么全部执行,要么全不执行
- 事务是一个不可分割的工作逻辑单元,用来维护数据库的完整性,保证一系列的MySQL操作
START TRANSACTION; #开启事务
BEGIN; #开启事务
COMMIT; #提交事务
ROLLBACK; #回滚事务
注意: 在回滚和提交之前,数据库中的数据都是操作的缓存中的数据,而不是数据库的真实数据
特性:
- 原子性(Atomicity):不可拆分
- 一致性(Consistency):状态一致(提交或回滚)
- 隔离性(Isolation):各个事务互不影响
- 持久性(Durability):数据持久化,不丢失
默认一个DML语句是一个事务
select @@tansaction_isolation ; #查看默认事务级别
select @@autocommit; #查询事务的默认提交方式
set @@autocommit = 数字; #设置默认事务的提交方式(0:手动提交,1:自动提交)
#注意: MySQL中事务是默认提交的,Oracle中事务是手动提交的
– 设置事务隔离级别 (当前会话)
set session transaction isolation level read uncommitted ;
set session transaction isolation level read committed ;
set session transaction isolation level read repeatable ;
set session transaction isolation level read serializable ;
并发问题:
- 脏读(Dirty read): 事务A读取到了事务B(可能回滚)未提交的数据。
- 幻读(Phantom read)锁表: 多次查询数据不一致(增加或删除数据)
- 不可重复读(Unrepeatable read)锁行: 多次查询数据不一致(修改数据)
事务隔离级别:
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 (READ UNCOMMITED) | 存在 | 存在 | 存在 |
读已提交 (READ COMMITED) | 不存在 | 存在 | 存在 |
重复读 (REPEATABLE READ) MySQL默认级别 | 不存在 | 不存在 | 存在 |
串行化 / 序列化 (SERIALIZABLE) | 不存在 | 不存在 | 不存在 |
视图(View)
概念:从单张或者多张基础数据表或其他视图中构建出来的虚拟表,只是一个查询语句。
-- 创建视图
create view 视图名称
as -- 关联表关键字
select 表中字段或者*
from 表1
join 表2
on 连接条件
where 筛选条案件 ; -- 可选项
-- 查看视图
select * from 视图名称
-- 操作视图 会影响到数据库数据
insert into 视图名称 .... ;
....
...
--
create or replace(替换,试图里有就替换,无就创建) view 视图名称
as -- 关联表关键字
select 表中字段或者*
from 表1
join 表2
on 连接条件
with check option(校验) ; --建议加上
注意: 视图可以基于视图创建。
存储过程(Stored Procedure)
类似方法的使用对数据库的查询进行了效率化,通过调用存储过程简化操作
- 无返回值的存储过程:
-- 定义一个无返回值的 存储过程
create procedure 存储过程名(in 参数名 参数类型)
begin -- 存储过程开始
if 参数 is null or 参数 = "" then -- 分支判断条件
select * from 表名; -- 满足条件执行的语句
else -- 另一条分支
select * from 表名 where 筛选条件 like concat('%',参数,'%'); -- 满足条件执行的语句
end if; -- if判断结束
end; -- 存储过程结束
-- 举例:
create procedure mypro1(in name varchar(10))
begin
if name is null or name = "" then
select * from emp;
else
select * from emp where ename like concat('%',name,'%');
end if;
end;
-- 删除存储过程
drop procedure 存储过程名 ;
-- 调用存储过程
call 存储过程名(参数);
- 有返回值的存储过程:
-- 定义一个有返回值的 存储过程
create procedure 存储过程名(in 参数名 参数类型,out 返回值名 返回值类型)
begin
if 参数 is null or 参数 = "" then
select * from 表名 ;
else
select * from 表名 where 筛选条件 like concat('%',参数,'%') ;
end if;
select found_rows() into 返回值名; -- 返回值执行语句
end;
-- 调用存储过程
call 存储过程名(参数, @返回值名) ; -- 注意这个只是存储过程,返回值另外查询
select @返回值名 ;
-- 删除存储过程
drop procedure 存储过程名 ;
索引
作用: 用来加快数据的访问速度
MySQL数据存储在磁盘,查询数据比较慢,一般卡在IO上面
提高效率:
- 减少IO次数
- 减少IO量(数据量)
局部性原理: 数据和程序都有聚集成群的倾向,同时之前被访问过的数据可能被再次查询,时间局部性,空间局部性。
磁盘预读: 内存跟磁盘在发生数据交换的时候,一般情况下有一个最小的逻辑单元,称之为页(datapage),页一般由操作系统决定多大,一般是4k或8k,而我们在进行数据交互的时候,可以取页的整数倍来进行读取。innodb存储引擎,每次读取数据,读取16k。
索引存储在磁盘,查询数据时,索引优先加载到内存
索引:
- Key:实际数据行中存储的值
- 文件地址
- offset:偏移量
OLAP: 联机分析处理(对海量历史数据进行分析,产生决策性的影响)-> 数据仓库(Hive)
OLTP: 联机事务处理(要求在很短时间内返回对应的结果)-> 关系型数据库(mysql、oracle、db2)
存储引擎: 不同数据在磁盘的不同组织形式
- Innodb(frm(表结构),idb(数据+索引)): 主要是B+树,支持自适应hash
- myisam(frm,MYD(Data),MYI(Index)): B+树
- memory: 使用hash索引
聚簇索引: 数据和索引放在一起(innodb只能有一个聚簇索引,但是可以有很多非聚簇索引,索引Key可以是主键,没有主键就是唯一键,没有唯一键,自动生成一个6字节的rowId,用户不可见)
非聚簇索引: 数据和索引不在一起(myisam)
回表: 从非聚簇索引跳转到聚簇索引中查找数据的过程。
索引覆盖: 当非聚簇索引的叶子节点中包含了查询需要的所有字段时,不需要回表。
索引下推: 把要检索的数据从Server层推到了存储引擎层。
主键: 一般是一个列
联合主键: 可以有多个列
索引: 一般是单个索引列
联合索引/组合索引: 可能有多个索引列
最左匹配: 最左前缀原则,又称最左匹配原则,是指在使用联合索引(复合索引)进行查询时,查询条件需要遵循索引中列的顺序,从左到右进行匹配。
假设有一张表,有id、name、age、gender四个字段,name、age是组合索引列,组合索引使用的时候必须先匹配name,然后匹配age
select * from table where name=? and age=? -- 走索引
select * from table where name=? -- 走索引
select * from table where age=? -- 不走索引
select * from table where and age=? name=? -- 走索引
-- mysql 内部有优化器,会调整对应的顺序
存储引擎: innodb、myisam、memory
存储引擎 | innodb | myisam |
---|---|---|
事务 | 支持 | 不支持 |
外键 | 支持 | 不支持 |
锁类型 | 支持表锁和行锁 | 支持表锁 |
索引 | 5.6之后支持全文索引 | 一直支持 |
索引类型 | 索引的叶子节点直接存放数据(聚簇索引) | 存放地址(非聚簇索引) |