Msql常用命令:
本地登录:
mysql -uroot -proot
退出mysql:
exit;
showdatabase;
use xxx;
show tables;
desc xxx;
SQL语言分类
-
DML(Data Manipulation Language)数据操纵语言
如:insert,delete,update,select(插入、删除、修改、检索)简称CRUD操新增Create、查询Retrieve、修改Update、删除Delete
DDL(Data Definition Language)数据库定义语言
如:create,drop,alter之类,主要是对表结构进行操作。
DCL(Data Control Language)数据库控制语言
如:grant、deny、revoke等,只有管理员才有相应的权限
DQL(Data Query Language)数据库查询语言
如: select 语法
注意:SQL不区分大小写
sql文件相关操作:
1.导入
先use一个数据库然后
source + 直接拖进去
2.查询表中所有数据
select* from + 表名
3.不看表的数据,只看表的结构
desc + 表名
4.查看数据库版本号+使用数据库
select version();
select database();
5.\c 用来终止输入
简单查询:
查询字段(列):
select 字段名1,字段名2 from 表名
强调:sql 以; 结尾,不区分大小写
select * from 表名 ;
效率低,可读性差,不建议开发写
给查询的列起别名:
select 字段名1,字段名2 as 别名 from 表名;(as)可以省略
注意只是将显示的查询结果显示,原表名字不会更改
如果别名里相加空格,就用单引号括起来
注意:所有数据库中,字符串统一用单引号
注:字段名 可以 + - x /
条件查询:
查询符合条件的数据:
select
字段
from
表名
where
条件
sal >=800 and sal<=3000;
sal between 800 and 3000;【】闭区间,包括两端的值
使用between and 时 必须左小右大
都有哪些条件:
= ,< ,> ,!= , <>, <=, >=,between and ,>= adn <=,
is null,is not null,
select empno,ename from emp where sal=800;
等号可以运用在字符串上
or:
select ename,job from emp where job=’manager‘ or job=’salesman‘;
and 和 or同时出现:and优先级高
select ename, job from emp where sal >2500 and deptno =10 or deptno =20;会按一下顺序执行:
select ename, job from emp where (sal >2500 and deptno =10) or deptno =20;
正确执行方式:
select ename, job from emp where sal>2500 and (deptno =20 or deptno=10);
in:相当于多个or,但不是多个区间,in后面跟的是具体的值
select empno,ename,job from emp where job in('manager' ,"salesman");
select empno,ename,job from emp where job='manager' or job="salesman";
like:模糊查询
%和_是特殊的符号,
%:任意多个字符,也可能是一个
_:任意一个字符
找出名字中含有o的:
select ename from emp where ename like '%o%';
以t结尾:
select ename from emp where ename like '%t';
以k开始:
select ename from emp where ename like 'k%';
第二个字母是a:
select ename from emp where ename like '_a%';
第三个字母是r:
select ename from emp where ename like '__r%';
找出含有_的名字:
select ename from emp where ename like '%\_%'
\转义,不然会全都查找出来
排序:
默认是升序:
select ename,sal from emp order by sal (asc);默认不写就是升序
降序:
select ename,sal from emp order by sal desc;(descend)
按照薪资升序排列,如果薪资一样,按照名字升序排列:
select ename,sal from emp order by sal,ename;
注:sal在前起主导,只有sal相等情况下才轮到ename
小综合:
select
ename,sal
from
emp
where
sal between 1250 and 3000
order by
sal desc;
数据处理函数,单行处理:
又叫单行处理函数:
特点:一个输入对应一个输出,
和单行处理函数相对的是多行处理函数:多个输入对应一个输出。
常见的单行处理函数:
lower:
select lower(ename) from emp;
upper:
select upper(ename) as ename from emp;
substr:
select substr(ename,1,3) as ename from emp;
起始下标从1开始
找出名字第一个字母是a的:
第一种:模糊查找:
select ename from emp where ename like 'a%';
第二种:
select ename from emp where substr(ename,1,1) ='a';
concat:字符串拼接
select concat(substr(ename,1,1),lower(substr(ename,2,length(ename))))
from emp;
length:上面那个
trim:
select * from emp where ename = trim(' king ');
去掉前后空格
round:
select round(123.23153,3) from emp;
四舍五入保留小数位
select round(1236.23153,-1) from emp; //1240
rand:
select rand() from emp;
select round(rand()*100) from emp;
null:
null参与运算最后结果都是null
select ename,(ifnull(comm,0)+sal)*12 from emp;
case..when...then...when...then...else...end
当工作岗位是manager,工资上调10%
当工作岗位是salesman时,工资上调50%
注意:不修改数据库,只是将查询结果显示显示出来
select ename,job, (case job when 'manager' then salx1.1 when 'salsman' then sal*1.5 else sal end ) as sal from emp;
分组函数,多行处理函数:
输入多行最终输出一行
5个:
count 计数
sum 求和
avg 平均值
max 最大
min 最小
注意:分组函数必须先进行分组才能用!!!
如果没有分组,整张表默认为一组
注:分组函数自动忽略null,不需要对null提前处理。
count(*)数全部的行
count(字段)统计该字段下不为null的元素总数
分组函数不能直接使用在where中??????????????????
所有的分组函数可以组合起来一起用
分组查询*****
先进行分组,再对每一组的信息操作
select
**...**
from
...
where
...
group by
....
having
...
order by
**...**
计算每个部门的工作和?计算每个工作岗位的平均薪资?最高薪资?
执行顺序
1.from2.where3.group by4.having5.select6.order by7.limit**
先经过where筛选,再分组,然后having过滤,再挑选,再排序
为什么分组函数不能使用在where后面?
以为分组函数在使用的时候要先分组,where执行时还没分组,所以where后面不能出现分组函数
重点结论:
在一条select语句中,如果有group by 语句,select后面只能跟:参加分组的字段,以及分组的函数,其他一律不能跟
找出每个部门的最高薪资:
这样写没有意义,select后面加加ename无意义。
找出每个部门不同岗位的最高薪资:
*having:
先将》3000的都找出来然后再分组
综合案例:
找出每个岗位的平均薪资,要求显示平均薪资》1500的,除manager之外
要求按照平均薪资升序排列。
select avg(sal),job from emp where job != 'manager'group by job having avg(sal)>1500 order by avg(sal) ;
distinct
distinct 放在字段前面,联合起来判断
统计工作岗位的数量,有多少工种:
连接查询
跨表查询,多张表连一起查询
分类:
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接
右外连接
全连接
当两张表进行连接查询时,没有任何条件的限制,会发生上面现象?
案例:
select ename, dname from emp,dept where emp.deptno=dept.deptno order by dname;
思考:最终查询结果为14条但是匹配次数减少了吗?没有!还是14*4次,只是四选一,上面14条记录,一一跟下面的表的四条记录进行匹配。
这叫做笛卡尔积现象!!!!!
select emp.ename, dept.dname from emp,dept where emp.deptno=dept.deptno order by dname;
下面这张情况,匹配次数少了,给表起别名:
内连接之等值连接
查询每个员工所在的部门名称,显示员工名和部门名:
SQL92:缺点,表连接的条件在where里,结构不清晰
select
e.ename,d.dname
from
emp e,dept d
where
e.deptno=d.deptno;
SQL99:结构更清晰一点
select
e.ename,d.dname
from
emp e,
(inner)join
dept d
on
e.deptno=d.deptno;
优点,连接独立,可以继续添加where筛选
找出每个员工的薪资等级,要求显示员工名,薪资,薪资等级:
内连接之自连接
自己跟自己连接
查询员工的上级领导,要求显示员工名和对应的领导名:
一张表看成两张表
外连接:左右连接
select
e.ename,d.dname ,e.deptno ,d.deptno
from
emp e
right (outer) join
dept d
on
e.deptno=d.deptno;
right 表示把右边表的数据全部显示出来,捎带着查询左边的表
两张表产生了主次关系,右边的是主表
左右连接是想通的
外连接的查询结果条数一定>=内连接查询结果条数
案例:查询每个员工的上级领导,要求显示所有员工的名字和领导名
select e.ename as 'emp' , e1.ename as 'leader' from emp as e left join emp as e1 on e.mgr=e1.empno;
多张表的连接
select ..from a
join b on a,b的连接条件
join c on a,c的条件
join d on a,d的条件
案例:找出每个员工的部门名称,和薪资等级,(上级领导),显示员工名,薪资,部门名,薪资等级
慢慢写就行了 一点也不难
子查询
select语句中 嵌套select
子查询都可以出现在哪里?
select
...(select )...
from
....(select).....
where
.....(select)...
where子查询:
案例:找出比最低工资高的员工姓名和工资
1.找出最小的
2.找出》最小的
select ename , sal from emp where sal >(select min(sal) from emp);
from子查询
技巧:from后面的子查询可以将查询结果当作一张临时表来看待
案例:找出每个岗位的平均工资的薪资等级
1.:找出每个岗位的平均工资
2.把上面的表当做一个临时表 t,与下面的s表进行表连接
-
要给avg(sal)起别名
select
t.*,s.grade
from
(select job,avg(sal) as avgsal from emp group by job) as t
join
salgrade s
on
t.avgsal between s.losal and s.hisal
或者颠倒一下
select s.grade , t.avgsal from salgrade s
join
( select job,avg(sal) as avgsal from emp group by job) as t
on
t.avgsal between s.losal and s.hisal
union合并查询
查询工作岗位是manager 和 salesman的员工
1.select ename , job from emp where job='manager' or job='salesman';
2.select ename , job from emp where job in ('manager','salesman');
3.select ename , job from emp where job='manager'
union
select ename , job from emp where job='salesman';
注意:
union效率会高一点,对于表连接来说,每连接一次新表,则匹配的次数需要满足笛卡尔积,成倍的翻。。。
但是union可以减少匹配的次数,在减少匹配的次数下,还可以完成两个结果集的拼接。
a连接b连接c
a10条记录
b10条记录
c10条记录
匹配次数:1000
a连接b:100次
a连接c:100次
使用union的话,100+100=200次 等于两个查询结果拼装在一起
把乘法运算变成了加法运算
union使用的注意事项:
上下的列数要相同,列和列的数据类型也要一样,不然没法合并
limit:
将查询结果一部分显示出,通常使用在分页当中。
取前五条记录,limit:5 。limit是在order by之后执行
完整用法:limit startIndex , length; 起始下标 和 长度
不写,默认startIndex为0
取3到5名:limit 2,3 ;
分页,每页显示3条记录
第1页:limit 0,3
第2页:limit 3,3
第3页:limit 6,3
第4页:limit 9,3
每页显示pagesize条记录
第1页:limit (pagenumber-1)*pagesize,pagesize
第2页:limit (pagenumber-1)*pagesize,,pagesize
第3页:limit (pagenumber-1)*pagesize,,pagesize
第4页:limit (pagenumber-1)*pagesize,,pagesize
表的创建(DDL)
DDL: create drop alter
create table 表名(
字段名1 数据类型,
字段名2 数据类型,
字段名3 数据类型
);
表名:建议以t_或者tbl__ 开始
表名和字段名都数据标识符:要见名只意
数据类型:
varchar
可变长度字符串,会动态分配空间,比较智能,节省空间
最长255
优点:节省空间,但需要动态分配空间,速度快
char
定长字符串,不管实际数据长度多少,都会分配固定长度
最长255
缺点:使用不恰当时,会导致空间的浪费
优点:不需要动态分配空间,速度快
如何选择?性别->char,固定长度的选择char
int
就是int 最长11
bigint
等同于long
float
单精度浮点
double
双精度浮点
date
短日期类型
datetime
长日期类型
clob
字符大对象
最多可以存储4g的字符串,如存储一篇文章,存储一个简介,一个说明
character large Object
blob
二进制大对象
binary large object
专门用来存储图片、声音、视频流等媒体数据
让blob上插入视频等文件要io流
删表:
drop table if exists t_table;
插入数据insert(DML)
insert into 表名(字段名1,字段名2,字段名3.。。)
values(值1,值2,值3)[这边可以插入多条记录];
注意:字段名和值要一一对应。
insert into t_student (no,name,age,email) values (1,'zhangsan',18,'90315@qq.com');
格式化数字format
select ename,format(sal,'$999,999') as sal from emp;
str_to_date:将字符串varchar类型转换成date类型
date_format:将date类型转化为具有一定格式的varchar类型
str_to_date ('字符串日期',‘日期格式’)
str_to_date('01-12-1999','%d-%m-%Y')
mysql的日期格式
%Y 年
%m 月
%d 日
%h 时
%i 分
%s 秒
如果提供日期字符串是这个格式,可以省略str_to_date,自动类型转换
‘%Y-%m-%d’
date和datetime
mysql短日期‘%Y-%m-%d’
mysql长日期‘%Y-%m-%d %h:%i:%s’
修改update(DML)
update 表名 set 字段名1=值1 ,字段名2=值2,字段名3=值3.。。where 条件;
注意:没有条件限制会导致所有数据全部更新
删除delete(DML)
delete from 表名 where 条件;
注意:没有条件
delete删除支持回滚 rollback回复,缺点是删除效率比较低
truncate
物理删除,不支持回滚,优点,快
增删改查
insert delete update select
快速创建表,表的复制
create table emp2 as select * from emp;
create table my_table as select ename,empno from emp where job='manager';
等于把查询结果当做一个表新建
将查询结果插入到一个表中?
insert into dept_bak select * from dept;
约束*****
constraint,创建表时给表中字段加上一些约束,保证数据的完整性,有效性。
约束的作用就是为了保证:表中的数据有效!!
约束包括:
非空约束 not null
唯一性约束 unique
主键约束 primary key
外键约束 foreign key
检查约束 check
非空约束:not null
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) not null,
);
insert into t_vip(id,name) values(1,'zhangsan');
insert into t_vip(id,name) values(2,'lisi');
唯一性约束:unique
不能重复,但是能都为null,null可以重复
联合唯一性:一个人可以有多个邮箱,一个邮箱只能有一个主人
drop table if exists t_vip;
create table t_vip(id int,
name varchar(255) ,
email varchar(255),
unique(name,email)
);
insert into t_vip(id,name) values('zhangsan','zhangsan@qq.com');
insert into t_vip(id,name) values(zhangsan','zhangsan@163.com');
表级约束
给多个字段联合起来添加某一个约束
unique和not null联合
create table t_vip(id int,
name varchar(255) notnull unique
);
主键约束:primary key(pk)
相关术语:
主键约束:一种约束
主键字段:该字段上添加了主键约束,这样的额字段叫主键字段
主键值:主键字段中的值
主键值存在的意义就是这一行记录的身份证号,不建议使用复合主键
create table t_vip(id int,
age int primary key
);
一张表主键约束只能添加一个
主键值建议使用:
int bigint char 不建议使用 varchar做主键,主键值一般都是数字,定长的
主键出了单一,复合主键,还能如此分类:
自然主键:主键值是个自然数
业务主键:主键值跟业务关联,如;拿银行卡号当主键
实际开发,自然主键多,因为主键只意做到不重复就行 不需要有意义
业务主键不好,业务发生变动时可能会影响到主键值,所以业务主键不建议使用,尽量使用自然主键。
drop table if exists t_vip;
create table t_vip(id int primary key auto_increment, //表示自增,从1开始自增
name varchar(255) ); insert into t_vip(name) values('zhangsan'); insert into t_vip(name) values('zhangsan'); insert into t_vip(name) values('zhangsan'); insert into t_vip(name) values('zhangsan');
+----+----------+ | id | name | +----+----------+ | 1 | zhangsan | | 2 | zhangsan | | 3 | zhangsan | | 4 | zhangsan | +----+----------+
会自动生成序号
外键约束(foreign key, FK)*****
业务背景: 请设计数据库表,来描述“班级和学生”的信息?
第一种方案:班级和学生存储在一张表中??? t_student no(pk) name classno classname------------------------------------------------------ 1 jack 100 高三1班 2 lucy 100 高三1班 3 lilei 100 高三1班 4 hanmeimei 100 高三1班 5 zhangsan 101 高三2班 6 lisi 101 高三2班 7 wangwu 101 高三2班 8 zhaoliu 101 高三2班 分析以上方案的缺点: 数据冗余,空间浪费!!!! 这个设计是比较失败的!
``第二种方案:班级一张表、学生一张表?? ``t_class 班级表 ``classno(pk) classname ``------------------------------------------------------ ``100 北京市大兴区亦庄镇第二中学高三1班 ``101 北京市大兴区亦庄镇第二中学高三1班 ``t_student 学生表 ``no(pk) name cno(FK引用t_class这张表的classno) ``------------------------------------------------------ ``1 jack 100 ``2 lucy 100 ``3 lilei 100 ``4 hanmeimei 100 ``5 zhangsan 101 ``6 lisi 101 ``7 wangwu 101 ``8 zhaoliu 101
保证只能出现100 和101 加外键约束
当cno字段没有任何约束的时候,可能会导致数据无效。可能出现一个102,但是102班级不存在。 所以为了保证cno字段中的值都是100和101,需要给cno字段添加外键约束。 那么:cno字段就是外键字段。cno字段中的每一个值都是外键值。
注意: t_class是父表 t_student是子表
删除表的顺序?
先删子,再删父。
创建表的顺序?
先创建父,再创建子。
删除数据的顺序?
先删子,再删父。
插入数据的顺序?
先插入父,再插入子。
drop table if exists t_student;
drop table if exists t_class;
create table t_class(
classno int primary key,
classname varchar(255)
);
create table t_student(
no int primary key auto_increment,
name varchar(255),
cno int,
foreign key(con) references t_class (classno)
);
思考:子表中的外键引用的父表中的某个字段,被引用的这个字段必须是主键吗? 不一定是主键,但至少具有unique约束。不能重复*
测试:外键可以为NULL吗?
外键值可以为NULL。
事务******
事务就是一个完整的业务逻辑
什么是一个完整的业务逻辑?
A向b转10k,A-10k(update),b+10k(upda)就是个完整的业务逻辑
以上的操作是一个最小的工作单元,同时成功或者失败,不可再分
两个update要同时成功或者失败
只有DML语句才有事务:
insert delete update
因为只有以上操作对数据库中数据进行增删改,只要操作一旦涉及到数据增删改,就一定要考虑安全问题。数据安全第一位!!!!
假设所有业务只要一条DML语句完成,还有必要存在事务机制吗?
正是因为某件事务需要多个DML语句联合起来完成,如果任何一件复杂的事都能一条DML语句完成,事务就没有存在的价值了。
说道本质上,一个事务就是多条DML语句同时成功或者同时失败。
事务是怎么做到多条DML语句同时成功与失败呢?
InnoDB存储引擎:提供一组用来记录事务性活动的日志文件
事务开启了:
insert
insert
delete
update
事务结束了:
事务执行过程中每一条DML都会记录到“事务性活动日志文件中”
事务执行过程中,可以提交事务,也可以回滚事务。
提交事务?
清空事务性活动的日志文件,将数据全部彻底持久化到数据库中
提交事务标志着,事务的结束。并且是一种全部成功的结束。
回滚事务?
将之前所有的DML操作全部撤销,并且清空事务性活动的日志文件
回滚事务标志着事务的结束,并且是一种全部失败的结束
怎么提交,回滚事务?
提交事务:commit;
回滚事务:rollback;(只能回滚到上一次的提交点,所以mysql回滚不了)
事务对应的英语单词是:transaction
测试一下。mysql中默认的事务行为:
mysql默认情况下自动提交事务,每执行一条DML语句就提交一次
其实自动提交是不符合实际开发情况的,可以先用 start transaction,再用 commit提交
怎么关闭自动提交机制?
先执行:start transaction;
事务的四个特性
A:原子性
说明事务是最小的工作单元不可再分
C:一致性
所有事务要求,在同一事务当中,所有事务必须同时成功,或者同时失败,以保证数据的一致性。
I: 隔离线
A事务和B事务之间有一定的隔离,教室A与教室B之间有一道墙,之间有隔性。多线程访问同一张表一样。
D:持久性
事务最终结束的一个保障,事务提交就相当于将没有保存到硬盘中的数据保存在硬盘上
研究一下事务的隔离性
A教室和B教室中间有一道墙,可以很厚也可以很薄,就是事务的隔离级别。
隔离级别越高,表示这道墙越厚,
事务和事务之间的隔离级别有哪些?
-
读未提交: read uncommitted(最低隔离级别,没有提交就读到了)
事务A可以读取事务B未提交的数据
这种隔离级别存在的问题就是脏读现象(Dirty Read)
我们称读到了脏数据
这种隔离级别一般都是理论上的,大多数数据库隔离界别都是二挡起步
-
读已提交: read committed(提交之后才能读到)
事务A只能读取到事务B提交之后的数据,这种隔离级别解决了脏读的现象。
这种隔离级别存在什么问题?
不可重复读取数据:在事务开启之后,第一次读到的数据是3条,由于当前B事务还没结束。可能第二次再读取的时候读到的事务是4条。称为不可重复读取。
这种隔离级别是比较真实的数据,每次读到的数据都比较真实,Oracle默认的隔离级别。
-
可重复读: repeatable read(提交之后也读不到)
事务A开启之后,不管是多久,每一次在A中读取到的数据都是一致的,即使B修改,提交了,A读取到的数据还是没改变。
解决了不可重复读问题。
存在的问题?
可能会出现幻影读。
每次读取到的数据都是幻象,不够真实。
早上九点开启了事务,只要事务不结束,到晚上九点,读取到的事务还是那样,读到的是假象,不够绝对的真实。
mysql默认的隔离级别!!!!!!!!!!!
-
序列化/串行化: serializable(最高隔离级别)
效率最低,解决了所有问题,这种隔离级别表示事务排队,不能并发
类似于synchronized
每次读取到的数据都是最真实的,但效率是最低的
验证各种隔离界别
查看隔离级别:select @@tx_isolation;
read uncommitted
read committed
repeatable read
serializable
索引
是在数据库表的字段上加的,为了提高表的查询效率
一张表的一个字段可以添加一个索引,多个字段联合起来也可以添加索引。
一张表没有添加索引的话,会一个一个找目标,全表扫描。
第二种方式是:索引检索。
注意:
在实际中,汉语字典前面的目录是排序的,按照abcdef排序,
因为只有排序了才会有区间查找这一说法。
缩小扫描范围其实就是扫描某个区间罢了,在mysql数据库中,索引也是需要排序的,并且索引的排序和TreeSet数据结构相同,底层是个自平衡的二叉树。在mysql种,索引是个B-Tree数据结构。遵循左小右大原则存放,采用中序遍历方式遍历数据。
索引的实现原理
t_user
id(PK) name
100 zhangsan
123 lisi
99 wangwu
88 zhaoli
101 jack
55 lucy
130 tom
*提醒1:在任何数据库中,主键会自动添加索引**
在mysql中,字段有unique也会自动创建索引
提醒2:在任何数据库中,任何一张表的任何一张记录在硬盘上都有一个物理存储编号
提醒3:在mysql中索引是一个单独的对象,不同的存储引擎以不同的形式存在,在MYISAM存储引擎中,索引存储在一个MYI文件中,在INODB中,索引存储在table space中,MEMORY存储引擎存储在内存中。不管在那个存储引擎,索引在mysql中都是一个自平衡二叉树B-TREE

注意:MySQL中主键和unique字段都会添加索引
什么条件下,会考虑添加索引?
-
数据量庞大,需要测试,每一个硬件环境不同。
-
经常出现在where后面的字段,总是被扫描
-
该字段很少的DML(insert delete update)操作,因为DML之后索引需要重新排序
建议不要随意添加索引,因为索引也是需要维护的,太多的话,反而会降低系统的性能,建议通过主键查询,建议通过unique约束的字段进行查询。效率也比较高
索引的创建和删除
create index emp_ename_index on emp(ename);
drop index emp_ename_index on emp;
查看一个sql语句是否使用了索引进行检索
explain select * from emp where ename='king';
加一个explain
索引的失效
1.模糊查询以%开头
select * from emp where ename like '%T'
这样即使ename添加了索引也不会走索引
原因是以%开头,所以尽量避免模糊查询时以%开始。
这是一种优化的手段
2.使用or时会失效,
如果使用or,两边的条件字段都要有索引才会走索引,如果一边没有,那么另一边的索引也会失效。
所以少用or 也是一种优化手段,用union就行了
3.复合索引
使用复合索引的时候,没有使用左侧的列进行查找,索引失效。
复合索引:多个字段联合起来添加一个索引叫复合索引
create index emp_job_sal_index on emp(job,sal);
举例:
explain select * from emp where job='salesman';
用了索引
下面没用索引
explain select * from emp where sal=800;
4.参与运算
where中索引列参加了运算,索引失效。
create index sal_index on emp(sal);
explain select * from emp where sal+1=800;(失效了,不走索引)
5.使用函数
where中索引使用了函数
explain select * from emp where lower(ename)='smith';
6。。。
7.。。。
索引是各种数据库进行优化的重要手段
优化的时候优先考虑的因素就是索引,索引在数据库种分了很多类:
单一索引:一个字段
复合索引:两个或更多
主键索引:主键加
唯一性索引:unique上加
。。。。。
注意:唯一性比较弱的字段上添加索引用处不大,unique上重复性比较大,索引几乎不起索引,越唯一效率越高。
试图
view:站在不同的角度去看待同一份数据
创建视图对象
create view emp_view1 as select * from emp;
删除试图对象
drop view dept2_view;
注意:只有dql语句才能以view形式创建
create view dept2_view as 这边加上的语句必须是DQL语句
试图对象能干什么
可以面向视图对象进行增删改查
对试图对象的增删改查会导致原表被操作
update dept2_view set sal=2000 where deptno=30;
原表也会改变
试图在开发中有什么用
方便,简化开发,利于维护
create view view_tem as(这边只能是查询语句)
select e.ename ,d.dname
from emp e join dept d on e.deptno=d
一条sql语句很复杂,想直接对其进行操作。就把这条复杂的sql语句以视图对象的形式新建,在需要编写这条sql语句的位置直接使用试图对象,大大简化开发,便于后期维护,只需要修改视图对象所映射的sql语句。
这条语句 我对view_tem 操作时 把 dept表跟emp表都给改了。我日
以后面向视图开放时跟表一样,一样增删改查。视图对象也是存储在硬盘上的不会消失。
DBA常用命令了解一下
重点掌握数据的导入导出
导出:
把数据库导出,到d盘sql文件
mysqldump whx2021 > D:\bjpowernode.sql -uroot -proot
导出表格:
mysqldump whx2021 emp > D:\bjpowernode.sql -uroot -proot
导入:
这个得先创建一个数据库,use数据库,再导入
MariaDB [whx2021]> source C:\Users\90315\Desktop\cs笔记\bjpowernode.sql
(这边不要有英文)
数据库设计三范式
数据库表的设计依据。
1.要求任何一张表必须有主键,每一个字段原子性不可分
2.要求所有非主键字段完全依赖主键,不要产生部分依赖。
第二范式是建立在第一范式之上。
3.建立在第二范式的基础之上,要求所有非主键直接依赖主键,不要产生传递依赖。
声明:面试经常问,一定要熟记在心。
设计数据库表的时候按照以上范式可以避免数据冗余,空间浪费。
第一范式:
最核心最重要的范式,所有表的设计必须满足,
必须有主键,所有主键原子性不能再分。
学生编号 学生姓名 联系方式 ``------------------------------------------ ``1001 张三 zs@gmail.com,1359999999 ``1002 李四 ls@gmail.com,13699999999 ``1001 王五 ww@163.net,13488888888
1.没有主键
2.联系方式还能再分邮箱,电话
第二范式
要求所有非主键字段完全依赖主键,不要产生部分依赖。
学生编号 学生姓名 教师编号 教师姓名 ---------------------------------------------------- 1001 张三 001 王老师 1002 李四 002 赵老师 1003 王五 001 王老师 1001 张三 002 赵老师
``分析以上的表是否满足第一范式? ``不满足第一范式。 ``怎么满足第一范式呢?修改
学生编号+教师编号(pk) 学生姓名 教师姓名 ---------------------------------------------------- 1001 001 张三 王老师 1002 002 李四 赵老师 1003 001 王五 王老师 1001 002 张三 赵老师
学生编号 教师编号,两个字段联合做主键,复合主键(PK: 学生编号+教师编号) 经过修改之后,以上的表满足了第一范式。但是满足第二范式吗? 不满足,“张三”依赖1001,“王老师”依赖001,显然产生了部分依赖。 产生部分依赖有什么缺点? 数据冗余了。空间浪费了。“张三”重复了,“王老师”重复了。
``使用三张表来表示多对多的关系!!!! ``学生表 ``学生编号(pk) 学生名字 ``------------------------------------ ``1001 张三 ``1002 李四 ``1003 王五 ``教师表 ``教师编号(pk) 教师姓名 ``-------------------------------------- ``001 王老师 ``002 赵老师
学生教师关系表 id(pk) 学生编号(fk) 教师编号(fk) -------------------------------------------------- 1 1001 001 2 1002 002 3 1003 001 4 1001 002
``背口诀: ``多对多怎么设计? ``多对多,三张表,关系表两个外键!!!!!!!!!!!!!!!
第三范式
建立在第二范式的基础之上,要求所有非主键直接依赖主键,不要产生传递依赖。
``学生编号(PK) 学生姓名 班级编号 班级名称 ``--------------------------------------------------------- ``1001 张三 01 一年一班 ``1002 李四 02 一年二班 ``1003 王五 03 一年三班 ``1004 赵六 03 一年三班 ``以上表的设计是描述:班级和学生的关系。很显然是1对多关系! ``一个教室中有多个学生。
``分析以上表是否满足第一范式? ``满足第一范式,有主键。 ``分析以上表是否满足第二范式? ``满足第二范式,因为主键不是复合主键,没有产生部分依赖。主键是单一主键。 ``分析以上表是否满足第三范式? ``第三范式要求:不要产生传递依赖! ``一年一班依赖01,01依赖1001,产生了传递依赖。 ``不符合第三范式的要求。产生了数据的冗余。 ``那么应该怎么设计一对多呢?
班级表:一 ``班级编号(pk) 班级名称 ``---------------------------------------- ``01 一年一班 ``02 一年二班 ``03 一年三班
``学生表:多
``学生编号(PK) 学生姓名 班级编号(fk) ``------------------------------------------- ``1001 张三 01 ``1002 李四 02 ``1003 王五 03 ``1004 赵六 03 ``背口诀: ``一对多,两张表,多的表加外键!!!!!!!!!!!!
总结表的设计:
一对多:
一对多两张表,多的表加外键
多对多:
多对多,三张表,关系表连个外键
一对一:
实际开发中可能存在一张表字段太多太庞大,要拆分,一对一怎么设计?
没有拆分表之前:一张表


*#utf8字符集
CREATE DATABASE hsp02 CHARACTER SET utf8;hsp02 #校对规则 utf8_bin 区分大小写,默认的utf8_general_ci不区分大小写 CREATE DATABASE hsp03 CHARACTER SET utf8 COLLATE utf8_bin;
本文详细介绍了MySQL数据库的常用命令,包括SQL语言分类、DDL、DCL、DQL和DML,以及SQL文件操作。讲解了简单查询、条件查询、排序、数据处理函数、分组查询、连接查询、子查询、事务、索引、视图和数据库设计三范式等关键概念,并提供了丰富的示例。此外,还探讨了事务的隔离性和索引的失效场景。
365

被折叠的 条评论
为什么被折叠?



