MySQL必备知识(快速上手,直接掌握数据库操作)

Mysql知识精化

一、Mysql实用知识量并不多,核心就是增删改查,其他的一切基本都是围绕这这个核心展开,下面的知识包含了Mysql使用的方方面面,请大家放心食用!将以三张表为例展开,表结构如下所示:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
数据库文件直接下载:sql文件
二、信息介绍
该数据有三张表,信息介绍如下:

                        部门表dept(deptno部门编号、dname部门名称、loc位置)
                        员工表emp(empno工号、ename员工姓名、job职位、mgr直属领导工号、

                              hiredate入职日期、sal月薪、comm补贴、deptno部门编号)

                      薪水等级表salgrade(grade等级、losal最低工资、hisal最高工资)

三、知识+例子+sql语句

1、查询年薪:select ename,sal×12 from emp;
给查询结果的列重命名:select ename,sal×12 as yearsal from emp; (as是可以省略的)
别名中有中文:select ename,sal×12 as 年薪 from emp; //错误
select ename,sal×12 as ‘年薪’ from emp; //正确
注意:标准sql语句中字符串使用单引号括起来(双引号也可以,尽量别用)

2、条件查询。select 字段,字段… from 表名 where 条件;
查询工资等于5000的员工姓名:select ename from emp where sal = 5000;
查询SMITH的工资:select sal from emp where ename = ‘SMITH’; (姓名字段类型是varcher,是字符串)
查询工资大于3000的员工姓名:select ename from emp where sal >3000;
工资在1100和3000之间的员工姓名,包括1100和3000:select ename from emp where sal>=1100 and sal<=3000;
select ename from emp where sal between 1100 and 3000;
大于等于 : >= 不等于3000: !=3000 或 <>3000 且:and
between…and… :在…和…之间(闭区间) 在使用时必须左小右大
between and 还可以使用在字符串方面:select ename frome emp where ename between ‘A’ and ‘C’; (根据首字母判定,左闭右开)

3、在数据库中NULL不是一个值,代表什么都没有,为空,和0不一样。空不是一个值,不能用等号衡量,必须使用 is null或 is not null
找出哪些津贴为null:select ename from emp where comn is null;
找出哪些津贴为null和0:select ename from emp where comn is null and comn=0;

4、工作岗位是MANAGER和SALESMAN的员工:select ename from emp where job=‘MANAGER’ or job =‘SALESMAN’;
and: 和 or:或者 and运算级高
找出工资大于1000并且部门编号是20或30部门的员工名字:select ename from emp where sal>1000 and (deptno=20 or deptno =30 ) ;
注意:当运算符的优先级不确定时,加小括号

5、in等同于or
工作岗位是MANAGER和SALESMAN的员工:select ename from emp where job=‘MANAGER’ or job =‘SALESMAN’;
select ename from emp where job in ( ‘MANAGER’ , ‘SALESMAN’ ) ;
not in:不在这几个值当中。
查询工资不是800和5000的人: select ename from emp where sal not in ( 800,5000 ) ;

6、模糊查询like
2个特殊的符号:% _
%:任意多个字符 _:任意一个字符
找出名字里含o的: select ename from emp where ename like ’ %o% ’ ;
找出名字中有下划线的:select ename from emp where ename like ‘%_%’ ; // 下划线转义 在前面加上斜杠

7、排序(升序、降序)
按照工资升序排序:select ename,sal from emp order by sal; (默认是升序排列)
asc : 升序 desc :降序
select ename,sal from emp order by sal; //升序
select ename,sal from emp order by sal asc; //升序
select ename,sal from emp order by sal desc; //降序
按照工资的降序排列,当工资相同时按照名字的升序排列:select ename,sal from emp order by sal desc , ename asc;
多个字段同时排序,越靠前的字段越能起到主导作用,只有前面字段无法排序的时候,才会启用后面的字段。
找出工作岗位是SALESMAN的员工,并且要求按照工资的降序排列:select ename from emp where job=‘SALESMAN’ order by say desc;
order by 是最后执行的。 先起别名,排序也是根据别名进行排序的。

