动力节点 讲师:郭鑫
在此先行感谢
参考笔记
https://blog.csdn.net/wangjx92/article/details/79333599
章节
- 数据库概述及安装
- MySQL的安装及登录
- 常用命令
- 演示数据结构
- 简单的查询
- 条件查询
- 数据排序 asc/desc
- 处理函数
- select语句总结
- 连接查询/跨表查询
- 子查询
- union合并(相加)集合
- limit使用
- 表
- 存储引擎
- 事务Transaction
- 索引(了解)
- 视图
- DBA命令
- 数据库设计三大范式
- 34题经典SQL试题
一、数据库的概述及其安装
相关概念介绍:
数据库管理系统 DBMS
数据库/仓库 DB
结构化查询语言 SQL
系统概述:
- 什么是数据库:一个或一组文件,保存了一些符合特定规格的数据,DataBase,数据库软件称为数据库管理统,DBMS,DataBase Management System,例如:Oralce,MySQL,SQL Server,Sybase,informix、DB2等
- MySQL发展历史
- SQL概述:Structured Query Language,结构化查询语言,是一套标准,使用SQL完成和数据库的通信,每个不同的数据库管理系统有不同的特性,有一些特定的SQL特性,大概占10%
数据库管理系统安装:
默认端口3306 可能被攻击, 可以使用别的端口(eg:3360)
添加系统环境变量:
C:\Program Files\MySQL\MySQL Server 5.7\bin
二、Mysql的安装与登录
在DOS启动和关闭服务
net start mysql
net stop mysql
表的定义:
表是一种结构化的文件,可以用来存储特定类型的数据,如:学生信息、课程信息等,都可 以放到表中,另外表都有特定的名称,而丏丌能重复。表中有以下几个概念:列、行、主键
1.列(字段)
通常叫做字段,每一个字段都包含:字段名称、字段数据类型、字段约束、字段长度;
2.行(记录)
通常叫做表中的记录。表中的数据是按行(记录)存储的,表里可以有0条戒多条记录;
登录
mysql -u 账号 - p 密码 || mysql -u 账号 -p —> 在输入密码
SQL语句分类:
DQL:数据查询语句,select
DML:数据操作语句,insert/delete/update
DDL:数据库定义语句,create/drop/alter
TCL:事务控制语言,commit/rollback
创建数据库
create database 数据库名称;
导入数据库脚本
数据库脚本:以.sql后缀结尾的文件
导入数据库脚本:
1.选定数据库 2.source命令(可以直接将sql文件拖到命令中)
source C:\Users\84741\Desktop\bjpowernode.sql
SQL数据库脚本
DROP TABLE IF EXISTS EMP;
DROP TABLE IF EXISTS DEPT;
DROP TABLE IF EXISTS SALGRADE;
CREATE TABLE DEPT
(DEPTNO int(2) not null ,
DNAME VARCHAR(14) ,
LOC VARCHAR(13) ,
primary key (DEPTNO)
);
CREATE TABLE EMP
(EMPNO int(4) not null ,
ENAME VARCHAR(10) ,
JOB VARCHAR(9) ,
MGR INT(4) ,
HIREDATE DATE DEFAULT NULL ,
SAL DOUBLE(7,2) ,
COMM DOUBLE(7,2) ,
primary key (EMPNO) ,
DEPTNO INT(2)
);
CREATE TABLE SALGRADE
(GRADE INT ,
LOSAL INT ,
HISAL INT
);
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES (
10, 'ACCOUNTING', 'NEW YOURK');
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES (
20, 'RESEARCH', 'DALLAS');
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES (
30, 'SALES', 'CHICAGO');
INSERT INTO DEPT( DEPTNO, DNAME, LOC ) VALUES (
40, 'OPERATIONS', 'BOSTON');
commit;
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (
7396, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, NULL, 20);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (
7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300,30);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (
7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250, 500, 30);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (
7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, NULL, 20);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (
7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (
7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850, NULL, 30);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (
7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450, NULL, 20);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (
7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19', 3000, NULL, 20);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (
7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5000, NULL, 10);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (
7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08', 1500, 0, 30);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (
7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1100, NULL, 20);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (
7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, NULL, 30);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (
7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, NULL, 20);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (
7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, NULL, 10);
commit;
INSERT INTO SALGRADE (GRADE, LOSAL, HISAL) VALUES (
1, 700, 1200);
INSERT INTO SALGRADE (GRADE, LOSAL, HISAL) VALUES (
2, 1201, 1400);
INSERT INTO SALGRADE (GRADE, LOSAL, HISAL) VALUES (
3, 1401, 2000);
INSERT INTO SALGRADE (GRADE, LOSAL, HISAL) VALUES (
4, 2001, 3000);
INSERT INTO SALGRADE (GRADE, LOSAL, HISAL) VALUES (
5, 3001, 9999);
commit;
数据库表的介绍
查看描述表的结构: desc dept;
字段,字段类型,字段长度,字段约束
以DEPTNO为例,字段为DEPTNO,字段类型为INT,字段长度为2,约束是字段不能为空且为主键,默认值为NULL
desc emp;
desc salgrade;
double(7,2) 表示七位数,二位小数点 其数值的范围为 0-99999.99
三、常用命令
查看数据库的版本
mysql --version
mysql -V
select version() (在进入数据库中数据库)
表的定义
查看哪些数据库:show databases;
使用某个数据库:use test;
查看有哪些表:show tables;
查看自己在那个数据库下 :select database();
直接查看其它数据库中的表:show tables from mysql;
退出数据库:exit \q 或者 Ctrl +c
删除数据库: drop database 数据库名;
四、演示数据结构
1、查看和指定现有的数据库 show databases;
2、指定当前缺省数据库 use bjpowernode;
3、查看当前使用的数据库 select database();
4、查看当前数据库中的表 show tables;
5、查看其它数据库中的表 show tables from 数据库名称;
6、查看表结构 desc 表名称;
7、查看表的创建询句 show create table 表名称;
五、简单的查询
单个字段和多个字段
select ename from emp;
select ename,sal,comm from emp;
查询全部字段
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp;
select * from emp;
俩个查询所有字段的方法最好使用前一个,因为用*代替的方法需要把* 转译成所有具体字段,效率低,并且语义不明确
查询员工年薪及给字段起别名
字段名可以进行数学计算,起别名
select ename,sal*12 as yearsal from emp;
或者:
select ename,sal*12 yearsal from emp; 不建议省略as
六、条件查询
14、条件查询
关键字:where
select 字段 from 表名 where 条件;
15、条件查询支持的运算符介绍
运算符 | 说明 |
= | 等于 |
<>或!= | 不等于 |
< | 小于 |
<= | 小于等于 |
> | 大于 |
>= | 大于等于 |
between ... and ... | 两个值之间,相当于>= and <= |
is null | 为null(is not null 不为空) |
and | 并且 |
or | 或者 |
in | 包含,相当于多个or(not in 不在这个范围中) |
not | Not可以取非,用于is和in中 |
like | Like为模糊查询,支持%或者下划线匹配 %匹配任意个字符 下划线只匹配一个字符 |
ps:因为稍微有点基础,简单的也就不写了
1、区间操作运算符
select ename,sal from emp where sal>1000 and sal<1600;
select ename,sal from emp where sal between 1000 and 1600; (between中的范围是从小到大的)
select ename,sal from emp where sal in (800.1600);
select ename,sal from emp where sal not in (800,1600);
2、and优先级高于or
select deptno,sal from emp where sal>1600 and ( deptno=20 or deptno=30)
3、is运算符
select ename,comm from emp where comm is null;
null不是数字,是空值,不能进行数学计算,因此不能用=号
select ename,comm from emp where comm is not null;
4、like 模糊查询
select ename from emp where ename like ‘%s%’;
select ename from emp where ename like ‘s%’;
select ename from emp where ename like ‘_d%’;
select ename from emp where ename like ‘%n_’;
七、数据排序 asc(升) desc(降)
1、数据排序的概述
单一字段排序 :order by
默认:asc
降序:desc
order by 放在where之后
2、通过字段排序
select * from emp order by sal;
select * from emp order by sal desc;
select ename,hiredate from emp order by hiredate desc;
多个字段排序
select ename,hiredate,sal from emp order by hiredate desc,sal asc;
多个字段排序的时候,首先按照第一个字段排序,如果第一个字段相同,那么按照第二个字段再进行排序,以此类推
有条件查询的时候,order by放在where之后
3、通过字段下标排序
字段下标从1开始,这里的下标指的是你查询显示的列的下边,比如job,ename,sal,那么job就是1,sal是3
select ename,job,sal from emp where job='clerk' order by 3;
八、数据处理函数
①、单行处理函数
lower | 转换小写 |
upper | 转换大写 |
substr | 截取子串(substr(被截取的字符串,起始下标,截取的长度) |
length | 取长度 |
trim | 去空格 |
str_to_date | 将字符串转换成日期 |
Date_format | 格式化日期 |
Format | 设置千分位 |
Round | 四舍五入(数字,保留小数位) |
Rand() | 生成随机数 |
Ifnull | 可以把null转换成一个具体值 |
注意:数据处理函数是该数据本身特有的,有些函数可能在其他数据库不起作用
单行的意思:处理一行输出一行
1、转换大小写函数
select lower(ename) as lowername from emp;
select upper(ename) as lowername from emp;
2、substr截取字符串函数
select substr(ename,1,1) from emp;
起始下标是从1开始的!
取3,4,5个字符:
select substr(ename,3,3) from emp;
3、length和trim函数
select length(ename) from emp;
去掉后面的空格:一般在用户输入的时候,条件查询中会用到(MYsql会自动去掉后面的空格)
select * from emp where ename=trim('king ');
4、round 四舍五入函数
select round(123.56);
select round(123.56,0);
上面两个输出都是124
select round(123.56,1);
输出是123.6
select round(123.56,-1);
输出是120
select round(123.56);
select round(123.56,0);
上面两个输出都是124
select round(123.56,1);
输出是123.6
select round(123.56,-1);
输出是120
5、rand 随机函数
select rand();
输出0到1闭区间的随机数
select round(rand()*122,0);
输出0到122闭区间的随机数
6、case_when_then_else_end函数
匹配工作岗位,为MANAGER时,薪水上调10%,为SALESMAN的时候,薪水上调50%
select job,ename,
(case job
when ‘MANAGER’ then sal*1.1
when ‘SALESMAN’ then sal*1.5
else sal
end) as newsal from emp;
7、ifnull空值处理函数
eg:统计计算补贴了的所有员工年收入,如何没有补贴,则默认为0
select (sal+ifnull(comm,0))*12 as yearmoney from emp;
8、str_to_date函数
用法:str_to_date(‘日期字符串’,’日期格式’)
日期格式包括:
序号 | 格式符 | 功能 |
| 格式符 | 功能 |
1 | %Y | 4位年份 |
| %y | 2位年份 |
2 | %m | 月,01...12 |
| %c | 月,1...12 |
3 | %d | 日 |
|
|
|
4 | %H | 24小时制 |
| %h | 12小时制 |
5 | %i | 分钟,格式00...59 |
|
|
|
6 | %S或者%s | 秒,格式00...59 |
|
|
|
eg:查询1981-12-03入职的员工
1、自动类型转换
select ename,hiredate from emp where hiredate='1981-12-03';
2、标准格式
MYSQL默认的日期格式为 %Y-%m-%d
eg:把其他类型的日期字符串转化为DATE
select ename,hiredate from emp where hiredate=str_to_date('12-03-1981','%m-%d-%Y');
另外一种使用方式在insert中
总结:
1、日期是数据库本身的特使,也是数据库本身机制中的一个重要内容;
2、每一个数据库处理日期采用的机制都不一样,所以在实际开发中将日期字段定义为DATE类型的情况很少
3、如果使用日期类型,java程序则不能通用,实际开发中会使用“日期字符串”来表示日期
例子:
1、创建t_student 表,插入含有日期的数据
create table t_student(
id int(10),
name varchar(32),
birth date);
2、插入数据 1980-01-18
insert into t_student(id,name,birth) values (1,’jack’,’1980-01-18’);
执行成功,因为格式和MySQL数据库默认的日期格式相同,会自动类型转换
3、插入数据 01-18-1980
insert into t_student(id,name,birth) values (1,’jack’,’01-18-1980’);
插入失败
正确写法:
insert into t_student(id,name,birth) values (1,’jack’,str_to_date(’01-18-1980’,’%m-%d-%Y’))
9、date_format函数
日期类型转换成特定格式的日期字符串
data_format(日期类型数据,’日期格式’)
例子:
- 查询员工的入职日期
select ename,date_format(hiredate,'%m-%d-%Y') as new Date from emp;
select ename,date_format(hiredate,'%m/%d/Y') as new Date from emp;
MySQL日期默认格式示例:
hiredate自动转换成varchar类型,采用年月日格式
select ename,hiredate from emp;
②、多行处理函数(聚合函数、分组函数)
分组函数/聚合函数/多行处理函数
常用以下几种:
sum | 求和 |
avg | 平均 |
max | 最大值 |
min | 最小值 |
count | 记录数 |
单行函数式一行输入对应一行输出
多行处理函数是多行输入对应一行输出
注意:
- 分组函数会自动忽略空值,不需要手动增加where条件排除空值;
- 分组函数不能直接使用在where关键字后
1、count函数
select count(*) from emp where comm is null;
count(*)表示多行记录
如果写成:
select count(comm) from emp where comm is null;
结果为0,因为count()会自动忽略空值
count(*)统计的是结果集的总条数,count(字段名)统计的是该字段值不为null的总条数
select count(comm) from emp where comm is not null;
等价于
select count(comm) from emp;
③、distinct去除重复记录概述
distinct:将查询结果中的某一个字段的重复记录去除
用法:distinct 字段名或distinct 字段名1,字段名2 ...
distinct A 区处于字段名A相同的记录
distinct A,B 去除与字段名A和字段名B相同的记录
注意:DISTINCT只能出现在所有字段的最前面,后面接多个字段为多字段联合去重
select distinct job from emp;
select count(distinct job) from emp;
select distinct deptno,job from emp order by deptno;
④分组查询
group by
语句格式:
select 字段
from 表名
group by 字段;
eg:查询每个职业中的最高薪水
select job,max(sal) from emp group by job;
select job,sal from emp group by job;
这种语句,只取拿到的第一个记录
select job,ename,max(sal) as maxsal
from emp
group by job;
查找每个职业中,最高的薪水,同时会取出每个职业的第一个名字(没有意义,SCOTT不一定是3000收入的人)
在ORACLE中会直接报错
例子:
计算每个工作岗位的最高薪水,并且按照由低到高排序
先按照工作分组,然后排序
select job,max(sal) as maxsal from emp group by job order by maxsal desc;
例子:
计算每个部门的平均薪水
select deptno,avg(sal) from emp group by deptno;
例子:
计算出不同部门不同岗位的最高薪水
select deptno,job,max(sal) from emp group by deptno,job;
用法和distinct类似,多个字段联合
例子:
找出每个工作岗位的最高薪水,除了MANAGER之外
select job,max(sal) from emp where job<> 'manager' group by job;
having数据过滤用法
例子:找出每个工作岗位的平均薪水,要求显示平均薪水大于2000的
select job,avg(sal) as avgsal from emp group by job having avgsal>2000;
having 必须和 group by搭配使用,分组后再筛选
having与where数据过滤用法区别
where 在 group by之前
having 在 group by之后
九、select语句总结
一个完整的SQL语句如下:
select xxx
from xxx
where xxx
group by xxx
having xxx
order by xxx.
- from 将硬盘上的表文件加载到内存
- where 将符合条件的数据行摘取出来,生成一张临时表
- group by 根据列中的数据种类,将当前临时表划分成若干个新的临时表
- having 可以过滤掉group by生成的不符合条件的临时表
- select 对当前表进行整列读取
- order by 对select生成的临时表,进行重新排序,生成新的临时表
- limit 对最终生成的临时表的数据行进行截取
十、连接查询/跨表查询
在实际开发中,数据往往丌是存放储一张表中,而是同时存储在多张表中,这些表不表存 在着关系,我们在检索数据的时候往往需要多张表联合起来检索,这种多表联合检索被称为连 表查询戒跨表查询
1、笛卡尔积现象
含义:若两张表迚行连接查询的时候没有任何条件限制,最终的查询结果总数是两张表记录 的乘积,该现在称为笛卡尔积现象。
例子:查询员工名称和部门名称
select ename,dname from emp,dept;
这个语句没有加条件限制,因此结果是两个表的乘积
比如表A
1
2
3
表B
4
5
6
结果是
1 4
1 5
1 6
2 4
2 5
2 6
3 4
3 5
3 6
称为 笛卡尔积
2、跨表查询的分类介绍
年代划分:
SQL92
SQL99
连接方式划分:
内连接
等值连接
非等值连接
自连接
外连接
左外连接
右外连接
全连接
2.1 根据年代分类_SQL92语法
例子:
显示每个员工信息,并显示所属部门名称
select ename,dname from emp as e,dept as d where e.deptno = d.deptno;
这个语句的匹配次数依然是笛卡尔积
2.2根据年代分类_SQL99语法
例子:
显示每个员工信息,并显示所属部门名称
select ename,dname from emp as e join dept as d on d.deptno = d.deptno;
格式: 开发使用sql99
2.3根据连接方式分类_内连接_等值连接
例子:
显示每个员工信息,并显示所属部门名称
select ename,dname from emp as e inner join dept as d on d.deptno = d.deptno;
2.4根据连接方式分类_内连接_非等值连接
例子:查询员工薪水对应的薪水等级
select enam, sal,grade from emp as e inner join salgrade as s on sal between s.losal and hisal;
总共执行了14*5=70次
2.5根据连接方式分类_内连接_自连接
例子:
查询员工所对应的领导名称,显示员工名称和领导名称
select e1.ename,e2.ename from emp as e1 join emp as e2 on e1.mgr = e2.empno;
这个语句相当于把emp表做了两次别名处理,一张表看成两张表
2.6根据连接方式分类_外连接概述
A表和B表能够完全匹配的记录查询出来之外,将其中一张表的记录无条件的完全查询出来,对方表没有匹配的记录时,会自动模拟出null值与之匹配
注意:外连接的查询结果条数>=内连接的查询结果条数
2.7根据连接方式分类_外连接_右外连接
包含右边表的全部行(不管左边表是否存在与它们匹配的行),以及左边表中全部匹配的行
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 as e right outer join dept as d on e.deptno = d.deptno;
2.8根据连接方式分类_外连接_左外连接
包含左边表的全部行(不管右边表是否存在与它们匹配的行),以及右边表中全部匹配的行
例子:
select a.ename, b.ename as leadername from emp a left outer join emp b on a.mgr = b.empno;
这里KING是没有领导的 显示为NULL
2.9全连接
3、多表查询语法介绍
select d.dname,e.ename,b.ename as leadername,s.grade
from emp e
join dept d
on e.deptno = d.deptno
join emp b
on e.mgr = b.empno
join salgrade s
on e.sal between s.losal and s.hisal;
十一、子查询
子查询:select语句嵌套select语句
注意:select子句可以出现在select/from/where关键字后面,例如
select ... (select) ... [很少时候用,了解即可]
from ... (select) ...
where ... (select) ...
1、where关键字后的嵌套查询
例子:
找出薪水比公司平均薪水高的员工,要求显示员工名和薪水
错误语句:分组函数不能直接使用在where关键字后面
select ename,sal from emp where sal > avg(sal);
正确语句:
select ename,sal from emp where sal > (select avg(sal) from emp);
2、from关键字后的嵌套查询
例子:找出每个部门的平均薪水,并且要求显示平均薪水的薪水等级
select e.deptno,avg(sal) as avgsal from emp e group by e.deptno;
把上面作为临时表t
select t.avgsal,s.grade from t join salgarde s on t.avgsal between s.losal and s.hisal;
最终语句:
select t.avgsal,s.grade from (select e.deptno,avg(sal) as avgsal from emp e group by e.deptno
) t join salgarde s on t.avgsal between s.losal and s.hisal;
十二、 union合幵(相加)集合
定义:将查询的结果集合幵
注意事项: 合幵结果集的时候,查询字段个数必须相同;
例子:查询出job为MANAGER和SALESMAN的员
select ename,job from emp where job = ‘MANAGER’ or job = ‘SALESMAN’;
select ename,job from emp where job in (‘MANAGER’,’SALESMAN’);
使用UNION
select ename,job from emp where job = ‘MANAGER’
union
select ename,job from emp where job = ‘SALESMAN’;
如果将第二个表的ename 改为 empno
输出结果是一串数字没有意义
十三、Limit使用
limit只在MySQL中有效,获取一个表前几行或者中间某几行数据
用法:
limit起始下标m,长度n
m从0开始,表示第一行记录
n表示从第m+1条开始,取N行记录
下标从0开始,但是长度是从1开始
例子:取得前5个员工信息
select * from emp limit 0,5;
或者
select * from emp limit 5;
例子:取薪水前3名的员工
select ename,sal from emp order by sal desc limit 3;
动力节点_MySQL_068_limit实现分页
例子:emp表,每页显示3条记录
页码 pageNo
记录数 pageSize
分析:
第1页 1,2,3 limit 0,3
第2页 4,5,6 limit 3,3
第3页 7,8,9 limit 6,3
limit规律: limit (pageNo-1)*pageSize,pageSize
十四、表
①定义
表(table):是数据库最基本的组成单元,数据库是用来存储数据的,数据库中有很多表,每一个
表都是一个独立的单元,表也是一个结构化的文件,由行和列组成,行称为数据戒记录,列称为字段,
字段又包含:字段名称、字段类型、长度、约束。
②创建表
create table 表名(
字段1 字段类型(长度) 字段约束,
字段2 字段类型(长度) 字段约束,
字段3 字段类型(长度) 字段约束,
...
字段N 字段类型(长度) 字段约束,
primary key(字段)
)engine=InnoDB default charset=utf8;
commit;
CREATE TABLE IF NOT EXISTS `runoob_tbl`(
`runoob_id` INT UNSIGNED AUTO_INCREMENT,
`runoob_title` VARCHAR(100) NOT NULL,
`runoob_author` VARCHAR(40) NOT NULL,
`submission_date` DATE,
PRIMARY KEY ( `runoob_id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
实例解析:
如果你不想字段为 NULL 可以设置字段的属性为 NOT NULL, 在操作数据库时如果输入该字段的数据为NULL ,就会报错。
AUTO_INCREMENT定义列为自增的属性,一般用于主键,数值会自动加1。
PRIMARY KEY关键字用于定义列为主键。 您可以使用多列来定义主键,列间以逗号分隔。
ENGINE 设置存储引擎,CHARSET 设置编码。
2.1常用数据类型介绍
数据类型 | 占用字节数 | 描述 |
char | char(n) | 定长字符串,存储空间大小固定,使用char(2)表示类型或状态 |
varchar | varchar(n) | 变长字符串,存储空间等于实际数据空间 只包含英文字符的字符串 |
int | 4个字节 | 表示整型 比如自增ID和表示数量 |
bigint | 8个字节 | 长整型 比如自增ID,数据量比较大的情况下使用 |
float | float(有效数字位数,小数位) | 数值型 |
double | double(有效数字位数,小数位) | 数值型 |
date | 8个字节 | 表示日期和时间 |
BLOB |
| 二进制大对象,Binary Large Object,视频图像等,开发中基本不用,只需要存文件地址 |
CLOB |
| 字符大对象,Character Large Object,开发中很少用,最大存4G+的字符串 |
注意:
VARCHAR 和CHAR对比
- 都是字符串
- VARCHAR可以根据实际数据长度分配空间,需要进行长度判断,因此执行效率比较低
- CHAR不需要动态分配空间,执行效率高,可能会导致空间浪费
- 字段中数据不具备伸缩性的时候,采用CHAR存储,比如(状态值)性别MALE和FEMALE,其他就是用VARCHAR,比如姓名等
2.2 创建表和删除表
例子:创建学生表
create table t_student(
no int(4) not null,
name varchar(32) not null,
gender char(1) not null,
birth date,
email varchar(128),
primary key(no)
);
查看建表语句:
show create table t_student;
删除表:
drop table t_student;
如果存在就删除表:
drop table if exists t_student;
2.3 复制表语法
create table aemp_baks select * from emp;
③、数据库操作语言DML(insert,update,delete)
1、insert 语句
insert into 表名(字段1,字段2,...,字段N) values (字段1的值,字段2 的值,...,字段N的值);
2、数据操作语言DML语句_update语法
update 表名 set 字段名称 = 字段值,字段名称 = 字段值 where 限制条件;
必须加限制条件!!否则就是全表修改
update t_student set birth = str_to_date(‘1951-10-10’,’%Y-%m-%d’), email = ‘lilei@126.com’ where name = ‘lilei’;
3、数据操作语言DML语句_delete语法
语法:
delete from t_student; //删除所有
delete from t_student where no = 4; //加限制条件
注意:这属于物理删除,无法恢复,如果需要做回收站的功能可以先将需要删除的数据保存起来
4、设置表中字段默认值
关键字:default
5、动力节点_MySQL_079_表_MySQL-Front工具使用介绍
show variables like '%char%';
字符集改成gbk
再查一下
5、快速向表中插入数据
insert
insert into emp_bak select * from emp where job = 'MANAGER';
select count(*) from emp_bak;
注意:快速插入保证字段类型和数量一致
④、修改表结构
ALTER关键字
- 新增:ALTER TABLE 表名 ADD 字段名 字段类型(长度);
- 修改:ALTER TABLE 表名 MODIFY 字段名 字段类型(长度);
- 删除:ALTER TABLE 表名 DROP 字段名;
drop table if exists t_student;
create table t_student(
no int(10),
name varchar(32)
);
alter table t_student add email varchar(128);
alter table t_student modify no int(8);
alter table t_student drop email;
不常用的修改字段名称方法:
alter table t_student change name username varchar(32);
⑤、约束
目的:保证表中数据的完整和有效
英语:constraint
定义:对表中数据的限制条件
1、动力节点_MySQL_083_约束_非空约束
not null
表明字段必须由具体数据,不能为NULL
2、动力节点_MySQL_084_约束_唯一性约束_列级写法
unique
表明字段必须不能重复,保持唯一
列级约束:写在字段后面,保证邮箱唯一性
create table t_student(
no int(10),
name varchar(32) not null,
email varchar(128) unique
);
3、动力节点_MySQL_085_约束_唯一性约束_表级写法
表级约束:
email varchar(128),
unique(email)create table t_student(
no int(10),
name varchar(32) not null,
);
效果和84一样。
表级支持多个字段联合约束
create table t_student(
no int(10),
name varchar(32) not null,
email varchar(128),
unique(name,email)
);
只有当name和email都一样的时候,才是重复值,只要有一个值不一样,就认为不是重复记录
约束起别名:
create table t_student(
no int(10),
name varchar(32) not null,
email varchar(128),
constraint t_user_name_email_unique unique(name,email)
);
查询约束:
select CONSTRAINT_NAME from TABLE_CONSTRAINTS where table_name ='t_user';
4、动力节点_MySQL_086_约束_非空约束与唯一性约束联合使用
例子:手机号,不为空,不能重复
not null unique
⑥、约束____主键
1、主键约束概述及相关概念
primary key
主键约束、主键字段、主键值
表中某个字段添加主键约束之后,该字段成为主键字段,主键字段中出现的每一个数据都成为主键值。
2、键约束的作用
1、添加了主键 primary key 的字段“不能重复也不能为空”,而且会自动添加“索引-index”,提高检索效率。
2、一张表必须有主键,否则这张表就是无效的(数据库设计第一范式),主键值是当行数据的唯一标识,就是表中两行数据完全相同,但是由于主键不同,也可以认为是两行完全不同的数据。
3、单一主键和复合主键
单一主键:给一个字段添加主键约束;
列级: id int(10) primary key
表级: 在创建数据库表的时候,最后一个加primary key(id)
上面两种写法效果一样
复合主键:
constraint t_user_id_name_pk primary key(id,name)
只有当id和name都一致的时候,才认为是重复的数据
无论是单一主键还是复合主键,一张表中有且只能有一个主键约束
4、自然主键和业务主键
按照业务性质分类:
自然主键:主键值是一个自然数,与业务没有任何关系
业务主键:主键值和表中业务紧密相关,如果业务发生变化,则主键也会受到影响,所以业务主键使用较少,大多数情况下使用自然主键,比如身份证号位数扩展
5、increment函数_自动生成主键值
auto_increment
自增数字auto_increment,用来自动生成主键值,是MySQL独有的函数,默认从1开始,步进1递增
例子:
id int(4) primary key auto_increment
使用insert的时候就不需要填写id的值了 或者使用default
⑦、约束____外键
1、键约束概述及相关概念
foreign key 简称FK
外键约束,外键字段,外键值
给某个字段添加外键约束之后,这个字段就是外键字段,字段中的数据就是外键值。
单一外键:给一个字段添加外键约束
复合外键:给多个字段联合添加外键
同一张表中可以有多个外键存在
2、实例创建外键约束
需求:设计数据库表用来存储学生和班级信息(给出两种方案)
需求分析:
学生表t_student包含:sno,sname,classno,cname
学生和班级的关系,一个班级有多个学生,一个学生只能属于一个班级,属于一对多关系
第一种解决方案:
把学生和班级信息都存储到一张表中
问题:高三一班重复出现,数据冗余
第二种解决方案:
创建1张学生表,1张班级表
为了保证t_student表中的cno字段的数据必须来之t_class中的cno,需要给t_student的cno字段添加外键约束,cno成为外键字段,100、200、300就是外键值,cno此处为单一外键
完整语句:
注意:
- 外键字段可以为NULL,空外键值为孤儿数据
- 被引用的字段必须unique约束(就是父表的主键)
- 外键引用之后,就可以区分父表和子表,t_class为父表,t_student为子表
3、查询出学生所对应的班级名称
select ts.sname,tc.cname from t_student as ts join t_class as tc on ts.cno = tc.cno;
注意:MySQL中没有提供修改外键约束的语法
4、级联更新与级联删除概述
用法:添加级联更新与级联删除的时候,需要在外键约束后添加关键字
注意:级联更新与极限删除操作谨慎使用,因为级联操作会导致数据改变或者删除
5、级联删除的操作
级联删除:on delete cascade
先删除外键约束:
ALTER TABLE 表名 DROP FOREIGN KEY 外键字段;
alter table t_student drop foreign key t_student_classno_fk;
添加外键约束:
alter table t_student add constraint t_student_classno_fk foreign key(classno) references t_class(cno) on delete cascade;
6、级联更新的操作
级联删除:on update cascade
先删除外键约束:
ALTER TABLE 表名 DROP FOREIGN KEY 外键字段;
alter table t_student drop foreign key t_student_classno_fk;
添加外键约束:
alter table t_student add constraint t_student_classno_fk foreign key(classno) references t_class(cno) on update cascade;
十五、存储引擎
1、存储引擎的概述
存储引擎是MySQL特有,其他数据库没有
本质:
- 通过采用不同的技术将数据存储在文件或内存中
- 每一种技术都有不同的存储机制,提供不同的功能,具备不同的能力
- 选用不同的技术,可以获得额外的速度和功能,改善应用
查看存储引擎命令
show engines\G;
一共9种,默认是InnoDB
2、存储引擎的基本操作
1、创建表时,可以使用ENGINES=InnoDB指定引擎类型
create table table_name(
no int(2)
)engine = InnoDB;
2、如果创建表时没有指定存储引擎,会使用默认的存储引擎
3、默认的存储引擎可以在安装目录的my.ini中配置default-storage-engin指定
4、修改表的存储引擎:alter table table_name engine = new_engine_name;
5、查看表使用的存储引擎
show create table emp\G;
或者
show table status like ‘emp’\G;
3、常用的存储引擎_MyISAM
1、是MySQL数据库最常用的
2、管理的表具备以下特性
a) 格式文件 存储表的结构 mytable.frm
b) 数据文件 存储表的数据 mytable.MYD
c) 索引文件 存储表的索引 mytable.MYI
3、可压缩、只读表,节省空间
4、常用的存储引擎_InnoDB
1、是MySQL默认的存储引擎
2、管理的表具备以下特性
a) 每个InnoDB表在数据库目录中以.frm格式文件表示
b) InnoDB表空间tablespace被用于存储表的内容
c) 提供一组用来记录事务性活动的日志文件
d) 用commit/savepoint/roolback支持事务处理
e) 提供全部ACID兼容
f)在MySQL服务器崩溃后提供自动回复
g)多版本(MVCC)和行级锁定
h)支持外键及引用的完整性,包括级联更新和删除
5、常用的存储引擎_MEMORY
1、 数据存储在内存中,且行的长度固定,因此非常快
2、 管理的表具备以下特性:
a) 在数据库目录中,每个表以.frm格式文件表示
b) 表数据及索引被存储在内存中
c) 表级锁机制
d) 字段属性不能包含TEXT或者BLOB字段
3、 旧名HEAP引擎
6、如何选择合适的存储引擎
1、MyISAM表适合于大量数据读而少量数据更新的混合操作。MyISAM表的另一种适用情形是使用压缩的只读表
2、如果查询中包含较多的数据更新操作,应该使用InnoDB,其行级锁机制和多版本的支持为数据读取和更新的混合提供了良好的并发机制(由事务控制)
3、使用MEMORY存储引擎存储非永久需要的数据,或者是能够从基于磁盘的表中重新生成测数据。
十六、索引
1、索引的概述
index
相当于一本字典目录,提高程序的检索/查询效率,表中的每一个字段都可以添加索引
主键自动添加索引,能通过主键查询的尽量通过主键查询,效率较高
索引也是存储在磁盘文件中
1、 索引和表相同,是一个对象,表示存储在硬盘文件中,索引是表的一部分,因此也存放在硬盘文件中
2、索引的检索方式及什么情况下创建索引
MySQL数据库有2中检索方式:
- 全表扫描(效率较低)
例子:查询ename=’KING’
select * from emp where ename=’KING’;
如果ename没有添加索引,那么通过ename过滤数据的时候,ename字段会全表扫描
- 通过索引检索(提高查询效率)
创建索引的情况:
- 该字段的数据量庞大
- 该字段很少使用DML操作(索引需要维护,DML操作太多的时候,影响检索效率)
- 该字段经常出现在筛选条件where中
实际开发中根据项目需求或客户需求综合调整
3、索引的应用
1、创建索引
语法:
create index 索引名 on 表名(列名);
create unique index 索引名 on 表名(列名);
注:添加unique表示在该表中的该列添加一个唯一性约束
例如:create index dept_dname_index on dept(dname);
2、查看索引
show index from 表名;
3、删除索引
drop index 索引名on 表名;
十七、视图
1、视图概述及应用
view
视图在数据库管理系统中也是一个对象,以文件形式存在
视图也对应了一个查询结果,只是从不同的角度查看数据
语法:
create view 视图名称 as 查询语句;
例如:create view myview as select * from emp;
show tables;
可以查看到新建的myview视图
视图底层也是表
查看视图的语句
show create view my view;
删除:drop view if exists myview;
2、视图的作用_隐藏表的实现细节
隐藏表的实现细节
例子
create view myview as select empno as a, ename as b from emp;
select * from myview;
3、视图的作用_提高检索效率
提高检索效率
例子
create view myview2 as
select e.ename,d.dname from emp e join dept d on e.deptno = d.deptno;
十八、DBA
1、新建用户
create user username identified by ‘password’;
例子:
create user p361 identified by ‘123’;
登录后只能看见information_schema一个库
- 授权
grant all privileges on dbname.tbname to ‘username’@’login ip’ identified by ‘password’ with grant option
dbname = 数据库,*表示所有数据库
tbname = 表,*表示所有表
login ip = 登录IP,%表示任意IP
password = 登录密码,空表示不需要密码
with grant option:表示这个用户可以授权其他用户
细粒度授权
- root登录mysql
- grant select,insert,update,delete on *.* to p361 @localhost identified by ‘123’;
- localhost改为%表示可以再任何机器上登录mysql
- 回收授权
- 导入导出
十九、数据库设计三范式
①、第一范式
主键、字段不能再分
要求有主键,数据库中不能出现重复记录,每一个字段是原子性不能再分
实例:不符合第一范式:
上面存在的问题:
数据存在重复记录,数据不唯一,没有主键
联系方式可以再分为邮箱和手机号,不是原子性
修改方案:
结论:
- 每一行必须唯一,也就是每个表必须有主键,这是设计数据库的最基本要求
- 主键主要通常采用数值型或者定长字符串表示
- 关于列不可再分,应该根据具体的情况来决定,如联系方式,为了开发商的遍历有坑呢就采用一个字段,不分为邮箱和手机
②、第二范式
非主键字段完全依赖主键
第二范式在第一范式的基础上,要求数据库中所有非主键字段完全依赖主键(严格意义上说,尽量不要使用联合主键)
示例1,数据仍然可能重复
示例2,确定主键,学生编号,教师编码,出现冗余
分析
- 上面例子虽然确定了主键,但是表会出现大量的冗余,主要涉及到的冗余字段是 学生姓名 和教师姓名
- 出现冗余的原因是,学生姓名部分依赖了主键的一个字段 学生编号,没有依赖 教师编号
教师姓名部分依赖了逐渐的一个字段 教师编号,这就是第二范式部分依赖
解决方案:
老师和学生是多对多的关系
学生信息表:学生编号PK,学生姓名
教师信息表:教师编号PK,教师姓名
多对多的关系,需要有1张关系表:
教师-学生关系表:
学生编号PK fk(学生表的学生编号),教师编号PK fk(教师表的教师编号)
结论:典型的多对多关系
③、第三范式
在第二范式基础上,要求非主键字段不能产生传递依赖与主键字段
例子1,学生信息表
班级名称存在冗余,因为班级名称没有直接依赖主键(学生编号)
班级名称依赖于班级编号,班级编号依赖于学生编号(学生调班之后班级编号就变了),这就是传递依赖
一对多的设计:在多的一方添加外键
解决方案:
学生信息表:学生编号PK,学生姓名,班级编号FK
班级信息表:班级编号PK,班级名称
④、一对一关系如何设计
- 一对一
方案1:分两张表存储,共享主键
t_husband t_wife两张表
t_husband
hno(PK),hname
t_wife
wno(PK,同时也是外键FK,引用t_husband的主键),wname
方案2:两张表存储,外键唯一
t_husband
hno(PK),hname,wifeno(FK-unique)
t_wife
wno(FK),wname
实际开发中如何做
1、尽量遵循三大范式
2、根据实际需求进行取舍,有时候冗余换速度,最终目的,满足需求