数据库常用操作
exit; //退出
show databases;//展示数据库列表
use ???;//使用某个数据库
create database ???;//创建某个数据库
show tables;//展示该数据库中有哪些表
select database();//查看当前使用的是哪个数据库
source D:\course\03-MySQL\document\bjpowernode.sql;
//向mysql中导入sql文件
select * from ???;//从???表中查询所有数据
desc ???;//查询表的结构:describe也可以
select xxx from ???;//查询表中一列的信息,在sql语言中是不区分大小写的
select xxx,yyy from ???;//查询表中的多列信息
查询所有字段一般采用select a,b,… from ???的形式
select xxx,yyy as ttt from ???;//给查询的列起别名,是把yyy变为了ttt,原来的表名不会变化,其中as关键字是可以省略的,别名如果是中文需要使用' '括起来'
select xxx,yyy as'tt t' from ???;//针对别名要使用空格的情况
select xxx,yyy*12 from ???;//字段可以使用数学表达式
select语句永远不会进行修改操作
条件查询
语法格式:
select
字段1,字段2,字段3....
from
表名
where
条件;
select xxx,yyy,zzz from ??? where yyy>=800;//查询yyy>=800情况下的数据
在数据库当中null不能使用等号进行衡量。需要使用is null因为数据库中的null代表什么也没有,它不是一个值,所以不能使用等号衡量。
select xxx,yyy from ??? where yyy between 2000 and 3000;//查找数据库中yyy值在2000-3000情况下的数据
select xxx,yyy from ??? where yyy is not null;//查找yyy非空的数据
select xxx,yyy,zzz from ??? where yyy=!!! and zzz=!!!;//使用and查询符合两个条件的数据
select xxx,yyy,zzz from ??? where yyy=!!! or zzz=!!!;//使用or查询符合两个条件中任意一个的数据
select xxx,yyy from ??? where yyy in(2000,3000,...);//相当于多个or,查找表中符合in中条件的所有数据
and优先级比or高。语句会先执行and,然后执行or。
not可以取非,主要用在is或in中
like
称为模糊查询,支持%或下划线匹配
%匹配任意多个字符
下划线:任意一个字符。
(%是一个特殊的符号,_ 也是一个特殊符号)
找出名字以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 name from t_student where name like '%\_%'; // \转义字符。
排序
select
xxx,yyy
from
???
order by
yyy;
//默认是升序
指定降序:
select
xxx,yyy
from
???
order by
yyy desc;
指定升序?
select
xxx,yyy
from
???
order by
yyy asc;
//按照多个字段排序,先排yyy,只有yyy相同才用xxx
select
xxx,yyy
from
???
order by
yyy asc,xxx asc;
综合案例
找出工资在1250到3000之间的员工信息,要求按照薪资降序排列。
select xxx,yyy as zzz from ??? where yyy between 1250 and 3000 order by sal desc;
关键字顺序不能变:
select
...
from
...
where
...
order by
...
以上语句的执行顺序必须掌握:
第一步:from
第二步:where
第三步:select
第四步:order by(排序总是在最后执行!)
数据处理函数(单行处理函数)
单行处理函数的特点:一个输入对应一个输出。
和单行处理函数相对的是:多行处理函数。(多行处理函数特点:多个输入,对应1个输出!)
select substr(xxx,?,?) as xxx from ???;//取子串
select concat(xxx,yyy) from ???;//对字符串进行拼接
select length(xxx) from ???;//取长度
//case..when..then..when..then..else..end
当员工的工作岗位是MANAGER的时候,工资上调10%,当工作岗位是SALESMAN的时候,工资上调50%,其它正常。
select ename,job,sal as oldsal,(case job when 'MANAGER' then sal*1.1 when 'SALESMAN' then sal*1.5 else end) as newsal from emp;
分组函数(多行处理函数)
5个:
count 计数
sum 求和
avg 平均值
max 最大值
min 最小值
注意:
分组函数在使用的时候必须先进行分组,然后才能用。
如果你没有对数据进行分组,整张表默认为一组。
分组函数在使用的时候需要注意哪些?
第一点:分组函数自动忽略NULL,你不需要提前对NULL进行处理。
第二点:分组函数不能够直接使用在where子句中。
第三点:所有的分组函数可以组合起来一起用。
什么是分组查询?
在实际的应用中,可能有这样的需求,需要先进行分组,然后对每一组的数据进行操作。
这个时候我们需要使用分组查询,怎么进行分组查询呢?
select
...
from
...
group by
...
计算每个部门的工资和?
计算每个工作岗位的平均薪资?
找出每个工作岗位的最高薪资?
....
将之前的关键字全部组合在一起,来看一下他们的执行顺序?
select
...
from
...
where
...
group by
...
order by
...
以上关键字的顺序不能颠倒,需要记忆。
执行顺序是什么?
1. from
2. where
3. group by
4. having
5. select
6. order by
从某张表中查询数据,
先经过where条件筛选出有价值的数据。
对这些有价值的数据进行分组。
分组之后可以使用having继续筛选。
select查询出来。
最后排序输出!
重点结论:
在一条select语句当中,如果有group by语句的话,
select后面只能跟:参加分组的字段,以及分组函数。
其它的一律不能跟。
使用having可以对分完组之后的数据进一步过滤。
having不能单独使用,having不能代替where,having必须和group by联合使用。
找出每个部门最高薪资,要求显示最高薪资大于3000的?
select deptno,max(sal) from emp group by deptno having max(sal) > 3000;
或
select deptno,max(sal) from emp where sal>3000 group by deptno;
常用操作2
select distinct job from emp;//去除重复记录,当distinct出现在两个字段之前,表示两个字段联合起来去重
连接查询
什么是连接查询?
从一张表中单独查询,称为单表查询。
emp表和dept表联合起来查询数据,从emp表中取员工名字,从dept表中取部门名字。
这种跨表查询,多张表联合起来查询数据,被称为连接查询。
根据表连接的方式分类:
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接(左连接)
右外连接(右连接)
当两张表进行连接查询,没有任何条件限制的时候,最终查询结果条数,是两张表条数的乘积,这种现象被称为:笛卡尔积现象。(笛卡尔发现的,这是一个数学现象。)
select !.xx,!!.yy from ??? !,### !! where !.x=!!.y;
内连接之等值连接。
案例:查询每个员工所在部门名称,显示员工名和部门名?
select e.ename,d.dname from emp e,dept d where e.deptno = d.deptno;(92语法)
select e.ename,d.dname from emp e inner join dept d on e.deptno=d.deptno;(99语法)
sql99优点:表连接的条件是独立的,连接之后,如果还需要进一步筛选,再往后继续添加where
SQL99语法:
select
...
from
a
join
b
on
a和b的连接条件
where
筛选条件
内连接之非等值连接。
案例:找出每个员工的薪资等级,要求显示员工名、薪资、薪资等级?
select e.ename,s.grade from emp e inner join salgrade s on e.sal between s.losal and s.hisal;
内连接之自连接(把一张表看成两张表)
案例:查询员工的上级领导,要求显示员工名和对应的领导名?
select a.ename as '员工名',b.ename as '领导名' from emp as a inner join emp as b on a.mgr = b.empno;
外连接:
右外连接(右连接)right代表什么:表示将join关键字右边的这张表看成主表,主要是为了将
这张表的数据全部查询出来,捎带着关联查询左边的表。
左外连接同理
外连接的查询结果条数一定是 >= 内连接的查询结果条数?
正确。
案例:查询每个员工的上级领导,要求显示所有员工的名字和领导名?
select a.ename as '员工名',b.ename as '领导名' from emp a left join emp b on a.mgr = b.empno;
三张表,四张表怎么连接?
语法:
select
...
from
a
join
b
on
a和b的连接条件
join
c
on
a和c的连接条件
right join
d
on
a和d的连接条件
案例:找出每个员工的部门名称以及工资等级,要求显示员工名、部门名、薪资、薪资等级?
select e.ename,e.sal,d.dname,d.grade from emp e join dept d on e.deptno = d.deptno join salgrade s on e.sal between s.losal and s.hisal;
案例:找出每个员工的部门名称以及工资等级,还有上级领导,要求显示员工名、领导名、部门名、薪资、薪资等级?
select e.ename,e.sal,d.dname,s.grade,l.ename from emp e join dept d on e.deptno = d.deptno join salgrade s on e.sal between s.losal and s.hisal left join emp l on e.mgr = l.empno;
子查询
什么是子查询?
select语句中嵌套select语句,被嵌套的select语句称为子查询。
子查询都可以出现在哪里呢?
select
..(select).
from
..(select).
where
..(select).
union合并查询结果集
案例:查询工作岗位是MANAGER和SALESMAN的员工?
select ename,job from emp where job = 'MANAGER'
union
select ename,job from emp where job = 'SALESMAN';
union的效率要高一些。对于表连接来说,每连接一次新表,
则匹配的次数满足笛卡尔积,成倍的翻。。。
但是union可以减少匹配的次数。在减少匹配次数的情况下,
还可以完成两个结果集的拼接。
要求两个结果集的列数相同。
limit
limit作用:将查询结果集的一部分取出来。通常使用在分页查询当中。
百度默认:一页显示10条记录。
完整用法:limit startIndex, length
startIndex是起始下标,length是长度。
起始下标从0开始。
注意:mysql当中limit在order by之后执行!!!!!!
案例:按照薪资降序,取出排名在前5名的员工?
select ename,sal from emp order by sal desc limit 0,5;
DQL语句总结
关于DQL语句的大总结:
select
...
from
...
where
...
group by
...
having
...
order by
...
limit
...
执行顺序?
1.from
2.where
3.group by
4.having
5.select
6.order by
7.limit..
建表
DDL语句
create table 表名(字段名1 数据类型, 字段名2 数据类型, 字段名3 数据类型);
mysql中的数据类型
varchar(最长255)(可变,慢,不浪费资源)
可变长度的字符串
比较智能,节省空间。
会根据实际的数据长度动态分配空间。
优点:节省空间
缺点:需要动态分配空间,速度慢。
char(最长255)(不可变,快,浪费资源)
定长字符串
不管实际的数据长度是多少。
分配固定长度的空间去存储数据。
使用不恰当的时候,可能会导致空间的浪费。
优点:不需要动态分配空间,速度快。
缺点:使用不当可能会导致空间的浪费。
int(最长11)
数字中的整数型。等同于java的int。
bigint
数字中的长整型。等同于java中的long。
float
单精度浮点型数据
double
双精度浮点型数据
date
短日期类型
datetime
长日期类型
clob
字符大对象
最多可以存储4G的字符串。
比如:存储一篇文章,存储一个说明。
超过255个字符的都要采用CLOB字符大对象来存储。
Character Large OBject:CLOB
blob
二进制大对象
Binary Large OBject
专门用来存储图片、声音、视频等流媒体数据。
往BLOB类型的字段上插入数据的时候,例如插入一个图片、视频等,
你需要使用IO流才行。
drop table xxx;//删除表
drop table if exists xxx;//如果这张表存在的话,删除
插入数据insert (DML)
语法格式:
insert into 表名(字段名1,字段名2,字段名3...) values(值1,值2,值3);
注意:字段名和值要一一对应。什么是一一对应?
数量要对应。数据类型要对应。
没有给其它字段指定值的话,默认值是NULL。
创建表使用default常量
create table t_student(
no int,
name varchar(32),
sex char(1) default 'm',
age int(3),
email varchar(255)
);
格式化数字:format(数字, '格式')
str_to_date:将字符串varchar类型转换成date类型
date_format:将date类型转换成具有一定格式的varchar字符串类型。
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 from t_user where id = 2;
insert into t_user(id) values(2);
delete from t_user; // 删除所有!
常用操作三
insert 一次插入多条记录
insert into t_user(id,name,birth,create_time) values
(1,'zs','1980-10-11',now()),
(2,'lisi','1981-10-11',now()),
(3,'wangwu','1982-10-11',now());
语法:insert into t_user(字段名1,字段名2) values(),(),(),();
快速删除表中的数据?(turncate比较重要)
delete语句删除数据的原理?(delete属于DML语句!!!)
表中的数据被删除了,但是这个数据在硬盘上的真实存储空间不会被释放!!!
这种删除缺点是:删除效率比较低。
这种删除优点是:支持回滚,后悔了可以再恢复数据!!!
truncate语句删除数据的原理?
这种删除效率比较高,表被一次截断,物理删除。
这种删除缺点:不支持回滚。
这种删除优点:快速。
用法:truncate table dept_bak; (这种操作属于DDL操作。)
truncate是删除表中的数据,表还在!
对表结构的增删改?
添加一个字段,删除一个字段,修改一个字段!!!
约束
在创建表的时候,我们可以给表中的字段加上一些约束,来保证这个表中数据的完整性、有效性!!!
约束包括哪些?
非空约束:not null
唯一性约束: unique
主键约束: primary key (简称PK)
外键约束:foreign key(简称FK)
检查约束:check(mysql不支持,oracle支持)
not null:
create table ??? (id int, name varchar(255) not null);
unique:
create table ??? (id int, name varchar(255) unique);
新需求:name和id两个字段联合起来具有唯一性!!!!
create table ??? (id int, name varchar(255), unique(id,name));
在mysql当中,如果一个字段同时被not null和unique约束的话,该字段自动变成主键字段。
create table ??? (id int not null unique, name varchar(255));
primary key:
主键约束的相关术语?
主键约束:就是一种约束。
主键字段:该字段上添加了主键约束,这样的字段叫做:主键字段
主键值:主键字段中的每一个值都叫做:主键值。
什么是主键?有啥用?
主键值是每一行记录的唯一标识。
主键值是每一行记录的身份证号!!!
记住:任何一张表都应该有主键,没有主键,表无效!!
怎么给一张表添加主键约束呢?
//一个字段做主键,叫做:单一主键
create table ??? (id int primary key, name varchar(255));
//表级约束主要是给多个字段联合起来添加约束?
create table ??? (id int, name varchar(255),primary key(id,name));
在实际开发中不建议使用:复合主键。建议使用单一主键!
因为主键值存在的意义就是这行记录的身份证号,只要意义达到即可,单一主键可以做到。
复合主键比较复杂,不建议使用!!!
主键除了:单一主键和复合主键之外,还可以这样进行分类?
自然主键:主键值是一个自然数,和业务没关系。
业务主键:主键值和业务紧密关联,例如拿银行卡账号做主键值。这就是业务主键!
在mysql当中,有一种机制,可以帮助我们自动维护一个主键值?
create table ??? (id int primary key auto_increment,name varchar(255));//auto_increment表示自增,从一开始递增。
insert into ???(name) values('sss');//id会自动变成1
foreign key:
注意:
t_class是父表
t_student是子表
删除表的顺序?
先删子,再删父。
创建表的顺序?
先创建父,再创建子。
删除数据的顺序?
先删子,再删父。
插入数据的顺序?
先插入父,再插入子。
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(cno) references t_class(classno));
mysql常用的存储引擎
MyISAM存储引擎?
它管理的表具有以下特征:
使用三个文件表示每个表:
格式文件 — 存储表结构的定义(mytable.frm)
数据文件 — 存储表行的内容(mytable.MYD)
索引文件 — 存储表上索引(mytable.MYI):索引是一本书的目录,缩小扫描范围,提高查询效率的一种机制。
可被转换为压缩、只读表来节省空间
提示一下:
对于一张表来说,只要是主键,
或者加有unique约束的字段上会自动创建索引。
MyISAM存储引擎特点:
可被转换为压缩、只读表来节省空间
这是这种存储引擎的优势!!!!
MyISAM不支持事务机制,安全性低。
InnoDB存储引擎?
这是mysql默认的存储引擎,同时也是一个重量级的存储引擎。
InnoDB支持事务,支持数据库崩溃后自动恢复机制。
InnoDB存储引擎最主要的特点是:非常安全。
它管理的表具有下列主要特征:
– 每个 InnoDB 表在数据库目录中以.frm 格式文件表示
– InnoDB 表空间 tablespace 被用于存储表的内容(表空间是一个逻辑名称。表空间存储数据+索引。)
– 提供一组用来记录事务性活动的日志文件
– 用 COMMIT(提交)、SAVEPOINT 及ROLLBACK(回滚)支持事务处理
– 提供全 ACID 兼容
– 在 MySQL 服务器崩溃后提供自动恢复
– 多版本(MVCC)和行级锁定
– 支持外键及引用的完整性,包括级联删除和更新
InnoDB最大的特点就是支持事务:
以保证数据的安全。效率不是很高,并且也不能压缩,不能转换为只读,
不能很好的节省存储空间。
MEMORY存储引擎?
使用 MEMORY 存储引擎的表,其数据存储在内存中,且行的长度固定,
这两个特点使得 MEMORY 存储引擎非常快。
MEMORY 存储引擎管理的表具有下列特征:
– 在数据库目录内,每个表均以.frm 格式的文件表示。
– 表数据及索引被存储在内存中。(目的就是快,查询快!)
– 表级锁机制。
– 不能包含 TEXT 或 BLOB 字段。
MEMORY 存储引擎以前被称为HEAP 引擎。
MEMORY引擎优点:查询效率是最高的。不需要和硬盘交互。
MEMORY引擎缺点:不安全,关机之后数据消失。因为数据和索引都是在内存当中。
事务
一个事务其实就是一个完整的业务逻辑。
是一个最小的工作单元。不可再分。
什么是一个完整的业务逻辑?
假设转账,从A账户向B账户中转账10000.
将A账户的钱减去10000(update语句)
将B账户的钱加上10000(update语句)
这就是一个完整的业务逻辑。
以上的操作是一个最小的工作单元,要么同时成功,要么同时失败,不可再分。
这两个update语句要求必须同时成功或者同时失败,这样才能保证钱是正确的。
只有DML语句才会有事务这一说,其它语句和事务无关!!!
insert、delete、update
到底什么是事务呢?
说到底,说到本质上,一个事务其实就是多条DML语句同时成功,或者同时失败!
事务:就是批量的DML语句同时成功,或者同时失败!
提交事务?
清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中。
提交事务标志着,事务的结束。并且是一种全部成功的结束。
回滚事务?
将之前所有的DML操作全部撤销,并且清空事务性活动的日志文件
回滚事务标志着,事务的结束。并且是一种全部失败的结束。
怎么提交事务,怎么回滚事务?
提交事务:commit; 语句
回滚事务:rollback; 语句(回滚永远都是只能回滚到上一次的提交点!)
事务对应的英语单词是:transaction
一个业务通常是需要多条DML语句共同执行才能完成的,为了保证数据的安全,必须要求同时成功之后再提交,所以不能执行一条就提交一条。
mysql默认情况下是支持自动提交事务的。(自动提交)
什么是自动提交?
每执行一条DML语句,则提交一次!
怎么将mysql的自动提交机制关闭掉呢?
先执行这个命令:start transaction;
//回滚数据 rollback
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into dept_bak values(10,'abc', 'tj');
Query OK, 1 row affected (0.00 sec)
mysql> insert into dept_bak values(10,'abc', 'tj');
Query OK, 1 row affected (0.00 sec)
mysql> select * from dept_bak;
+--------+-------+------+
| DEPTNO | DNAME | LOC |
+--------+-------+------+
| 10 | abc | tj |
| 10 | abc | tj |
+--------+-------+------+
2 rows in set (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from dept_bak;
Empty set (0.00 sec)
//提交数据 commit
mysql> insert into dept_no values(13,12);
Query OK, 1 row affected (0.00 sec)
mysql> insert into dept_no values(14,12);
Query OK, 1 row affected (0.00 sec)
mysql> select * from dept_no;
+----+------+
| id | name |
+----+------+
| 11 | 10 |
| 12 | 10 |
| 13 | 12 |
| 14 | 12 |
+----+------+
4 rows in set (0.00 sec)
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
mysql> rollback;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from dept_no;
+----+------+
| id | name |
+----+------+
| 11 | 10 |
| 12 | 10 |
| 13 | 12 |
| 14 | 12 |
+----+------+
事务包括4个特性?
A:原子性
说明事务是最小的工作单元。不可再分。
C:一致性
所有事务要求,在同一个事务当中,所有操作必须同时成功,或者同时失败,
以保证数据的一致性。
I:隔离性
A事务和B事务之间具有一定的隔离。
教室A和教室B之间有一道墙,这道墙就是隔离性。
A事务在操作一张表的时候,另一个事务B也操作这张表会那样???
会出现线程安全问题
D:持久性
事务最终结束的一个保障。事务提交,就相当于将没有保存到硬盘上的数据
保存到硬盘上!
重点研究一下事务的隔离性!!!
读未提交:read uncommitted(最低的隔离级别)《没有提交就读到了》
什么是读未提交?
事务A可以读取到事务B未提交的数据。
这种隔离级别存在的问题就是:
脏读现象!(Dirty Read)
我们称读到了脏数据。
set global transaction isolation level read uncommitted;
读已提交:read committed《提交之后才能读到》
什么是读已提交?
事务A只能读取到事务B提交之后的数据。
这种隔离级别解决了什么问题?
解决了脏读的现象。
这种隔离级别存在什么问题?
不可重复读取数据。(前后两次读可能数据不一致)
什么是不可重复读取数据呢?
在事务开启之后,第一次读到的数据是3条,当前事务还没有
结束,可能第二次再读取的时候,读到的数据是4条,3不等于4
称为不可重复读取。
set global transaction isolation level read committed;
可重复读:repeatable read《提交之后也读不到,永远读取的都是刚开启事务时的数据》
什么是可重复读取?
事务A开启之后,不管是多久,每一次在事务A中读取到的数据
都是一致的。即使事务B将数据已经修改,并且提交了,事务A
读取到的数据还是没有发生改变,这就是可重复读。
可重复读解决了什么问题?
解决了不可重复读取数据。
可重复读存在的问题是什么?
可以会出现幻影读。
每一次读取到的数据都是幻象。不够真实!
set global transaction isolation level repeatable read;
序列化/串行化:serializable(最高的隔离级别)
这是最高隔离级别,效率最低。解决了所有的问题。
这种隔离级别表示事务排队,不能并发!
synchronized,线程同步(事务同步)
每一次读取到的数据都是最真实的,并且效率是最低的。
set global transaction isolation level serializable;
索引
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z4uhygQH-1647070560431)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220227150623675.png)]
索引类似于B-Tree,
在mysql当中,主键上,以及unique字段上都会自动添加索引。
什么条件下,我们会考虑给字段添加索引呢?
条件1:数据量庞大(到底有多么庞大算庞大,这个需要测试,因为每一个硬件环境不同)
条件2:该字段经常出现在where的后面,以条件的形式存在,也就是说这个字段总是被扫描。
条件3:该字段很少的DML(insert delete update)操作。(因为DML之后,索引需要重新排序。)
建议通过主键查询,建议通过unique约束的字段进行查询,效率是比较高的。
索引的创建:
create index emp_ename_index on emp(ename);
给emp表的ename字段添加索引,起名:emp_ename_index
索引的删除:
drop index emp_ename_index on emp;
将emp表上的emp_ename_index索引对象删除
怎么查看SQL语句是否使用了索引进行检索
explain select * from emp where ename = 'KING';
什么时候索引失效?
1.select * from emp where ename like '%T';
ename上即使添加了索引,也不会走索引,为什么?
原因是因为模糊匹配当中以“%”开头了!
尽量避免模糊查询的时候以“%”开始。
这是一种优化的手段/策略。
2.使用or的时候会失效,如果使用or那么要求or两边的条件字段都要有
索引,才会走索引,如果其中一边有一个字段没有索引,那么另一个
字段上的索引也会实现。所以这就是为什么不建议使用or的原因。
3.使用复合索引的时候,没有使用左侧的列查找,索引失效
什么是复合索引?
两个字段,或者更多的字段联合起来添加一个索引,叫做复合索引。
create index emp_job_sal_index on emp(job,sal);
explain select * from emp where sal = 800;//不会调用索引
4.在where当中索引列参加了运算,索引失效。
explain select * from emp where sal+1 = 800;
5.在where当中索引列使用了函数
explain select * from emp where lower(ename) = 'smith';
视图
什么是视图?
view:站在不同的角度去看待同一份数据。
怎么创建视图对象?怎么删除视图对象?
创建视图对象
create view ???_view as select * from ???;
删除视图对象
drop view ???_view;
注意:只有DQL语句才能以view的形式创建。
create view view_name as 这里的语句必须是DQL语句;
我们可以面向视图对象进行增删改查,对视图对象的增删改查,会导致
原表被操作!(视图的特点:通过对视图的操作,会影响到原表数据。)
视图对象在实际开发中到底有什么用?《方便,简化开发,利于维护》
类似于java把代码封装到一个函数里
DBA常用命令
数据导出
mysqldump ??? > 地址 -用户名 -密码
数据导入
source ???.sql;
数据库设计三范式
什么是数据库设计范式?
数据库表的设计依据。教你怎么进行数据库表的设计。
第一范式:要求任何一张表必须有主键,每一个字段原子性不可再分。
第二范式:建立在第一范式的基础之上,要求所有非主键字段完全依赖主键,不要产生部分依赖。
第三范式:建立在第二范式的基础之上,要求所有非主键字段直接依赖主键,不要产生传递依赖。
多对多,三张表,关系表两个外键!!!!!!!!!!!!!!!
一对多,两张表,多的表加外键!!!!!!!!!!!!!!!!
一对一,外键唯一!!!!!!!!!!
数据库设计三范式是理论上的。
实践和理论有的时候有偏差。
最终的目的都是为了满足客户的需求,有的时候会拿冗余换执行速度。
因为在sql当中,表和表之间连接次数越多,效率越低。(笛卡尔积)
有的时候可能会存在冗余,但是为了减少表的连接次数,这样做也是合理的,
并且对于开发人员来说,sql语句的编写难度也会降低。
补充
当第二条sql语句和上面一条sql语句一模一样,甚至空格都一样的话,这条sql语句不会进行编译,直接执行。
数据库设计的补充
- 数据库设计的范式和数据库的查询性能很多时候是相悖的,我们需要根据实际业务情况做一个选择:
- 查询频次不高的情况下,我们更倾向于提高数据库的设计范式,从而提高存储的效率
- 查询频次较高的情形,我们更倾向于牺牲数据库的规范度,降低数据库设计的范式,运行特定的冗余。从而提高查询的性能