8、分组函数
count:计数 sum:求和 avg:平均值 max:最大值 min:最小值
所有的分组函数都是对”某一组“数据进行操作的。
找出工资总和:select sun(sal) from emp;
找出总人数:select count (*) from emp;
找出总人数:select count (ename) from emp;
分组函数一共5个,又名:多行处理函数
多行处理函数的特点:输入多行,最终输出一行
分组函数自动忽略NULL

 找出工资高于平均工资的员工:select ename,sal from emp where sal>age(sal);  //错误
 原因:分组函数不可直接使用在where子句中,因为group by是在where执行后才会执行的。
 找出工资高于平均工资的员工:select ename,sal from emp where sal>(select avg(sal) from emp);    //正确
  
 select       5 
       ..
 from         1
       ..
 where       2
       ..
 group by   3
       ..
  having      4
       ..
  order by    6
       ..

 count(*) :不是统计某个字段中数据的个数,而是统计总记录条数。(和某个字段无关)
 count(comm):表示统计commm字段不为NULL 的数据总数量。

9、单行处理函数:输入一行,输出一行
计算每个员工的年薪:select ename,(sal+comm)*12 as ‘年薪’ from emp;
如果某人的comm为NULL,他的年薪就是0
重点:只要数学表达式中有NULL参与运算,结果一定是NULL
故 计算每个员工的年薪:select ename,(sal+ifnull(comm,0) )*12 as ‘年薪’ from emp;
ifnull()空处理函数: ifnull(可能为NULL的数据,被当成什么来处理) 属于单行处理函数
select ename,ifnull(comm,0) as comm from emp;

10、group by 和 having
group by :按照某个字段或者某些字段进行分组
having :对分组之后的数据进行再次过滤
找出每个工作岗位的最高薪资:select max(sal) from emp group by job;
注意:分组函数一般都会和group by 联合使用,这也是为什么它被称为分组函数的原因
当一条sql语句中没有group by的话,整张表的数据自成一组。

  select ename,max(sal),job from emp group by job;
   以上在mysql当中可以执行,但是结果没有意义,在Oracle数据库中会语法错误,因为它的语法规则比Mysql严谨
   注意:当一条语句中有group by 的话,select后面只能跟分组函数和参与分组的字段。
  
   找出每个部门不同岗位的最高工资: select deptno,job,max(sal) from emp group by deptno,job; (把两个分组看成一个字段)
   找出每个部门的最高工资,要求显示工资大于2500的:select deptno, max(sal) from emp group by deptno having max(sal)>2500;    //可以但是效率低
                                                                                select deptno,max(sal) from emp where sal>2500 group by deptno  //效率高,先用where过滤掉

   找出每个部门的平均工资,要求显示工资大于2000的:select deptno,avg(sal) from emp group by deptno having avg(sal)>2000; 

11、查看无线网密码
netsh wlan show profiles :查看本机连接过无线密码
netsh wlan show profile name=“楠” key=clear 查看这个无线网的信息(name是无线网的密码)

12、关于查询结果集的去重
select distinct job from emp; //distinct 关键字去除重复记录
select ename,distinct job from emp; //错误 distinct只能出现在所有字段的前面
注意:distinct 出现在最前方,表示后面所有字段联合起来去除重复
统计岗位的数量:select count(distinct job) from emp;

13、连接查询:多张表联合查询取出最终的结果
当学号、姓名、班级、地址都放在一张表的时候,数据会存在大量的重复,导致数据的冗余,往往拆分成多张表。

   根据表的连接方式来划分,包括:
          内连接:  
              等值连接 
              非等值连接
              自连接
          外连接:
               左外连接
               右外连接
          全连接(很少用)

     在表的连接查询方面有一种现象被称为 笛卡尔积现象: 如果两张表连接但没有条件限制,结果条数为两张表条数的乘积
     找出每一个员工的部门名称,要显示员工名和部门名:select ename,dname from emp,dept;  (ename和dname要联合起来显示,所以发生笛卡尔积现象)

14、关于表的别名
select e.ename , d.dname from emp e , dept d; (56个结果)
表的别名好处:执行效率高、可读性好
加条件避免笛卡尔积现象,不会减少记录的匹配次数,依然是56次,只不过显示的是 有效记录。

  显示员工名和部门名:select e.ename,d.dname from emp e,dept d where e.deptno = d.deptno;    (避免了笛卡尔积现象,但是暗地还是匹配了56次)
+--------+-------------+
| ename  | dname       |
+--------+-------------+
| CLARK  | ACCOUNTING  |
| KING   | ACCOUNTING  |
| MILLER | ACCOUNTING  |
| SIMITH | RESEARCHING |
| JONES  | RESEARCHING |
| SCOTT  | RESEARCHING |
| ADAMS  | RESEARCHING |
| FORD   | RESEARCHING |
| ALLEN  | SALES       |
| WARD   | SALES       |
| MARTIN | SALES       |
| BLAKE  | SALES       |
| TURNER | SALES       |
| JAMES  | SALES       |
+--------+-------------+
14 rows in set (0.00 sec)	

