MySQL

一些示例

主键用bigint
boolean用tinyint
日期用datetime

drop table if exists base_company;
create table base_company
(
    company_id                bigint            not null comment '公司ID主键'
        primary key,
    app_id                    varchar(255)      not null comment 'appId',
    app_secret                varchar(255)      not null comment 'app密钥',
    token                     varchar(255)      not null comment '通过app_id和app_secret生成的有时效性的token',
    delete_flag               tinyint default 0 not null comment '删除标志',
    default_config_id         bigint            not null comment '默认配置id',

    sync_frequency            int(11)           not null comment '同步频率',
    sync_method               int(11)           not null comment '同步方式',
    be_create_global_calendar tinyint           not null comment '是否已经创建全局日历',
    be_open_global_calendar   tinyint           not null comment '是否开启全局日历',
    lark_global_calendar_id   varchar(255)      null comment '飞书全局日历id',

    version                   bigint     default 1 comment '行版本号,用来处理锁',
    created_by                bigint(20) default 0 comment '创建人',
    creation_date             datetime   default CURRENT_TIMESTAMP comment '创建时间',
    last_updated_by           bigint(20) default 0 comment '最后更新人',
    last_update_date          datetime   default CURRENT_TIMESTAMP comment '最后更新时间',
    attribute1                varchar(255) comment '备用字段1',
    attribute2                varchar(255) comment '备用字段2',
    attribute3                varchar(255) comment '备用字段3',
    attribute4                varchar(255) comment '备用字段4',
    attribute5                varchar(255) comment '备用字段5'
)
comment '公司表';

概论

数据(元组、行)
字段(属性、列)应该有字段名、数据类型、约束

SQL分为:
DQL数据查询语言:查询语句
DML数据操作语言:insert delete updat,对表中数据的增删改
DDL数据定义语言:create drop alter,对表结构的增删改,例如删除字段。create创建表,drop删除表,alter修改表
TCL事务控制语言:commit提交事务,rollback回滚事务
DCL数据控制语言:grant授权、revoke撤销授权

导入数据

第一步:登录mysql数据库管理系统
dos窗口
mysql -uroot -p
密码
第二步:查看有哪些数据库
show databases;(这个不是SQL语句,属于MySQL的命令,其他数据库不通用)

±-------------------+
| Database |
±-------------------+
| information_schema |
| mysql |
| performance_schema |
| sakila |
| sys |
| world |

第三步:创建我们自己的数据库
create database daihan;(这个不是SQL语句,属于MySQL的命令,其他数据库不通用)

第四步:使用daihan数据
use daihan;(这个不是SQL语句,属于MySQL的命令,其他数据库不通用)

第五步:查看表
show tables;(这个不是SQL语句,属于MySQL的命令,其他数据库不通用)

第六步:初始化数据
source 绝对路径;
//使用source命令可以执行sql脚本

第七步:查看表结构
use daihan;
show tables;
desc 表名;//查看表结构
第八步:查看数据
select* from 表名;

删除数据库:

drop database daihan;

注:
使用use xxx;切换至xxx数据库
使用show tables 查看当前数据库有哪些表
.sql结尾的文件被称为“sql脚本”。sql脚本:以.sql结尾,并且在文件中编写了大量的sql语句

常用命令:
select database();查看当前使用的哪个数据库
select version();查看mysql版本号
\c;结束一条语句
exit ;退出
show create table emp;查看创建表的语句

DQL

简单查询

语句语法:
select 字段名1,字段名2,字段名3… from 表名;

给查询结果的列重命名
select 字段名1 as 新名字1 from 表名;
//as可以省略
//有中文则‘xxx’
//查询所有字段,字段名处只需写一个*

SQL语句不区分大小写
字段名可以写表达式,例如数学运算 字段名1 *12

条件查询语法:
select 字段,字段
from 表
where 条件and条件or条件;

条件符号:< ,>,<>,<=,>=,between…and…闭区间,is null,is not null,

between…and…也可以用在字符上,左闭右开

and 和 or 多加括号

in作用等同于or 字段 in(值1,值2)例如 where job in (‘aasd’,‘asd’)
not in

like 模糊查询
%代表多个字符 _ 代表一个字符
select ename from emp where ename like ‘%o%’;//含有o的
select ename from emp where ename like ‘_o%’;//第二个字母是o的

