新市网站建设,银锭网那个网站做的 好,电商网站设计素材,江苏南京最新通告文章目录day02课堂笔记1、把查询结果去除重复记录【distinct】10、连接查询10.1、什么是连接查询#xff1f;10.2、连接查询的分类#xff1f;10.3、当两张表进行连接查询时#xff0c;没有任何条件的限制会发生什么现象#xff1f;10.4、怎么避免笛卡尔积现象#xff1f;…
文章目录day02课堂笔记1、把查询结果去除重复记录【distinct】10、连接查询10.1、什么是连接查询10.2、连接查询的分类10.3、当两张表进行连接查询时没有任何条件的限制会发生什么现象10.4、怎么避免笛卡尔积现象10.5、内连接之等值连接。10.6、内连接之非等值连接10.7、内连接之自连接10.8、外连接10.9、三张表四张表怎么连接11、子查询11.1、什么是子查询11.2、子查询都可以出现在哪里呢11.3、where子句中的子查询11.4、from子句中的子查询11.5、select后面出现的子查询这个内容不需要掌握了解即可12、union合并查询结果集13、limit非常重要13.1、limit作用将查询结果集的一部分取出来。通常使用在分页查询当中。13.2、limit怎么用呢13.3、注意mysql当中limit在order by之后执行13.4、取出工资排名在[3-5]名的员工13.5、取出工资排名在[5-9]名的员工13.6、分页14、关于DQL语句的大总结15、表15.1、建表的语法格式(建表属于DDL语句DDL包括create drop alter)15.2、关于mysql中的数据类型15.3、创建一个学生表15.4、插入数据insert DML15.5、insert插入日期15.6、date和datetime两个类型的区别15.7、修改updateDML15.8、删除数据 delete DML本文章为学习动力节点的杜老师视频链接如下 https://www.bilibili.com/video/BV1Vy4y1z7EX 源码文档学习资料安装工具[点赞]都已经为大家准备好 链接https://pan.baidu.com/s/1PTbdG-olm8mpEzz-zXe6bw 提取码m0bc day02课堂笔记
1、把查询结果去除重复记录【distinct】
注意原表数据不会被修改只是查询结果去重。
去重需要使用一个关键字distinct
mysql select distinct job from emp;
-----------
| job |
-----------
| CLERK |
| SALESMAN |
| MANAGER |
| ANALYST |
| PRESIDENT |
-----------mysql select ename,distinct job from emp;// 这样编写是错误的语法错误。
// distinct只能出现在所有字段的最前方。
// distinct出现在job,deptno两个字段之前表示两个字段联合起来去重。
mysql select distinct job,deptno from emp;
-------------------
| job | deptno |
-------------------
| CLERK | 20 |
| SALESMAN | 30 |
| MANAGER | 20 |
| MANAGER | 30 |
| MANAGER | 10 |
| ANALYST | 20 |
| PRESIDENT | 10 |
| CLERK | 30 |
| CLERK | 10 |
-------------------统计一下工作岗位的数量 select count(distinct job) from emp;---------------------| count(distinct job) |---------------------| 5 |---------------------10、连接查询
10.1、什么是连接查询
从一张表中单独查询称为单表查询。 emp表和dept表联合起来查询数据从emp表中取员工名字从dept表中取部门名字。 这种跨表查询多张表联合起来查询数据被称为连接查询。
10.2、连接查询的分类
根据语法的年代分类 SQL921992年的时候出现的语法 SQL991999年的时候出现的语法 我们这里重点学习SQL99.(这个过程中简单演示一个SQL92的例子)
根据表连接的方式分类 内连接 等值连接 非等值连接 自连接
外连接 左外连接左连接 右外连接右连接
全连接不讲
10.3、当两张表进行连接查询时没有任何条件的限制会发生什么现象
案例查询每个员工所在部门名称 mysql select ename,deptno from emp;----------------| ename | deptno |----------------| SMITH | 20 || ALLEN | 30 || WARD | 30 || JONES | 20 || MARTIN | 30 || BLAKE | 30 || CLARK | 10 || SCOTT | 20 || KING | 10 || TURNER | 30 || ADAMS | 20 || JAMES | 30 || FORD | 20 || MILLER | 10 |----------------mysql select * from dept;------------------------------| DEPTNO | DNAME | LOC |------------------------------| 10 | ACCOUNTING | NEW YORK || 20 | RESEARCH | DALLAS || 30 | SALES | CHICAGO || 40 | OPERATIONS | BOSTON |------------------------------两张表连接没有任何条件限制
select ename,dname from emp, dept;
--------------------
| ename | dname |
--------------------
| SMITH | ACCOUNTING |
| SMITH | RESEARCH |
| SMITH | SALES |
| SMITH | OPERATIONS |
| ALLEN | ACCOUNTING |
| ALLEN | RESEARCH |
| ALLEN | SALES |
| ALLEN | OPERATIONS |
...
56 rows in set (0.00 sec)14 * 4 56
当两张表进行连接查询没有任何条件限制的时候最终查询结果条数是 两张表条数的乘积这种现象被称为笛卡尔积现象。笛卡尔发现的这是 一个数学现象。
10.4、怎么避免笛卡尔积现象
连接时加条件满足这个条件的记录被筛选出来
select ename,dname
from emp, dept
whereemp.deptno dept.deptno;select emp.ename,dept.dname
from emp, dept
whereemp.deptno dept.deptno;// 表起别名。很重要。效率问题。
select e.ename,d.dname
from emp e, dept d
wheree.deptno d.deptno; //SQL92语法。--------------------
| ename | dname |
--------------------
| CLARK | ACCOUNTING |
| KING | ACCOUNTING |
| MILLER | ACCOUNTING |
| SMITH | RESEARCH |
| JONES | RESEARCH |
| SCOTT | RESEARCH |
| ADAMS | RESEARCH |
| FORD | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| MARTIN | SALES |
| BLAKE | SALES |
| TURNER | SALES |
| JAMES | SALES |
--------------------思考最终查询的结果条数是14条但是匹配的过程中匹配的次数减少了吗 还是56次只不过进行了四选一。次数没有减少。
注意通过笛卡尔积现象得出表的连接次数越多效率越低尽量避免表的 连接次数。
10.5、内连接之等值连接。
案例查询每个员工所在部门名称显示员工名和部门名 emp e和dept d表进行连接。条件是e.deptno d.deptno
SQL92语法
select e.ename,d.dname
fromemp e, dept d
wheree.deptno d.deptno;sql92的缺点结构不清晰表的连接条件和后期进一步筛选的条件都放到了where后面。
SQL99语法
select e.ename,d.dname
fromemp e
joindept d
one.deptno d.deptno;//inner可以省略带着inner可读性更好一眼就能看出来是内连接select e.ename,d.dname
fromemp e
inner joindept d
one.deptno d.deptno; // 条件是等量关系所以被称为等值连接。sql99优点表连接的条件是独立的连接之后如果还需要进一步筛选再往后继续添加where
SQL99语法 select … from a join b on a和b的连接条件 where 筛选条件
10.6、内连接之非等值连接
案例找出每个员工的薪资等级要求显示员工名、薪资、薪资等级
mysql select * from emp; e
----------------------------------------------------------------------
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
----------------------------------------------------------------------
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |…
mysql select * from salgrade; s
---------------------
| GRADE | LOSAL | HISAL |
---------------------
| 1 | 700 | 1200 |
| 2 | 1201 | 1400 |
| 3 | 1401 | 2000 |
| 4 | 2001 | 3000 |
| 5 | 3001 | 9999 |
---------------------select
e.ename, e.sal, s.grade
from
emp e
join
salgrade s
on
e.sal between s.losal and s.hisal; // 条件不是一个等量关系称为非等值连接。select
e.ename, e.sal, s.grade
from
emp e
inner join
salgrade s
on
e.sal between s.losal and s.hisal;------------------------
| ename | sal | grade |
------------------------
| SMITH | 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 |
------------------------10.7、内连接之自连接
案例查询员工的上级领导要求显示员工名和对应的领导名
mysql select empno,ename,mgr from emp;
---------------------
| empno | ename | mgr |
---------------------
| 7369 | SMITH | 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 员工表
---------------------
| empno | ename | mgr |
---------------------
| 7369 | SMITH | 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 b 领导表
---------------------
| empno | ename | mgr |
---------------------
| 7369 | SMITH | 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 |
---------------------select
a.ename as 员工名, b.ename as 领导名
from
emp a
join
emp b
on
a.mgr b.empno; //员工的领导编号 领导的员工编号----------------
| 员工名 | 领导名|
----------------
| SMITH | 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。《内连接》
以上就是内连接中的自连接技巧一张表看做两张表。
10.8、外连接
mysql select * from emp; e
----------------------------------------------------------------------
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
----------------------------------------------------------------------
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
----------------------------------------------------------------------mysql select * from dept; d
------------------------------
| DEPTNO | DNAME | LOC |
------------------------------
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
------------------------------内连接A和B连接AB两张表没有主次关系。平等的。
select
e.ename,d.dname
from
emp e
join
dept d
on
e.deptno d.deptno; //内连接的特点完成能够匹配上这个条件的数据查询出来。--------------------
| ename | dname |
--------------------
| CLARK | ACCOUNTING |
| KING | ACCOUNTING |
| MILLER | ACCOUNTING |
| SMITH | RESEARCH |
| JONES | RESEARCH |
| SCOTT | RESEARCH |
| ADAMS | RESEARCH |
| FORD | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| MARTIN | SALES |
| BLAKE | SALES |
| TURNER | SALES |
| JAMES | SALES |
--------------------外连接右外连接
select
e.ename,d.dname
from
emp e
right join
dept d
on
e.deptno d.deptno;// outer是可以省略的带着可读性强。
select
e.ename,d.dname
from
emp e
right outer join
dept d
on
e.deptno d.deptno;right代表什么表示将join关键字右边的这张表看成主表主要是为了将 这张表的数据全部查询出来捎带着关联查询左边的表。 在外连接当中两张表连接产生了主次关系。
外连接左外连接
select
e.ename,d.dname
from
dept d
left join
emp e
on
e.deptno d.deptno;// outer是可以省略的带着可读性强。
select
e.ename,d.dname
from
dept d
left outer join
emp e
on
e.deptno d.deptno;带有right的是右外连接又叫做右连接。 带有left的是左外连接又叫做左连接。 任何一个右连接都有左连接的写法。 任何一个左连接都有右连接的写法。
--------------------
| ename | dname |
--------------------
| CLARK | ACCOUNTING |
| KING | ACCOUNTING |
| MILLER | ACCOUNTING |
| SMITH | RESEARCH |
| JONES | RESEARCH |
| SCOTT | RESEARCH |
| ADAMS | RESEARCH |
| FORD | RESEARCH |
| ALLEN | SALES |
| WARD | SALES |
| MARTIN | SALES |
| BLAKE | SALES |
| TURNER | SALES |
| JAMES | SALES |
| NULL | OPERATIONS |
--------------------思考外连接的查询结果条数一定是 内连接的查询结果条数 正确。
案例查询每个员工的上级领导要求显示所有员工的名字和领导名
select a.ename as 员工名, b.ename as 领导名
fromemp a
left joinemp b
ona.mgr b.empno; ----------------
| 员工名 | 领导名 |
----------------
| SMITH | 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 |
----------------10.9、三张表四张表怎么连接
语法 select … from a join b on a和b的连接条件 join c on a和c的连接条件 right join d on a和d的连接条件
一条SQL中内连接和外连接可以混合。都可以出现
案例找出每个员工的部门名称以及工资等级 要求显示员工名、部门名、薪资、薪资等级
select e.ename,e.sal,d.dname,s.grade
fromemp e
joindept d
on e.deptno d.deptno
joinsalgrade s
one.sal between s.losal and s.hisal;------------------------------------
| ename | sal | dname | grade |
------------------------------------
| SMITH | 800.00 | RESEARCH | 1 |
| ALLEN | 1600.00 | SALES | 3 |
| WARD | 1250.00 | SALES | 2 |
| JONES | 2975.00 | RESEARCH | 4 |
| MARTIN | 1250.00 | SALES | 2 |
| BLAKE | 2850.00 | SALES | 4 |
| CLARK | 2450.00 | ACCOUNTING | 4 |
| SCOTT | 3000.00 | RESEARCH | 4 |
| KING | 5000.00 | ACCOUNTING | 5 |
| TURNER | 1500.00 | SALES | 3 |
| ADAMS | 1100.00 | RESEARCH | 1 |
| JAMES | 950.00 | SALES | 1 |
| FORD | 3000.00 | RESEARCH | 4 |
| MILLER | 1300.00 | ACCOUNTING | 2 |
------------------------------------案例找出每个员工的部门名称以及工资等级还有上级领导 要求显示员工名、领导名、部门名、薪资、薪资等级
select e.ename,e.sal,d.dname,s.grade,l.ename
fromemp e
joindept d
on e.deptno d.deptno
joinsalgrade s
one.sal between s.losal and s.hisal
left joinemp l
one.mgr l.empno;-------------------------------------------
| ename | sal | dname | grade | ename |
-------------------------------------------
| SMITH | 800.00 | RESEARCH | 1 | FORD |
| ALLEN | 1600.00 | SALES | 3 | BLAKE |
| WARD | 1250.00 | SALES | 2 | BLAKE |
| JONES | 2975.00 | RESEARCH | 4 | KING |
| MARTIN | 1250.00 | SALES | 2 | BLAKE |
| BLAKE | 2850.00 | SALES | 4 | KING |
| CLARK | 2450.00 | ACCOUNTING | 4 | KING |
| SCOTT | 3000.00 | RESEARCH | 4 | JONES |
| KING | 5000.00 | ACCOUNTING | 5 | NULL |
| TURNER | 1500.00 | SALES | 3 | BLAKE |
| ADAMS | 1100.00 | RESEARCH | 1 | SCOTT |
| JAMES | 950.00 | SALES | 1 | BLAKE |
| FORD | 3000.00 | RESEARCH | 4 | JONES |
| MILLER | 1300.00 | ACCOUNTING | 2 | CLARK |
-------------------------------------------11、子查询
11.1、什么是子查询
select语句中嵌套select语句被嵌套的select语句称为子查询。
11.2、子查询都可以出现在哪里呢
select …(select). from …(select). where …(select).
11.3、where子句中的子查询
案例找出比最低工资高的员工姓名和工资 select ename,salfromemp wheresal min(sal);ERROR 1111 (HY000): Invalid use of group functionwhere子句中不能直接使用分组函数。
实现思路 第一步查询最低工资是多少
select min(sal) from emp;----------| min(sal) |----------| 800.00 |---------- 第二步找出800的m
select ename,sal from emp where sal 800; 第三步合并
select ename,sal from emp where sal (select min(sal) from emp);
-----------------
| ename | sal |
-----------------
| ALLEN | 1600.00 |
| WARD | 1250.00 |
| JONES | 2975.00 |
| MARTIN | 1250.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| SCOTT | 3000.00 |
| KING | 5000.00 |
| TURNER | 1500.00 |
| ADAMS | 1100.00 |
| JAMES | 950.00 |
| FORD | 3000.00 |
| MILLER | 1300.00 |
-----------------11.4、from子句中的子查询
注意from后面的子查询可以将子查询的查询结果当做一张临时表。技巧
案例找出每个岗位的平均工资的薪资等级。
第一步找出每个岗位的平均工资按照岗位分组求平均值 select job,avg(sal) from emp group by job;------------------------| job | avgsal |------------------------| ANALYST | 3000.000000 || CLERK | 1037.500000 || MANAGER | 2758.333333 || PRESIDENT | 5000.000000 || SALESMAN | 1400.000000 |------------------------t表第二步克服心理障碍把以上的查询结果就当做一张真实存在的表t。
mysql select * from salgrade; s表
---------------------
| GRADE | LOSAL | HISAL |
---------------------
| 1 | 700 | 1200 |
| 2 | 1201 | 1400 |
| 3 | 1401 | 2000 |
| 4 | 2001 | 3000 |
| 5 | 3001 | 9999 |
---------------------t表和s表进行表连接条件t表avg(sal) between s.losal and s.hisal;
select t.*, s.grade
from(select job,avg(sal) as avgsal from emp group by job) t
joinsalgrade s
ont.avgsal between s.losal and s.hisal;-------------------------------
| job | avgsal | grade |
-------------------------------
| CLERK | 1037.500000 | 1 |
| SALESMAN | 1400.000000 | 2 |
| ANALYST | 3000.000000 | 4 |
| MANAGER | 2758.333333 | 4 |
| PRESIDENT | 5000.000000 | 5 |
-------------------------------11.5、select后面出现的子查询这个内容不需要掌握了解即可
案例找出每个员工的部门名称要求显示员工名部门名
select e.ename,e.deptno,(select d.dname from dept d where e.deptno d.deptno) as dname
from emp e;
----------------------------
| ename | deptno | dname |
----------------------------
| SMITH | 20 | RESEARCH |
| ALLEN | 30 | SALES |
| WARD | 30 | SALES |
| JONES | 20 | RESEARCH |
| MARTIN | 30 | SALES |
| BLAKE | 30 | SALES |
| CLARK | 10 | ACCOUNTING |
| SCOTT | 20 | RESEARCH |
| KING | 10 | ACCOUNTING |
| TURNER | 30 | SALES |
| ADAMS | 20 | RESEARCH |
| JAMES | 30 | SALES |
| FORD | 20 | RESEARCH |
| MILLER | 10 | ACCOUNTING |
----------------------------//错误ERROR 1242 (21000): Subquery returns more than 1 rowselect e.ename,e.deptno,(select dname from dept) as dname
fromemp e;注意对于select后面的子查询来说这个子查询只能一次返回1条结果 多于1条就报错了。
12、union合并查询结果集
案例查询工作岗位是MANAGER和SALESMAN的员工
select ename,job from emp where job MANAGER or job SALESMAN;
select ename,job from emp where job in(MANAGER,SALESMAN);
------------------
| ename | job |
------------------
| ALLEN | SALESMAN |
| WARD | SALESMAN |
| JONES | MANAGER |
| MARTIN | SALESMAN |
| BLAKE | MANAGER |
| CLARK | MANAGER |
| TURNER | SALESMAN |
------------------select ename,job from emp where job MANAGER
union
select ename,job from emp where job SALESMAN;------------------
| ename | job |
------------------
| JONES | MANAGER |
| BLAKE | MANAGER |
| CLARK | MANAGER |
| ALLEN | SALESMAN |
| WARD | SALESMAN |
| MARTIN | SALESMAN |
| TURNER | SALESMAN |
------------------union的效率要高一些。对于表连接来说每连接一次新表 则匹配的次数满足笛卡尔积成倍的翻。。。 但是union可以减少匹配的次数。在减少匹配次数的情况下 还可以完成两个结果集的拼接。
a 连接 b 连接 c a 10条记录 b 10条记录 c 10条记录 匹配次数是1000
a 连接 b一个结果10 * 10 -- 100次 a 连接 c一个结果10 * 10 -- 100次 使用union的话是100次 100次 200次。union把乘法变成了加法运算
union在使用的时候有注意事项吗
//错误的union在进行结果集合并的时候要求两个结果集的列数相同。
select ename,job from emp where job MANAGER
union
select ename from emp where job SALESMAN;// MYSQL可以oracle语法严格 不可以报错。要求结果集合并时列和列的数据类型也要一致。
select ename,job from emp where job MANAGER
union
select ename,sal from emp where job SALESMAN;
-----------------
| ename | job |
-----------------
| JONES | MANAGER |
| BLAKE | MANAGER |
| CLARK | MANAGER |
| ALLEN | 1600 |
| WARD | 1250 |
| MARTIN | 1250 |
| TURNER | 1500 |
-----------------13、limit非常重要
13.1、limit作用将查询结果集的一部分取出来。通常使用在分页查询当中。
百度默认一页显示10条记录。 分页的作用是为了提高用户的体验因为一次全部都查出来用户体验差。 可以一页一页翻页看。
13.2、limit怎么用呢
完整用法limit startIndex, length startIndex是起始下标length是长度。 起始下标从0开始。
缺省用法limit 5; 这是取前5.
按照薪资降序取出排名在前5名的员工
select ename,sal
fromemp
order by sal desc
limit 5; //取前5select ename,sal
fromemp
order by sal desc
limit 0,5;----------------
| ename | sal |
----------------
| KING | 5000.00 |
| SCOTT | 3000.00 |
| FORD | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
----------------13.3、注意mysql当中limit在order by之后执行
13.4、取出工资排名在[3-5]名的员工
select ename,sal
fromemp
order bysal desc
limit2, 3;2表示起始位置从下标2开始就是第三条记录。
3表示长度。----------------
| ename | sal |
----------------
| FORD | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
----------------13.5、取出工资排名在[5-9]名的员工
select ename,sal
fromemp
order by sal desc
limit4, 5;-----------------
| ename | sal |
-----------------
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| ALLEN | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
-----------------13.6、分页
每页显示3条记录 第1页limit 0,3 [0 1 2] 第2页limit 3,3 [3 4 5] 第3页limit 6,3 [6 7 8] 第4页limit 9,3 [9 10 11]
每页显示pageSize条记录 第pageNo页limit (pageNo - 1) * pageSize , pageSize
public static void main(String[] args){// 用户提交过来一个页码以及每页显示的记录条数int pageNo 5; //第5页int pageSize 10; //每页显示10条int startIndex (pageNo - 1) * pageSize;String sql select ...limit startIndex , pageSize;}记公式 limit (pageNo-1)*pageSize , pageSize
14、关于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…
15、表
15.1、建表的语法格式(建表属于DDL语句DDL包括create drop alter)
create table 表名(字段名1 数据类型, 字段名2 数据类型, 字段名3 数据类型);
create table 表名(字段名1 数据类型, 字段名2 数据类型, 字段名3 数据类型
);表名建议以t_ 或者 tbl_开始可读性强。见名知意。 字段名见名知意。 表名和字段名都属于标识符。
15.2、关于mysql中的数据类型
很多数据类型我们只需要掌握一些常见的数据类型即可。
varchar(最长255) 可变长度的字符串 比较智能节省空间。 会根据实际的数据长度动态分配空间。
优点节省空间 缺点需要动态分配空间速度慢。
char(最长255) 定长字符串 不管实际的数据长度是多少。 分配固定长度的空间去存储数据。 使用不恰当的时候可能会导致空间的浪费。
优点不需要动态分配空间速度快。 缺点使用不当可能会导致空间的浪费。
varchar和char我们应该怎么选择 性别字段你选什么因为性别是固定长度的字符串所以选择char。 姓名字段你选什么每一个人的名字长度不同所以选择varchar。
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流才行。
t_movie 电影表专门存储电影信息的
编号 名字 故事情节 上映日期 时长 海报 类型
no(bigint) name(varchar) history(clob) playtime(date) time(double) image(blob) type(char)
10000 哪吒 … 2019-10-11 2.5 … ‘1’ 10001 林正英之娘娘 … 2019-11-11 1.5 … ‘2’ …
15.3、创建一个学生表
学号、姓名、年龄、性别、邮箱地址
create table t_student(no int,name varchar(32),sex char(1),age int(3),email varchar(255)
);删除表 drop table t_student; // 当这张表不存在的时候会报错
// 如果这张表存在的话删除
drop table if exists t_student;15.4、插入数据insert DML
语法格式 insert into 表名(字段名1,字段名2,字段名3…) values(值1,值2,值3);
注意字段名和值要一一对应。什么是一一对应 数量要对应。数据类型要对应。
insert into t_student(no,name,sex,age,email) values(1,zhangsan,m,20,zhangsan123.com);
insert into t_student(email,name,sex,age,no) values(lisi123.com,lisi,f,20,2);insert into t_student(no) values(3);----------------------------------------------
| no | name | sex | age | email |
----------------------------------------------
| 1 | zhangsan | m | 20 | zhangsan123.com |
| 2 | lisi | f | 20 | lisi123.com |
| 3 | NULL | NULL | NULL | NULL |
----------------------------------------------
insert into t_student(name) values(wangwu);
----------------------------------------------
| no | name | sex | age | email |
----------------------------------------------
| 1 | zhangsan | m | 20 | zhangsan123.com |
| 2 | lisi | f | 20 | lisi123.com |
| 3 | NULL | NULL | NULL | NULL |
| NULL | wangwu | NULL | NULL | NULL |
----------------------------------------------注意insert语句但凡是执行成功了那么必然会多一条记录。 没有给其它字段指定值的话默认值是NULL。
drop table if exists t_student;
create table t_student(no int,name varchar(32),sex char(1) default m,age int(3),email varchar(255)
);------------------------------------------------
| Field | Type | Null | Key | Default | Extra |
------------------------------------------------
| no | int(11) | YES | | NULL | |
| name | varchar(32) | YES | | NULL | |
| sex | char(1) | YES | | m | |
| age | int(3) | YES | | NULL | |
| email | varchar(255) | YES | | NULL | |
------------------------------------------------insert into t_student(no) values(1);
mysql select * from t_student;
-------------------------------
| no | name | sex | age | email |
-------------------------------
| 1 | NULL | m | NULL | NULL |
-------------------------------insert语句中的“字段名”可以省略吗可以
insert into t_student values(2); //错误的// 注意前面的字段名省略的话等于都写上了所以值也要都写上
insert into t_student values(2, lisi, f, 20, lisi123.com);
--------------------------------------
| no | name | sex | age | email |
--------------------------------------
| 1 | NULL | m | NULL | NULL |
| 2 | lisi | f | 20 | lisi123.com |
--------------------------------------15.5、insert插入日期
数字格式化format
select ename,sal from emp;-----------------| ename | sal |-----------------| SMITH | 800.00 || ALLEN | 1600.00 || WARD | 1250.00 || JONES | 2975.00 || MARTIN | 1250.00 || BLAKE | 2850.00 || CLARK | 2450.00 || SCOTT | 3000.00 || KING | 5000.00 || TURNER | 1500.00 || ADAMS | 1100.00 || JAMES | 950.00 || FORD | 3000.00 || MILLER | 1300.00 |-----------------格式化数字format(数字, ‘格式’)
select ename,format(sal, $999,999) as sal from emp;---------------| ename | sal |---------------| SMITH | 800 || ALLEN | 1,600 || WARD | 1,250 || JONES | 2,975 || MARTIN | 1,250 || BLAKE | 2,850 || CLARK | 2,450 || SCOTT | 3,000 || KING | 5,000 || TURNER | 1,500 || ADAMS | 1,100 || JAMES | 950 || FORD | 3,000 || MILLER | 1,300 |---------------str_to_date将字符串varchar类型转换成date类型 date_format将date类型转换成具有一定格式的varchar字符串类型。
drop table if exists t_user;
create table t_user(id int,name varchar(32),birth date // 生日也可以使用date日期类型
);create table t_user(id int,name varchar(32),birth char(10) // 生日可以使用字符串没问题。
);生日1990-10-11 10个字符
注意数据库中的有一条命名规范 所有的标识符都是全部小写单词和单词之间使用下划线进行衔接。
mysql desc t_user;
-----------------------------------------------
| Field | Type | Null | Key | Default | Extra |
-----------------------------------------------
| id | int(11) | YES | | NULL | |
| name | varchar(32) | YES | | NULL | |
| birth | date | YES | | NULL | |
-----------------------------------------------插入数据
insert into t_user(id,name,birth) values(1, zhangsan, 01-10-1990) // 1990年10月1日 出问题了原因是类型不匹配。数据库birth是date类型这里给了一个字符串varchar。
怎么办可以使用str_to_date函数进行类型转换。 str_to_date函数可以将字符串转换成日期类型date 语法格式 str_to_date(‘字符串日期’, ‘日期格式’)
mysql的日期格式 %Y 年 %m 月 %d 日 %h 时 %i 分 %s 秒
insert into t_user(id,name,birth) values(1, zhangsan, str_to_date(01-10-1990,%d-%m-%Y));str_to_date函数可以把字符串varchar转换成日期date类型数据 通常使用在插入insert方面因为插入的时候需要一个日期类型的数据 需要通过该函数将字符串转换成date。
好消息 如果你提供的日期字符串是这个格式str_to_date函数就不需要了 %Y-%m-%d insert into t_user(id,name,birth) values(2, lisi, 1990-10-01);查询的时候可以以某个特定的日期格式展示吗 date_format 这个函数可以将日期类型转换成特定格式的字符串。
select id,name,date_format(birth, %m/%d/%Y) as birth from t_user;
----------------------------
| id | name | birth |
----------------------------
| 1 | zhangsan | 10/01/1990 |
| 2 | lisi | 10/01/1990 |
----------------------------date_format函数怎么用 date_format(日期类型数据, ‘日期格式’) 这个函数通常使用在查询日期方面。设置展示的日期格式。
mysql select id,name,birth from t_user;
----------------------------
| id | name | birth |
----------------------------
| 1 | zhangsan | 1990-10-01 |
| 2 | lisi | 1990-10-01 |
----------------------------以上的SQL语句实际上是进行了默认的日期格式化 自动将数据库中的date类型转换成varchar类型。 并且采用的格式是mysql默认的日期格式’%Y-%m-%d’
select id,name,date_format(birth,%Y/%m/%d) as birth from t_user;java中的日期格式 yyyy-MM-dd HH:mm:ss SSS
15.6、date和datetime两个类型的区别
date是短日期只包括年月日信息。 datetime是长日期包括年月日时分秒信息。
drop table if exists t_user;
create table t_user(id int,name varchar(32),birth date,create_time datetime
);id是整数 name是字符串 birth是短日期 create_time是这条记录的创建时间长日期类型
mysql短日期默认格式%Y-%m-%d mysql长日期默认格式%Y-%m-%d %h:%i:%s
insert into t_user(id,name,birth,create_time) values(1,zhangsan,1990-10-01,2020-03-18 15:49:50);在mysql当中怎么获取系统当前时间 now() 函数并且获取的时间带有时分秒信息是datetime类型的。
insert into t_user(id,name,birth,create_time) values(2,lisi,1991-10-01,now());15.7、修改updateDML
语法格式 update 表名 set 字段名1值1,字段名2值2,字段名3值3… where 条件;
注意没有条件限制会导致所有数据全部更新。
update t_user set name jack, birth 2000-10-11 where id 2;
-------------------------------------------------
| id | name | birth | create_time |
-------------------------------------------------
| 1 | zhangsan | 1990-10-01 | 2020-03-18 15:49:50 |
| 2 | jack | 2000-10-11 | 2020-03-18 15:51:23 |
-------------------------------------------------update t_user set name jack, birth 2000-10-11, create_time now() where id 2;更新所有 update t_user set name abc;15.8、删除数据 delete DML
语法格式 delete from 表名 where 条件;
注意没有条件整张表的数据会全部删除
delete from t_user where id 2;
insert into t_user(id) values(2);
delete from t_user; // 删除所有
1、查询每一个员工的所在部门名称要求显示员工名和部门名。
mysql select * from emp;
----------------------------------------------------------------------
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
----------------------------------------------------------------------
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
----------------------------------------------------------------------mysql select * from dept;
------------------------------
| DEPTNO | DNAME | LOC |
------------------------------
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
------------------------------从emp表中取ename从dept表中取dname没有条件限制最终查询结果是
ENAME DNAME
SMITH ACCOUNTING 无效记录 SMITH RESEARCH 有效记录 SMITH SALES 无效记录 SMITH OPERATIONS 无效记录
ALLEN ACCOUNTING ALLEN RESEARCH ALLEN SALES ALLEN OPERATIONS
… 14*4条记录。
【加个条件是为了达到4选1也是为了筛查数据的有效记录】
select e.ename,d.dname
fromemp e
joindept d
one.deptno d.deptno;注意加条件只是为了避免笛卡尔积现象只是为了查询出有效的组合记录。匹配的次数一次 都没有少还是56次和效率无关。2、insert语句可以一次插入多条记录吗【掌握】 可以的
mysql desc t_user;-----------------------------------------------------| Field | Type | Null | Key | Default | Extra |-----------------------------------------------------| id | int(11) | YES | | NULL | || name | varchar(32) | YES | | NULL | || birth | date | YES | | NULL | || create_time | datetime | YES | | NULL | |-----------------------------------------------------一次可以插入多条记录 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 表名(字段名1,字段名2) values(),(),(),()…;
mysql select * from t_user;
-----------------------------------------------
| id | name | birth | create_time |
-----------------------------------------------
| 1 | zs | 1980-10-11 | 2020-03-19 09:37:01 |
| 2 | lisi | 1981-10-11 | 2020-03-19 09:37:01 |
| 3 | wangwu | 1982-10-11 | 2020-03-19 09:37:01 |
-----------------------------------------------3、快速创建表【了解内容】
mysql create table emp2 as select * from emp;原理 将一个查询结果当做一张表新建 这个可以完成表的快速复制 表创建出来同时表中的数据也存在了
create table mytable as select empno,ename from emp where job MANAGER;4、将查询结果插入到一张表当中insert相关的【了解内容】
create table dept_bak as select * from dept;mysql select * from dept_bak;------------------------------| DEPTNO | DNAME | LOC |------------------------------| 10 | ACCOUNTING | NEW YORK || 20 | RESEARCH | DALLAS || 30 | SALES | CHICAGO || 40 | OPERATIONS | BOSTON |------------------------------//很少用查的结果刚好符合表的结构才能查
insert into dept_bak select * from dept; mysql select * from dept_bak;
------------------------------
| DEPTNO | DNAME | LOC |
------------------------------
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
------------------------------5、快速删除表中的数据【truncate比较重要必须掌握】
//删除dept_bak表中的数据 //这种删除数据的方式比较慢。
delete from dept_bak;
mysql select * from dept_bak;
Empty set (0.00 sec)delete语句删除数据的原理delete属于DML语句 表中的数据被删除了但是这个数据在硬盘上的真实存储空间不会被释放 这种删除缺点是删除效率比较低。 这种删除优点是支持回滚后悔了可以再恢复数据
truncate语句删除数据的原理 这种删除效率比较高表被一次截断物理删除。 这种删除缺点不支持回滚。 这种删除优点快速。
用法truncate table 表名; 这种操作属于DDL操作。
大表非常大上亿条记录 删除的时候使用delete也许需要执行1个小时才能删除完效率较低。 可以选择使用truncate删除表中的数据。只需要不到1秒钟的时间就删除结束。效率较高。 但是使用truncate之前必须仔细询问客户是否真的要删除并警告删除之后不可恢复
truncate是删除表中的数据表还在 删除表操作drop table 表名; // 这不是删除表中的数据而是把表删除。
6、对表结构的增删改【非重点】
什么是对表结构的修改 添加一个字段删除一个字段修改一个字段
对表结构的修改需要使用alter属于DDL语句
DDL包括create drop alter
第一在实际的开发中需求一旦确定之后表一旦设计好之后很少的 进行表结构的修改。因为开发进行中的时候修改表结构成本比较高。 修改表的结构对应的java代码就需要进行大量的修改。成本是比较高的。 这个责任应该由设计人员来承担
第二由于修改表结构的操作很少所以我们不需要掌握如果有一天 真的要修改表结构你可以使用工具
修改表结构的操作是不需要写到java程序中的。实际上也不是java程序员的范畴。
7、约束非常重要*****
7.1、什么是约束 约束对应的英语单词constraint 在创建表的时候我们可以给表中的字段加上一些约束来保证这个表中数据的 完整性、有效性
约束的作用就是为了保证表中的数据有效
7.2、约束包括哪些 非空约束not null 唯一性约束: unique 主键约束: primary key简称PK 外键约束foreign key简称FK 检查约束checkmysql不支持oracle支持
我们这里重点学习四个约束 not null unique primary key foreign key
7.3、非空约束not null
非空约束not null约束的字段不能为NULL。
drop table if exists t_vip;
create table t_vip(id int,name varchar(255) not null // not null只有列级约束没有表级约束
);
insert into t_vip(id,name) values(1,zhangsan);
insert into t_vip(id,name) values(2,lisi);insert into t_vip(id) values(3);
ERROR 1364 (HY000): Field name doesnt have a default value小插曲 xxxx.sql这种文件被称为sql脚本文件。 sql脚本文件中编写了大量的sql语句。 我们执行sql脚本文件的时候该文件中所有的sql语句会全部执行 批量的执行SQL语句可以使用sql脚本文件。 在mysql当中怎么执行sql脚本呢 mysql source D:\course\03-MySQL\document\vip.sql
你在实际的工作中第一天到了公司项目经理会给你一个xxx.sql文件 你执行这个脚本文件你电脑上的数据库数据就有了
7.4、唯一性约束: unique
唯一性约束unique约束的字段不能重复但是可以为NULL。
drop table if exists t_vip;
create table t_vip(id int,name varchar(255) unique,email varchar(255)
);
insert into t_vip(id,name,email) values(1,zhangsan,zhangsan123.com);
insert into t_vip(id,name,email) values(2,lisi,lisi123.com);
insert into t_vip(id,name,email) values(3,wangwu,wangwu123.com);
select * from t_vip;insert into t_vip(id,name,email) values(4,wangwu,wangwusina.com);
ERROR 1062 (23000): Duplicate entry wangwu for key nameinsert into t_vip(id) values(4);
insert into t_vip(id) values(5);
----------------------------------
| id | name | email |
----------------------------------
| 1 | zhangsan | zhangsan123.com |
| 2 | lisi | lisi123.com |
| 3 | wangwu | wangwu123.com |
| 4 | NULL | NULL |
| 5 | NULL | NULL |
----------------------------------name字段虽然被unique约束了但是可以为NULL。
新需求name和email两个字段联合起来具有唯一性 drop table if exists t_vip;create table t_vip(id int,name varchar(255) unique, // 约束直接添加到列后面的叫做列级约束。email varchar(255) unique); 这张表这样创建是不符合我以上“新需求”的。 这样创建表示name具有唯一性email具有唯一性。各自唯一。
以下这样的数据是符合我“新需求”的。 但如果采用以上方式创建表的话肯定创建失败因为’zhangsan’和’zhangsan’重复了。
insert into t_vip(id,name,email) values(1,zhangsan,zhangsan123.com);
insert into t_vip(id,name,email) values(2,zhangsan,zhangsansina.com); 怎么创建这样的表才能符合新需求呢
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,email) values(1,zhangsan,zhangsan123.com);insert into t_vip(id,name,email) values(2,zhangsan,zhangsansina.com);select * from t_vip; name和email两个字段联合起来唯一
insert into t_vip(id,name,email) values(3,zhangsan,zhangsansina.com);
ERROR 1062 (23000): Duplicate entry zhangsan-zhangsansina.com for key name 什么时候使用表级约束呢 需要给多个字段联合起来添加某一个约束的时候需要使用表级约束。
unique 和not null可以联合吗
drop table if exists t_vip;create table t_vip(id int,name varchar(255) not null unique); mysql desc t_vip;
------------------------------------------------
| Field | Type | Null | Key | Default | Extra |
------------------------------------------------
| id | int(11) | YES | | NULL | |
| name | varchar(255) | NO | PRI | NULL | |
------------------------------------------------ 在mysql当中如果一个字段同时被not null和unique约束的话 该字段自动变成主键字段。注意oracle中不一样
insert into t_vip(id,name) values(1,zhangsan);insert into t_vip(id,name) values(2,zhangsan); //错误了name不能重复insert into t_vip(id) values(2); //错误了name不能为NULL。7.5、主键约束primary key简称PK*****
单一主键 复合主键 表级约束 列级约束
主键约束的相关术语 主键约束就是一种约束。PK 主键字段该字段上添加了主键约束这样的字段叫做主键字段ID 主键值主键字段中的每一个值都叫做主键值。1
什么是主键有啥用 主键值是每一行记录的唯一标识。 主键值是每一行记录的身份证号
记住任何一张表都应该有主键没有主键表无效
主键的特征not null unique主键值不能是NULL同时也不能重复
怎么给一张表添加主键约束呢
drop table if exists t_vip;// 1个字段做主键叫做单一主键create table t_vip(id int primary key, //列级约束name varchar(255));
insert into t_vip(id,name) values(1,zhangsan);
insert into t_vip(id,name) values(2,lisi);//错误主键ID不能重复
insert into t_vip(id,name) values(2,wangwu);
ERROR 1062 (23000): Duplicate entry 2 for key PRIMARY//错误主键ID不能为NULL
insert into t_vip(name) values(zhaoliu);
ERROR 1364 (HY000): Field id doesnt have a default value可以这样添加主键吗使用表级约束
drop table if exists t_vip;create table t_vip(id int,name varchar(255),primary key(id) // 表级约束);
insert into t_vip(id,name) values(1,zhangsan);//错误
insert into t_vip(id,name) values(1,lisi);
ERROR 1062 (23000): Duplicate entry 1 for key PRIMARY表级约束主要是给多个字段联合起来添加约束
drop table if exists t_vip;// id和name联合起来做主键复合主键create table t_vip(id int,name varchar(255),email varchar(255),primary key(id,name));
insert into t_vip(id,name,email) values(1,zhangsan,zhangsan123.com);
insert into t_vip(id,name,email) values(1,lisi,lisi123.com);//错误不能重复
insert into t_vip(id,name,email) values(1,lisi,lisi123.com);
ERROR 1062 (23000): Duplicate entry 1-lisi for key PRIMARY 在实际开发中不建议使用复合主键。建议使用单一主键 因为主键值存在的意义就是这行记录的身份证号只要意义达到即可单一主键可以做到。 复合主键比较复杂不建议使用
一个表中主键约束能加两个吗
drop table if exists t_vip;create table t_vip(id int primary key,name varchar(255) primary key);
ERROR 1068 (42000): Multiple primary key defined 结论一张表主键约束只能添加1个。主键只能有1个。
主键值建议使用 int bigint char 等类型。
不建议使用varchar来做主键。主键值一般都是数字一般都是定长的
主键除了单一主键和复合主键之外还可以这样进行分类 自然主键主键值是一个自然数和业务没关系。 业务主键主键值和业务紧密关联例如拿银行卡账号做主键值。这就是业务主键
在实际开发中使用业务主键多还是使用自然主键多一些 自然主键使用比较多因为主键只要做到不重复就行不需要有意义。最好是一个自然数和任何数据都没有关系 业务主键不好因为主键一旦和业务挂钩那么当业务发生变动的时候 可能会影响到主键值所以业务主键不建议使用。尽量使用自然主键。
在mysql当中有一种机制可以帮助我们自动维护一个主键值 主键值可以采用自增生成
drop table if exists t_vip;create table t_vip(id int primary key auto_increment, / /auto_increment表示自增从1开始以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);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);select * from t_vip; --------------
| id | name |
--------------
| 1 | zhangsan |
| 2 | zhangsan |
| 3 | zhangsan |
| 4 | zhangsan |
| 5 | zhangsan |
| 6 | zhangsan |
| 7 | zhangsan |
| 8 | zhangsan |
--------------7.6、外键约束foreign key简称FK非常重要五颗星*****
外键约束涉及到的相关术语 外键约束一种约束foreign key 外键字段该字段上添加了外键约束 外键值外键字段当中的每一个值。
业务背景 请设计数据库表来描述“班级和学生”的信息
第一种方案班级和学生存储在一张表中 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 当cno字段没有任何约束的时候可能会导致数据无效。可能出现一个102但是102班级不存在。 所以为了保证cno字段中的值都是100和101需要给cno字段添加外键约束。 那么cno字段就是外键字段。cno字段中的每一个值都是外键值。
注意 t_class是父表 t_student是子表
删除表的顺序 先删子再删父。
创建表的顺序 先创建父再创建子。
删除数据的顺序 先删子再删父。
插入数据的顺序 先插入父再插入子。
思考子表中的外键引用的父表中的某个字段被引用的这个字段必须是主键吗 不一定是主键但至少具有unique约束。
测试外键可以为NULL吗 外键值可以为NULL。 总结外键约束的作用保证父表t_student字段上的cno的数据安全一旦加了外键约束字段中的数据就不能写了来自某张表的某个字段的数据