15、内连接之等值连接:最大特点是:条件是等量关系
查询每个员工的部门名称:SQL92: select e.ename,d.dname from emp e,dept d where e.deptno = d.deptno;
SQL99: select e.ename,d.dname from emp e join dept d on e.deptno = d.deptno;
SQL99语法: …
A
(inner)join //inner 可以省略,内的意思
B
on
连接条件
where

      SQL99语法结构更清晰一些:表的连接条件和后来的where条件分离了。

16、内连接之非等值连接:最大特点是:连接条件中的关系是非等量关系。
找出每个员工的工资等级,要求显示员工名和工资等级:select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal >= s.losal and e.sal<= s.hisal;
select e.ename,e.sal,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;
±-------±--------±------+
| ename | sal | grade |
±-------±--------±------+
| SIMITH | 800.00 | 1 |
| ALLEN | 1600.00 | 3 |
| WARD | 1250.00 | 2 |
| JONES | 2975.00 | 4 |
| MARTIN | 1250.00 | 2 |
| BLAKE | 2850.00 | 4 |
| CLARK | 2450.00 | 4 |
| SCOTT | 3000.00 | 4 |
| KING | 5000.00 | 5 |
| TURNER | 1500.00 | 3 |
| ADAMS | 1100.00 | 1 |
| JAMES | 950.00 | 1 |
| FORD | 3000.00 | 4 |
| MILLER | 1300.00 | 2 |
±-------±--------±------+
17、自连接:最大的特点是:一张表看做两张表,自己连接自己
±------±-------±-----+
| empno | ename | mgr |
±------±-------±-----+
| 7369 | SIMITH | 7902 |
| 7499 | ALLEN | 7698 |
| 7521 | WARD | 7698 |
| 7566 | JONES | 7839 |
| 7654 | MARTIN | 7698 |
| 7698 | BLAKE | 7839 |
| 7782 | CLARK | 7839 |
| 7788 | SCOTT | 7566 |
| 7839 | KING | NULL |
| 7844 | TURNER | 7698 |
| 7876 | ADAMS | 7788 |
| 7900 | JAMES | 7698 |
| 7902 | FORD | 7566 |
| 7934 | MILLER | 7782 |
±------±-------±-----+
找出每个员工的上级领导,要求显示员工名和对应的领导名
员工表 emp a 领导表 emp b
故sql语句:select a.ename as ‘员工’,b.ename as ‘领导’ from emp a join emp b on a.mgr=b.empno;
±-------±------+
| 员工 | 领导 |
±-------±------+
| SIMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK | 13条记录 少一个人 KING 因为他没有领导(他是老板)
±-------±------+

18、外连接

   内连接:假设A和B表进行连接,使用内连接的话,凡是A表和B表能够匹配上的记录查询出来,就是内连接,AB两张表没有主副之分,是平等的
   外连接:假设A和B表进行连接,使用外连接的话,AB两张表有一张是主表,一张是副表,主要查询主表中的数据,捎带的查询副表,当
                副表中的数据没有和主表中的数据匹配上,副表自动模拟出NULL与匹配
    外连接的分类:
                左外连接(左连接):表示左边的这张表是主表
               右外连接(右连接):表示右边的这张表是主表
    左连接有右连接的写法,右连接也有对应的左连接的写法

找出每个员工的上级领导(所有员工都要查询出来,King也要查)?
内连接sql语句:select a.ename as ‘员工’ , b.ename as ‘领导’ from emp a join emp b on a.mgr = b.empno; //13条记录,少了King
左外连接:select a.ename as ‘员工’ , b.ename as ‘领导’ from emp a left join emp b on a.mgr = b.empno;
±-------±------+
| 员工 | 领导 | 左外连接:left outer join 位于左边的a是主表(员工表),顺带b(领导表),b没值就用NULL代表
±-------±------+ //outer可以省略
| SIMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| KING | NULL |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
±-------±------+
14 rows in set (0.00 sec)