order by 字段名 //排序,默认升序
order by 字段名 asc; //指定升序
order by 字段名 desc;//指定降序

当字段名1相同的时候,按照字段名2排序:
select name,sal from emp order by 字段名1 desc,字段名2 asc;

分组函数5个

分组函数是对”某一组“(某一列)数据进行操作

count 计数
sum 求和
avg 平均值
max 最大值
min 最小值

select sum(sal) from emp; //对emp表中sal求和
select max(sal) from emp; //找出最高ssal

注:**分组函数自动忽视NULL

count()和count(具体的字段)区别:
count(
)统计总的数据数;count(具体的字段)统计的是这个字段不为NULL的数据数

分组函数也能组合:
select count(),sum(),avg(sal) from emp;

单行处理函数

通过月薪sal计算年薪
select ename,sal*12 as yearsal from emp

注:计算式中有NULL,计算结果一定是NULL

ifnull(可能为null的数据,将其当作什么处理) //属于单行处理函数
ifnull(sal,0)
select ename,ifnull(sal,0)*12 as yearsal from emp

group by 和 having

group by:按照某个字段或某些字段进行分组
having:对分组之后的数据再次进行过滤

例:找出每个岗位的最高薪资
select max(sal),job from emp group by job;

如果再添加ename:select ename,max(sal),job from emp group by job;
会出现随机5个无意义的ename强行匹配
总结:当一条语句有group by的话 select只能跟参加分组的字段和分组函数

注:
分组函数常和group by联合使用
分组函数只会在group by执行之后执行
group by是在where之后执行

having例:
找出每个部门的最高薪资,要求显示薪资大于2500的数据
select max(sal),deptno from emp group by deptno;//先写上半句,再改进
select max(sal),deptno from emp group by deptno having max(sal)>2500;//效率低
再改进:select max(sal),deptno from emp where sal>2500 group by deptno;//where会先过滤,再分组

总结:where能解决就用where
where不能解决例:
找出部门平均薪资大于2000的
select avg(sal),deptno from emp group by deptno having avg(sal)>2000;
//这里不能用where,因为where后面不能使用分组函数

多字段联合分组
例:找出每个部门deptno不同岗位job的最高薪资sal
select
max(sal),job,deptno
from
emp
group by
job,deptno;

查询结果去重:

select后加上distinct
注:distinct只能出现在所有字段最前方,表示后面的字段联合去重

count(distinct job)去重之后统计数量
语法规则:

顺序
5 select 查出来
1 from 从哪里查
2 where 过滤
3 group by分组
4 having 再过滤
6 order by排序

分组函数不可直接出现在where语句中
错误:select ename,sala from emp where sal>avg(asl);//ERROR 1111:Invalid use of group function
原因:分组函数在group by之后,group by在where之后,冲突了
改正:select ename,sal from emp where sal>(select avg(sal) from emp);//先计算出平均工资,嵌套子查询

找出每个岗位的最高薪资
select max(sal),job from emp group by job;
如果再添加ename:select ename,max(sal),job from emp group by job;
错误:会出现随机5个无意义的ename强行匹配,有结果无意义
总结:**当一条语句有group by的话 select只能跟参加分组的字段和分组函数

UNION

将查询结果集相加

案例:找出工作是SALESMAN和MANAGER的员工
select ename,job from emp where job=‘SALESMAN’ or jor =‘MANAGER’;
select ename,job from emp where job in (‘SALESMAN’,‘MANAGER’);
select ename,job from emp where job=‘SALESMAN’ union select ename,job from emp where job=‘MANAGER’;

LIMIT

是mysql特有的
取结果集中的部分数据
语法:
limit startIndex,length
//startIndex表示其实位置,length表示取几个

案例:取出工资前5的
select ename,sal from emp order by sal desc limit 0,5;

//limit 最后执行

连接查询

连接查询
在多数开发中,都不是在单表中查询。需要多张表联合查询取出最终结果

查询连接的分类:

内连接:
等值连接:
非等值连接:
自连接:
外连接:
左外连接:
右外连接:
全连接:

笛卡尔乘积现象:
在表的连接查询的时候,如果没有条件限制,那么查询结果条数等于两张表条数乘积
select ename,dname from emp,dept;
改进:select e.ename,d.dname from emp e,dept d;//取别名,省略as。可以提升效率

避免笛卡儿积现象:添加条件
注:添加条件并不会减少记录比较次数。只是减少了显示的有效记录