右外连接:select a.ename as ‘员工’ , b.ename as ‘领导’ from emp b right join emp a on a.mgr = b.empno;
±-------±------+
| 员工 | 领导 | 右外连接:right outer join 位于右边的a是主表(员工表),顺带b(领导表),b没值就用NULL代表
±-------±------+ //outer 可以省略
| SIMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| KING | NULL |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
±-------±------+
14 rows in set (0.00 sec)

外连接最重要的特点是:主表的数据无条件的全部查询出来。如果使用内连接,可能会造成数据的丢失。

找出哪个部门没有员工: select distinct d.* from emp e right join dept d on e.deptno =d.deptno where e.empno is null;
±-------±-----------±-------+
| deptno | dname | loc |
±-------±-----------±-------+
| 40 | OPERATIONS | BOSTON |
±-------±-----------±-------+
1 row in set (0.00 sec)

19、三张表怎么连接查询
找出每个员工的部门名称以及工资等级: select e.ename,d.dname,s.grade from emp e, dept d,salgrade s where( e.deptno=d.deptno) and( e.sal between s.losal and s.hisal); //SQL92
select e.ename,d.dname,s.grade from emp e join dept d on e.deptno = d.deptno join salgrade s on e.sal between s.losal and s.hisal; //SQL99

A //表示:A表和B表先进行表连接,连接之后A表继续和C表连接
join
B
join
C
on

±-------±------------±------+
| ename | dname | grade |
±-------±------------±------+
| SIMITH | RESEARCHING | 1 |
| ALLEN | SALES | 3 |
| WARD | SALES | 2 |
| JONES | RESEARCHING | 4 |
| MARTIN | SALES | 2 |
| BLAKE | SALES | 4 |
| CLARK | ACCOUNTING | 4 |
| SCOTT | RESEARCHING | 4 |
| KING | ACCOUNTING | 5 |
| TURNER | SALES | 3 |
| ADAMS | RESEARCHING | 1 |
| JAMES | SALES | 1 |
| FORD | RESEARCHING | 4 |
| MILLER | ACCOUNTING | 2 |
±-------±------------±------+
14 rows in set (0.00 sec)

找出每个员工的部门名称、工资等级、上层领导:
select
e.ename ‘员工’ ,d.dname ‘部门’,s.grade ‘工资等级’,e1.ename as ‘领导’
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 e1
on
e.mgr=e1.empno;

±-------±------------±---------±------+
| 员工 | 部门 | 工资等级 | 领导 |
±-------±------------±---------±------+
| SIMITH | RESEARCHING | 1 | FORD |
| ALLEN | SALES | 3 | BLAKE |
| WARD | SALES | 2 | BLAKE |
| JONES | RESEARCHING | 4 | KING |
| MARTIN | SALES | 2 | BLAKE |
| BLAKE | SALES | 4 | KING |
| CLARK | ACCOUNTING | 4 | KING |
| SCOTT | RESEARCHING | 4 | JONES |
| KING | ACCOUNTING | 5 | NULL |
| TURNER | SALES | 3 | BLAKE |
| ADAMS | RESEARCHING | 1 | SCOTT |
| JAMES | SALES | 1 | BLAKE |
| FORD | RESEARCHING | 4 | JONES |
| MILLER | ACCOUNTING | 2 | CLARK |
±-------±------------±---------±------+
14 rows in set (0.01 sec)

20、子查询
select语句当中嵌套select语句,被嵌套的select语句是子查询。
子查询可以出现在哪里?
select
…(select)
from
…(select)
where
…(select)

where子句中使用子查询?
找出高于平均工资的员工信息:select * from emp where sal>(select avg(sal) from emp );

21、from后面嵌套子查询?
找出每个部门平均工资的工资等级:

第一步:找出每个部门的平均工资:select deptno,avg(sal) as avgsal from emp group by deptno;
±-------±------------+
| deptno | avgsal | //把这张表当成存在的表 t ,让t表和salgrade表连接,条件是t.avgsal between s.losal and s.hisal
±-------±------------+
| 10 | 2916.666667 |
| 20 | 2175.000000 |
| 30 | 1566.666667 |
±-------±------------+
第二步:将以上的查询结果当成临时表t,让t表和salgrade s 表连接
select
t.* , s.grade
from
(select deptno,avg(sal) as avgsal from emp group by deptno) t
join
salgrade s
on
t.avgsal between s.losal and s.hisal;

±-------±------------±------+
| deptno | avgsal | grade |
±-------±------------±------+
| 10 | 2916.666667 | 4 |
| 20 | 2175.000000 | 4 |
| 30 | 1566.666667 | 3 |
±-------±------------±------+

找出每个部门平均的工资等级:
方法1: select
t.deptno,avg(t.salavg)
from
(select e.deptno,s.grade as salavg from emp e join salgrade s on e.sal between s.losal and s.hisal) t
group by
deptno ;

方法2: select
e.deptno,avg(s.grade)
from
emp e
join
salgrade s
on
e.sal between s.losal and s.hisal
group by
e.deptno;

±-------±--------------+
| deptno | avg(t.salavg) |
±-------±--------------+
| 10 | 3.6667 |
| 20 | 2.8000 |
| 30 | 2.5000 |
±-------±--------------+

22、在select后面嵌套子查询
找出每个员工所在的部门名称,要求显示员工名和部门名:select
e.ename , (select d.dname from dept d where e.deptno = d.deptno) as dname
from
emp e;

23、union (可以将查询结果集相加)
找出工作岗位是SALESMAN和MANAGER的员工:
第一种: select * from emp where job=‘SALESMAN’ or job= ‘MANAGER’;
第二种: select * from emp where job in (‘SALESMAN’’ , ‘MANAGER’);

   第三种:    select * from emp where job='SALESMAN'
                    union
                    select * from emp where job='MANAGER';

±------±-------±---------±-----±-----------±--------±--------±-------+
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
±------±-------±---------±-----±-----------±--------±--------±-------+
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | NULL | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
±------±-------±---------±-----±-----------±--------±--------±-------+

两张不相干的表中的数据拼接在一起显示:select ename from emp union select dname from dept;
±------------+
| ename |
±------------+
| SIMITH | //员工名
| ALLEN |
| WARD |
| JONES |
| MARTIN |
| BLAKE |
| CLARK |
| SCOTT |
| KING |
| TURNER |
| ADAMS |
| JAMES |
| FORD |
| MILLER |
| ACCOUNTING | //部门名
| RESEARCHING |
| SALES |
| OPERATIONS |
±------------+

使用union时,每张表查询的字段数目要相同

24、limit (重点,分页查询靠它)
limit 是mysql 特有的,其他数据库中没有,不同用。(Oracle中有个相同的机制,叫rownum)
limit的作用: 取结果集中的部分数据

   语法机制:
            limit startIndex , length
         startIndex 表示起始位置        length 表示取几个
  取出工资前5名的员工:select ename ,sal from emp order by sal  desc limit 0,5;
                                    select ename ,sal from emp order by sal  desc limit    5;
   limit是sql语句最后执行的环节

   找出工资排名在第四到第九的员工:select ename,sal from emp order by sal desc limit 3,6;

   
   每页显示3条记录:
                  第一页:  0,3            第二页:3,3        第3页:6,3      第4页:9,3          
                   每页显示pageSize条记录,第pageNo页    :  (pageNo-1)* pageSize ,  pageSize

25、创建表:
建表语句的语法格式:
create table 表名(
字段名1 数据类型,
字段名2 数据类型,

);

  MYSQL当中字段的数据类型:
                       int       整数
                       bigint    长整数
                       float      浮点数
                       char   定长字符串
                       varchar    可变字符串           最大255字符
                        date       日期类型
                       BLOB      二进制大对象呢(存储图片、视频等流媒体信息)
                       CLOB     字符大对象(存储较大文本,可以存储4G的字符串) 	 
 
    char和varcher怎么选择:
                        在实际开发中,当某个字段中的数据长度不发生改变时,是定长的	比如性别、生日等都是采用char
                        当一个字段的数据长度不确定,比如简介等采用varchar
     BLOB 和CLOB类型的使用:
                          电影的海报:BLOB
                           电影历史:CLOB


     表名在数据库当中一般是t_或tbl_开始

    创建学生表:create table t_student(
                       no bigint,
                       name varchar(255),
                       sex   char(1)    default 1,      //插入数据时如果没有规定值,默认值为1
                       classno varchar(255),
                       birth char(10)
                       ); 