外连接和内连接区别:

内连接:假设A和B表进行连接,凡是A和B能匹配上的数据查询出来。A、B没有主副之分。返回交集
外连接:A和B表进行外连接的时候,有一个是主表另一个是附表。主要查询主表,捎带查询附表
如果附表没有匹配上,会自动模拟null与之匹配

内连接

select e.name,d.name
from emp e,dept d
where e.deptno=d.deptno
//SQL 92 以后不适用

select
e.name,d.name
from
emp e
jion
dept d
on
e.deptno=d.deptno
//SQL99 常用
//join / inner join 省略了inner 内连接
//底层实际还是匹配了笛卡尔乘积那样那么多次

内连接中的等值连接

同上
语法

A
join
B
on
连接条件
where

内连接中的非等值连接

查找
select
e.name,s.sal,s.grade
from
emp e
jion
salgrade s
on
e.sal between s.losal and s.hisal;

自连接

特点是一张表看作两张
例:表emp找出每个员工的上级领导,要求显示员工名和对应领导名(员工号empno,员工名ename,对应领导号mgr)
select
a.ename,b.ename
from
emp a
jion
emp b
on
a.mgr=b.ename

注:自连接也能是非等量条件

外连接

最重要的是主表的数据无条件查询出来

和内连接区别:
内连接:假设A和B表进行连接,凡是A和B能匹配上的数据查询出来。A、B没有主副之分
外连接:A和B表进行外连接的时候,有一个是主表另一个是附表。主要查询主表,捎带查询附表
如果附表没有匹配上,会自动模拟null与之匹配

左外连接:左边是主表
右外连接:右边是主表

例:表emp找出每个员工的上级领导,要求显示员工名和对应领导名,必须显示所有员工
员工号empno,员工名ename,对应领导号mgr
所有都显示应该使用外连接
select
a.ename,b.ename
from
emp a
left outer jion
emp b
on
a.mgr=b.ename

//left jion 左连接 左主表。outer可以省略

//区分inner 和 outer 靠是否有left和right

三张表连接

多表连接语法:
A
join
B
join
C
on

//A先和B连接,然后再和C连接

内连接:

例:找出每个员工的部门名称和工资等级
emp表empno,ename,deptno,sal empno员工编号 ename员工名 deptno部门编号 sal 工资
dept表deptno,dname deptno部门标号 dname部门名称
salgrade表grade,losal,hisal grade等级 losal最低薪资 hisal最高薪资

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;

外连接

例:找出员工的部门名称,工资等级,上级领导
//要保留每一个员工,所以内连接工资等级,外连接上级领导

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
left join
emp e1
on
e.mgr=e1.empno;

//emp表的mgr字段表示领导编号

where后子查询

子查询:在select语句中嵌套select语句,被嵌套的称为子查询。
语法:
select
…(select)…
from
…(select)…
where
…(select)…

案例一:

select * from emp where sal>(select avg(sal) from emp);

案例二:找出每个部门平均薪资的薪资等级

第一步:找出部门平均薪水
select deptno,avg(sal) as avgsal from emp group by deptno;
第二步:把第一步的结果当作一个新表t,让t表和salgrade表连接,条件是t.avgsal between s.losal and s.hisal;
select t.*,s.grade
from t
join s
on t.avgsal between s.losal and s.hisal;

合并
select t.*,s.grade
from (select deptno,avg(sal) as avgsal from emp group by deptno) t
join s
on t.avgsal between s.losal and s.hisal;

from语句中使用,重点

案例三:找出每个员工所在部门名称,要求显示员工名和部门名·

select e.ename,e.deptno(select d.dname from dept d where e.deptno=d.deptno)as dname from emp;
//select子句中使用

DDL & DML

创建表

语法:
create table 表名(
字段名1 数据类型,
字段名2 数据类型,
字段名3 数据类型,

);

注:表名最好以t_ 或 tbl_ 开头

字段的常见数据类型
int 整数型
bigint 长整型
float 浮点型
char 定长字符串
varchar 不定长字符串
date 日期类型
BLOB 二进制大对象(图片、视频等)
CLOB 字符大对象(较大文本)

char和varchar怎么选择
char:固定分配长度,不够长补偿,超出报错 效率高
varchar:动态分配长度,超出报错 效率低

default关键字可以设置默认值

例如:创建学生信息表
学生信息:学号、姓名、性别、班级编号、生日
学号 bigint
姓名 varchar
性别 char
班级 int
生日 date