26、insert语句插入数据
语法格式:
insert into 表名(字段名1,字段名2,字段名3, …) values (值1,值2,值3, …)
要求:字段数量和值的数量相同 ,且数据类型要对应相同。

    insert into t_student (no,name,sex,classno,birth) values (1,'zhangsan' , '1'  , 'gaosan1ban' , '1950-10-12');

    字段名顺序、个数没有要求,改怎么插入怎么插入,没有数据的用NULL代替

    注意:insert 语句插入数据了,表格中必然会多出一行记录,即使多的这一行记录中某些字段是NULL,后期也没有办法在执行insert语句插入数据了
              只能使用update进行更新

   insert into t_student values(2,'jack','1' , 'gaosan1ban','1955-11-15');          //字段可以省略不写,但是后面的values对数量和循序都有要求

  一次性插入多行数据: insert into t_student 
                                                (no,name,sex,classno,birth) 
                                    values 
                                                (3,'hgueg' , '1'  , 'gaosan1ban' , '1930-12-12'), (4,'yali' , '2'  , 'gaosan1ban' , '1950-10-16');

27、表的复制
create table 表名 as select 语句;
将查询结果当做表创建出来

28、将查询结果插入到一张表中
insert into t_student select * from t_sr

±-----±---------±-----±-----------±-----------+
| no | name | sex | classno | birth |
±-----±---------±-----±-----------±-----------+
| 1 | zhangsan | 1 | gaosan1ban | 1950-10-12 |
| 2 | jack | 1 | gaosan1ban | 1955-11-15 |
| 3 | hgueg | 1 | gaosan1ban | 1930-12-12 |
| 4 | yali | 2 | gaosan1ban | 1950-10-16 |
| 1 | zhangsan | 1 | gaosan1ban | 1950-10-12 |
| 2 | jack | 1 | gaosan1ban | 1955-11-15 |
| 3 | hgueg | 1 | gaosan1ban | 1930-12-12 |
| 4 | yali | 2 | gaosan1ban | 1950-10-16 |
±-----±---------±-----±-----------±-----------+
8 rows in set (0.00 sec)

29、修改数据:update
语法格式:
update 表名 set 字段名1=值1 , 字段名2=值2, … where 条件;
注意:没有条件整张表数据全部更新

     将部门10的LOC修改为SHANGHAI,将部门名称修改为RENSHIBU:
     update dept1 set loc='SHANGHAI' , dname='RENSHIBU'  where deptno=10;

30、删除数据
delete from 表名 where 条件

  删除10部门数据:delete from dept1 where deptno=10;
  删除所有记录:delete from dept1;

 怎么删除大表数据?(重点)
      truncate table emp1;       //表被截断,不可回滚,永久丢失

  删除表(结构 ) :drop table 表名;

31、约束
约束:在创建表的时候,可以给表的字段添加相应的约束,添加约束的目的是为了保证表中数据的
合法性、有效性、完整性。
常见的约束:
非空约束(not null) :约束的字段不能为NULL
唯一约束(unique) : 约束的字段不能重复
主键约束(primary key) :约束的字段既不能为NULL,也不能重复(简称PK)
外键约束(foreign key) : 。。。。。。。。。。。。。。(简称FK)
检查约束(check) :注意Oracle数据库有check约束,但是mysql没有,目前mysql不支持该约束。

32、非空约束 not null
创建表的时候,在数据类型后面加上 not null ,这样插入数据时,这个字段名必须赋值

33、唯一性约束(unique)
唯一约束修饰的字段具有唯一性,不能重复,但可以为NULL(NULL和NULL不一样,不能划等号)

   在数据类型后面加上 unique ,这样插入数据时,这个字段的数据不能出现相同的
    create table t_user(
                  id int,
                  usercode varchar(255)  unique,             //列级约束
                  username varchar(255) 
    );

    给多个字段联合添加unique:
     create table t_user(
                  id int,
                  usercode varchar(255)  ,
                  username varchar(255) 
                  unique(usercode , usetname)     //这两个字段的联合值  不能重复!!!!     表级约束
    );

34、主键约束 primary key 列级约束
create table t_user(
id int,
usercode varchar(255) primary key , //这个字段的数据不能为NULL 也不能重复 usercode:主键字段 插入的值:主键值
usename varchar(255)
);

                  表的设计三范式中有要求,第一范式要求任何一张表都应该有主键
                主键的作用:主键值是这行记录在这个表中的唯一标识(像身份证一样)

     主键的分类:
                 根据主键字段的字段数量来划分:
                                 单一主键:(推荐、常用)
                                 复合主键(多个字段联合起来添加一个主键约束)   (不建议使用)
                 根据主键性质来划分:
                                 自然主键:主键值最好就是一个和业务没有任何关系的自然数   (推荐)
                                 业务主键:主键值和系统业务挂钩,如:拿着银行卡卡号做主键(不建议)
                                                   最好不要拿着业务挂钩的字段作为主键,因为以后的业务一旦发生改变时,主键值可能也需要随着发生变化
                                                 但是有的时候没办法变化,因为变化可能会导致主键值重复           


             一张表的主键约束只能有一个(重点!!!)

       使用表级约束定义主键:
                   create table t_user(
                  id int,
                  usercode varchar(255)  ,
                  usename varchar(255) 
                  primary key(  id)
    );

         复合主键:(不建议使用)
                    create table t_user(
                  id int,
                  usercode varchar(255)  ,
                  usename varchar(255) 
      primary key(id,usetcode)    
);

         mysql提供主键自增:auto increment(重要)
         create table t_user(
                  id int   primary key auto increment ,  //id字段自动维护一个自增的数字,从1开始,递增加1
                  usercode varchar(255) ,
                  usename varchar(255) 
    );
                  Oracle 中也提供了自增机制:序列对象	(sequence)

35、外键约束 : foreign key
外键字段: 添加有外键约束的字段
外键值:外键字段中每一个值

                t_class 班级表                                                                           t_student 学生表
 cno(pk)                         cname                                                   sno(pk)                            sname               classno(添加外键约束fk)

  101                              上海1班                                                          1                                   s1                  101
  102                              北京 2班                                                         2                                   s2                   102
                                                                                                           3                                   s3                   101
                                                                                                           4                                     s4                 102
 t_student中的classno字段引用t_class表中的cno字段,此时t_student表叫做子表。t_class表叫做父表
 删除数据的时候,先删除子表,再删除父表
 添加数据的时候,先添加父表,再添加子表
 先创父,再创子    先删子,再删父

 create table t_class(                               create table t_student (
           cno int,                                           sno   int,
           cname varchar(255),                        sname varchar(255),
            primary key(cno)                              classno int,
                                                                   primary key(sno),
                                                                  foreign key(classno) references t_class(cno)
 );                                                            );

外键值可以为NULL
外键字段引用其他表的字段时,这个字段必须具有唯一性(一般用主键)

36、存储引擎:只有MysqL存在,Oracle叫存储方式
建表时,可以指定存储引擎和字符集,默认引擎是InnoDB 字符集是UTF8
查看当前mysql支持的存储引擎:show engines \G

 常用的:
            MyISAM存储引擎:使用3个文件来代表表   :   
                                                                             格式文件:存储表结构的定义         XXX.frm
          					数据文件:存储表行的内容         XXXX.MYD
				索引文件;存储表上索引	    XXX.MYI
            优点:可被压缩、节省空间、可转换成只读表,提升检索效率            缺点:不支持事物

            InnoDB存储引擎:      
            优点:支持事物、行级锁、外键等,这种引擎安全
            表的结构存储再xxx.frm中  
            数据存储在tavlespace这样的空间中,无法被压缩
             在mysql服务器崩溃后,自动恢复
             支持级联删除和级联更新

             MEMORY存储引擎:
                             缺点:不支持事物,数据容易丢失,因为所有数据和索引存储在内存中
                            优点:查询速度最快
                             断电数据就没了

37、事物(Transaction)
事物:一个事物是一个完整的业务逻辑单元,不可再分
比如:银行账户转账,从A账户向B账户转账10000,需执行两条update语句
update t_act set balance =balance-10000 where actno=‘act-001’;
update t_act set balance =balance+10000 where actno=‘act-002’;
以上语句必须同时成功或同时失败,不能一个成功一个失败
要想以上两条DML语句同时成功或同时失败,需要使用数据库的‘事物’

      和事物相关的语句只有DML(insert delete update)
      因为事物的存在是为了保证数据的完整性

     如果所有的业务都能使用一条DML语句完成,就不用事物机制了

     事物包括四大特性:ACID
         A:原子性:事务是最小的工作单元,不可再分
         B:一致性:事务必须保证多条DML语句同时成功或者同时失败
         I:隔离性:事务A与事务B之间具有隔离
         D:持久性:最终数据必须持久化到硬盘文件中,事务才算成功结束

  
     事物隔离性存在隔离级别,理论上有4个:           
                          第一级别:读未提交(read uncommitted) :对方事务还没有提交,我们当前事务可以读取到对方未提交的数据
                                          读未提交存在脏读现象:读到了脏的数据

                          第二级别:读已提交(read committed):对方事务提交之后的数据我方可以读取到
                                    缺点:我方不可重复读
                                     解决了脏读现象

                           第三级别:可重复读 (repeatable read) ;读到的一直是最开始的数据
                                      这种隔离级 别解决了不可重读问题
                                      缺点:读取到的数据是幻象

                           第四级别:序列化读/串行化读( serializable)
                                          解决了所有问题
                                              效率低,需要事务排队

                            Oracle数据库默认的隔离级别是:读已提交
                            mysql数据库默认的隔离级别是:可重复读