create table t_student(
no bigint,
name varchar(255),
sex char(1),
classno varchar(255),
birth char(10)
);

create table t_student(
no bigint,
name varchar(255),
sex char(1) default 1,
classno varchar(255),
birth char(10)
);
//sex 默认值是1

创建表,加入约束

常见约束:
非空约束 not null 不能为null
唯一约束 unique 不能重复
主键约束 primary key 既不能null也不能重复
外键约束 foreign key

检查约束 check Oracle有MySQL没有

非空约束not null

案例:
drop table if exists t_user;
create table t_user (
id int,
username varchar(255) not null,
password varchar(255)
);
insert into t_user(id,username,password)values(1,‘123’,‘abc’);//成功
insert into t_user(id,password)values(1,‘abc’);//失败,ERROR 1364:Field ‘username’ doesn’t have a default value

唯一性约束

不能重复,但可以为null,或者多个null。单个字段唯一性约束//列级约束
案例:
drop table if exists t_user;
create table t_user (
id int,
username varchar(255)
unique,
password varchar(255)
);
insert into t_user(id,username)values(1,‘abc’);//成功
insert into t_user(id,username)values(1,‘abc’);。//失败,ERROR 1062:Duplicate entry ‘abc’ for key ‘t_user.username’

**两个字段"联合"起来具有唯一性//又称表级约束
create table t_user (
id int,
username varchar(255),
password varchar(255),
unique(username,password)
);

主键约束

案例:
drop table if exists t_user;
create table t_user (
id int primary key,
username varchar(255) unique,
password varchar(255)
);
insert into t_user(id,username,password)values(1,‘123’,‘abc’);

作用:这行记录在表中的唯一标识

主键分类:
根据主键字段数量:单一主键(推荐)、符合主键
根据主键性质:自然主键(推荐)、业务主键

主键数量:只能有一个

注:
MySQL提供主键自增: auto_increment
例:
drop table if exists t_user;
create table t_user (
id int primary key auto_increment,
username varchar(255) unique,
password varchar(255)
);

外键约束

外键约束:foreignkey
外键字段:添加外键约束的字段
外键值: 外键字段中的每个值

业务例子:
设计数据库表维护学生和班级信息
班级表:班级编号(主键),班级名
学生表:学生编号(主键),学生名,班级编号(外键) //填了fk之后,字段里面的值必须来自某个字段

语法
foreign key(子表字段) references 父表名(父表字段)

外键值可以为null

外键引用别的表的字段,被引用字段不一定是主键,但必须有唯一性unique

案例:
以上条件下,学生表是子表,班级表是父表。先创建父表再创建子表,删除的时候先删除子表,添加的时候先附表。

drop table if exists t_class;
drop table if exists t_student;
create table t_class(
cno int ,
cname varchar(255),
primary key(cno)
);
create table t_student(
sno int,
sname varchar(255),
classno int,
primary key(sno),
foreign key(classno) references t_class(cno)
);
insert into t_class values(101,‘xxxxxxxxxxxx’);
insert into t_class values(102,‘xxxxxxxxxxxx’);
insert into t_student values(1,‘zs1’,101);
insert into t_student values(2,‘zs2’,101);
insert into t_student values(3,‘zs3’,102);
insert into t_student values(4,‘zs4’,102);
insert into t_student values(5,‘zs5’,102);

select *from t_class;
select *from t_student;

insert into t_student values(5,‘zs5’,103);
错误:ERROR 1452 Cannot add or update a child row: a foreign key constraint fails

插入数据

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

insert into t_student(no,name,sex,classno,birth) values (1,‘zhangsan’,‘1’,‘gaosan1ban’ );
//错误:ERROR 1136 (21S01): Column count doesn’t match value count at row 1

insert into t_student(no,name,sex,classno,birth) values (1,‘zhangsan’,‘1’,‘gaosan1ban’, ‘190-10-12’);
//成功:Query OK, 1 row affected (0.00 sec)

改顺序:
insert into t_student(name,sex,classno,birth,no) values (‘lisi’,‘1’,‘gaosan1ban’, ‘190-10-12’,2);
//成功:Query OK, 1 row affected (0.00 sec)

如果字段不齐全,自动在其他字段补null
insert into t_student(no,name) values (3,‘wangwu’);
//插入: 3 | wangwu | NULL | NULL | NULL