38、mysql事务默认情况是自动提交:执行任意一条DML语句则提交一次 回滚不了!!!!
start transaction :关闭自动提交(这样可以回滚了) 仅在当前事务有效
commit: 提交
rollback: 回滚到上一次的提交点

39、设置事务的隔离级别:set global transaction isolation level (在后面加上事务级别)
如 set global transaction isolation level read uncommitted;

  查看事务的全局隔离界别:select @@global.tx_isolation;  

40、索引
索引就相当于一本书的目录,通过目录可以快速的找到对应的资源
在数据库方面,查询一张表的时候有两种检索方式
第一种方式;全表扫描
第二种方式:根据索引检索(效率很高)

    索引最根本的原理是:缩小了扫描的范围
                 索引可以提高检索效率,但是不能随意添加索引,因为索引也是数据库种的对象,需要维护,有维护成本
                 比如表中数据经常被修改时,就不适合添加索引,一旦数据修改,索引需要重新排序。
     添加索引是给某一个字段,或则说某些字段添加索引	
   
     select ename,sal from emp where ename='SMITH';
     当ename字段上没有添加索引时候,sql语句会进行全表扫描,扫描ename字段的所有值
       当ename字段添加索引的时候,以上sql语句会根据索引扫描,快速定位

 -------------------------------------------------------------------------
       什么时候考虑添加索引:
                       数据量大、字段很少的DML操作、该字段经常出现在where子句中

        注意:主键和具有unique约束的字段自动会添加索引
                    根据主键查询效率高,尽量根据主键检索

       查看sql语句的执行计划: explain select ename,sal from emp where sal=5000;

±—±------------±------±-----±--------------±-----±--------±-----±-----±------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
±—±------------±------±-----±--------------±-----±--------±-----±-----±------------+
| 1 | SIMPLE | emp | ALL | NULL | NULL | NULL | NULL | 14 | Using where |
±—±------------±------±-----±--------------±-----±--------±-----±-----±------------+

       怎么创建索引: create index 索引名称 on 表名(字段名);
       删除索引对象:drop index 索引名称 on 表名;

       索引底层采用的数据结构:Betree

       索引实现原理:
                   通过B Tree缩小扫描范围,底层索引进行了排序,分区,索引会携带数据在表中的‘物理地址’
                   最终通过索引检索到数据之后,获取到i关联的物理地址,通过物理地址定位 表中的数据,效率
                    是最高的
               select ename from emp where ename = 'SMITH';
               通过索引转换为:
                select ename from emp where 物理地址=0x3;
        

        索引的分类:
                     单一索引:给单个字段添加索引
                      复合索引:给多个字段联合起来添加1个索引
                      主键索引:主键上会自动添加索引
                       唯一索引:有unique约束的字段会自动添加索引
                        .........

         索引什么什么会失效:select ename from emp ename like '%A%';
         模糊查询的时候,第一个通配符使用的是%,这个时候索引是失效的

41、视图(view):同一张表的数据,通过不同的角度去看
创建视图:create view myview as select empno,ename from emp;
删除视图:drop view myview;
只有DQL语句才能以视图对象的方式创建出来

  对视图进行增删改查,会影响到原表数据(通过视图影响原表数据,不是直接操作原表)
  
   视图的作用:可以隐藏表的实现细节,保密级别较高的系统,数据库只提供对外的视图,java程序员只对视图对象进行CRUD 

42、数据库设计三范式:
按照这个三范式设计的表不会出现数据冗余

 第一范式:任何一张表都应该有主键,并且每一个字段原子性不可再分
 第二范式:建立在第一范式的基础上,所有非主键字段完全依赖主键,不能产生部分依赖
     多对多?三张表,关系表两个外键
第三范式:建立在第二范式基础之上,所有非主键字段直接依赖主键,不能产生传递依赖
    一对多? 两张表,多的表加外键

提醒:在实际开发中,以满足客户的需求为主,有的时候会拿冗余换执行速度

猜你喜欢

转载自blog.csdn.net/weixin_43005654/article/details/123249793