表的复制nb

create table t_stu as select * from t_student;

语法:
create table 表名 as select 语句;

将查询结果插入
insert into 表名 select 语句;

修改数据 update

语法:
update 表名 set 字段名1=值1,字段名2=值2… where 条件;
注意:没有条件表示表全部更新

案例:把学号3改成13
update t_stu set no=13 where no=3;

删除数据

语法:
delete from 表名 where 条件;
注意:没有条件表示表全部删除

删除大表

truncate table t_stu;//表被截断 ,不可回滚,永久丢失

事务,TCL

一个事务是一个完整的业务逻辑单元,不可再分
一个事务就是多条DML捆绑在一起
例:银行账户转账,从A账户转到B账户
update t_tact set balance=balance -10000 where actno=‘act-001’;
update t_tact set balance=balance +10000 where actno=‘act-002’;
以上两条语句必须同时成功或者同时失败。这时就需要使用“事务”机制

和事务相关的只有DNL语句(insert、delete、update)

事务的语句TCL:commit 提交 , rollback 回滚 ,savepoint 保存点

事务的特性:
原子性:事务是最小逻辑结构,不可再分
一致性:事务必须保证所含的DNL语句同时 成功或失败
隔离性:事务A与B之间具有隔离
持久性:最终数据必须持久化到硬盘,事务才算结束

事务之间的隔离性: 4各级别
第一级别:读未提交Read Uncommitted,当前事务可以读到对方事务未提交的数据,存在脏读现象
第二级别:读已提交Read Committed,对方事务提交之后的数据,我方可读取,解决了脏读,但存在不可重复的
第三级别:可重复读Repeatable Read,解决了不可重复读,存在读取的数据是幻像
第四级别:两个事务不能并发Serializable,序列化/串行化,存在效率低

mysql默认第三级别,事务默认情况自动提交–执行一条DML语句就提交
关闭自动提交:start transaction;

rollback;//回滚到上一次的提交点,事务结束,下次需再次开启事务

案例:
create 建表
插入数据; //自动commit
start transaction;//关闭自动提交,开启事务
insert …;
insert …;
select …; //能查出三行数据
rollback;//回滚,事务结束,下次需再次开启事务
select …;// 只有一条数据

start transaction;//再次开启事务
insert …;
insert …;
select …; //查出三行数据
commit; //提交数据,事务结束
select …; //查出三行数据
rollback;//回滚,回滚无效

索引

索引:相当于书的目录,在数据库,查询数据的时候有两种方式,一种是全表扫描;另一种是根据索引检索(效率高)
原理:缩小了扫描的范围

select ename from emp where ename= ‘asd’;
ename 没有索引的时候,会进行全表扫描
ename有索引的时候,会根据索引扫描

创建索引

create index 索引名称 on 表名(字段名);

删除索引

drop index 索引名称 on 表名;

什么情况下加索引

1、数据量很大
2、字段很少DML操作(字段进行DML操作,索引需要维护)
3、经常出现在where子句中

注:主键和具有UNIQUE约束的字段会自动添加索引。所以根据主键查找效率高

索引的原理:B+树

索引分类:
单一索引:给单个字段添加索引
复合索引:几个字段联合起来添加索引
主键索引:主键字段自动添加索引
唯一索引:unique字段自动添加索引

索引失效
1、select ename from emp where ename like ‘%A%’; //模糊查询,第一个通配符使用%,会失效

视图

对于同一张表,通过不同角度去看

创建视图
create view myview as select empno,ename,from emp;

删除视图
drop view myview;

注:可以对视图进行增删改查,但是会影响原表数据。

作用:
可以隐藏表的实现细节

三范式

第一范式
任何表都有主键,属性字段不可再分

第二范式
所有非主键字段完全依赖于主键,不能部分依赖
例:多对对,三张表,两个外键
t_student 学生表
sno(pk)	sname
 --------------------------
1	张三
2	李四
3	王五
4	赵六

t_teacher教师表
tno(pk)	tname
 -------------------
1	王老师
2	张老师
3	李老师

t_student-teacher教师学生表
id(pk)	sno(fk)	tno(fk)		
 --------------------------
1	1	3
2	1	1
3	2	2
4	2	3
5	3	1
6	3	3

第三范式
所有非主键字段,直接依赖主键,不能传递依赖
一对多,两张表,”多“的表加外键
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值