分类:
DCL(Data Control Language):数据控制语言,用来哦定义访问权限和安全级别)
DDL(Data Definition Language):数据定义语言。对于库和表的操作
DML(Data Manipulate Lanaguage):数据操作语言。对数据的增删改
DQL(Data Query Language):数据查询语言,对数据进行查询
TCL(Transition Control Language):事务控制语言。
DCL:数据控制语言
- 创建用户:
创建了一个用户名为jsoft,在任意ip地址上都能登录,密码是Mys123456的用户。duo
create user 'jsoft'@'%' identified by 'Mys123456';
- 修改密码:
5.7版本需要使用password()修改密码
set password for jsoft@'%'=password('123456');
8.0版本修改密码
set password for jsoft@'%'='123456';
- 给用户授权
create:可以创建数据库
select:可以查询数据库
delete:可以删除数据
update:可以更新数据
insert:可以插入数据
all:所有权限
语法:grant 权限1,权限2.....on 数据库.*to 用户名@IP地址
grant all on `admin`.*to `jsoft`@`%`
- 撤销权限
revoke all on `admin` .* from `jsoft`@`%`;
- 查看权限
show grants for `jsoft`@`%`;
- 删除用户
drop user `jsoft`@`%`;
DDL:主要在定义或者改变表的结构。主要的命令:CREATE,ALTER,DROP等
- 创建表:
create table 表名(
字段名1(列名) 类型(宽度) 约束条件
字段名2(列名) 类型(宽度) 约束条件,
字段名3(列名) 类型(宽度) 约束条件,
........
);
- 常用的数据类型
(1) 整型 tinyint:-128~127
smallint:2字节
mediumint:3字节
int:4字节
bigint:8字节
在使用中,可以设置成无符号。tinyint(无符号),0~255,unsigned
(2)浮点型 float(m,d):4字节 单精度浮点型
double(m,d):8字节,双精度浮点型
decimal(m,d):对应我们java的BigDecimal m总长度 d 小数位数
float(5,3)
插入的数据是:123.45678。最后得到的结果是99.999
插入的数据是:12.34567。最后得到的结果是12.346
在使用浮点型的时候,注意陷阱,要以插入数据库中的实际结果为准。
(3)字符串类型 char:固定长度,最多255个字符。
varchar:可变长度,最大容量65535个字符
tinytext:可变长度,最多255个字节。
mediumtext:可变长度,16MB
longtext:可变长度,4GB
varchar和text区别?
text:不能设置默认值,有溢出存储。
varchar:可以设置默认值
(4)日期和时间类型
date:日期 2023-01-30
time:时间,08:49:30
datetime:日期时间,2023-01-30 08:49:30
timestamp:时间戳。毫秒数。自动存储记录的修改时间。(mysql5.7以后)
- 建表约束
(1)NOT NULL:非空约束
(2)UNIQUE:唯一约束,不能重复
(3)PRIMARY KEY:主键约束,自带非空,唯一索引
(4)DEFAULT:默认值
(5)FOREIGN KEY:外键约束
创建一张author表
create table author(
`aut_id` INT,
`aut_name` varchar(50) NOT NULL,#非空约束
`gender` char(1) default `男`
`country` varchar(50),
`birthday` datetime,
primary key(aut_id,aut_name);
创建一张book表
create table `book`(
`id` int primary key auto_increment,
`name` varchar(50) not null,
`bar_code` varchar(30) not null unique,
`aut_id` int not null --作者的编号
)
主键约束:(主键)
主键分为单字段主键和多字段联合主键
注意:
每个表只能定义一个主键
主键值必须唯一,不能为NULL,表中不能存在有相同主键值的两行数据。
一个字段名只能联合主键字段表中出现一次。
联合主键用要慎重
create table author(
`aut_id` INT,
`aut_name` varchar(50) NOT NULL,#非空约束
`gender` char(1) default `男`
`country` varchar(50),
`birthday` datetime
);
create table author(
`aut_id` INT,
`aut_name` varchar(50) NOT NULL,#非空约束
`gender` char(1) default `男`
`country` varchar(50),
`birthday` datetime
primary key(aut_id)
);
外键约束:FOREIGN KEY
外键约束维护的是表与表之间的关系。规定了当前列的数据必须来自于一张其他表的某一列中的值。
逻辑外键:在查询的时候,通过SQL的多表联查,临时使用的一种语法。
物理外键:在查询的时候,通过SQL添加的外键,可以看见的外键,约束能力很强。
create table `book`(
`id` int primary key auto_increment,
`name` varchar(50) not null,
`bar_code` varchar(30) not null unique,
`aut_id` int not null,
foreign key (aut_id) references author(aut_id)
);
对标的修改操作
切换库:use 库名;
显示当前库中的所有表:show tables;
查看表结构:desc 表名;
添加列:
alter table author add(
hobby varchar(20),
address varchar(50)
);
4.修改表:
- 修改表的数据类型
alter table author modify address varchar(100);
- 修改列名
alter table author change address addr varchar(60);
- 删除列
alter table author drop addr;
- 修改表名
alter table author rename `authors`;
删除表:
drop table if exists `author`;
DML(数据操作语言)(重要)
用来对表记录进行增删改
- 插入数据
insert into author(
aut_name,gender,country,birthday)values
('金庸`,`男`,`中国`,`1924-3-10`);
#批量插入
insert into author
values
(null,`韩寒`,`男`,`中国`,`1982-9-23`),
(null,`海明威`,`男`,`美国`,`1982-9-23`);
- 修改数据
(1)修改某列的全部值
update `author` set `country`=`中国`;
(2)修改某一条数据的某列的值
UPDATE `author` set `country`=`英语` where aut_id=2;
where关键字:=,!=,<>,<,>,<=,>=,between...and,in(...),is null, not,or,and...
where aut_id>1;
where aut_id in(1,3,5);
where aut_id between 1 and 4;
where aut_id>1 and aut_name=`xxx`;
where aut_name is null;
where aut_name is not null;
- 删除数据
delete from author where aut_id=4;
全部删除:
delete from author;
truncate:截断表,删除表中的全部数据
truncate table author;
面试题:数据库中表的数据的删除有几种方式?
drop
truncate
delete
面试题:truncate和delete的去别的?
主键的问题
truncate效率高,可以理解为把表删除了,又重新创建了这个表。
truncate实际上是一个DDL,不能回滚(事务)
truncate和delete都不会对表结构约束索引不会改变。
DQL数据查询语言
搭建环境:
create table student(
id int primary key auto_increment,
`name` varchar(10),
age int(5) not null,
gender varchar(2)
)
create table course(
id int primary key auto_increment,
`name`varchar(20),
t_id int
)
create table scores(
s_id int,
score int,
c_id int,
primary key(s_id,c_id)
)
- 基础查询
- 基础查询:
查询某一张表的所有数据。(实际上不建议写*)
select * from student;
#查询指定的的列
select id,name from student;
#去重
select distinct gender from student;
- 列运算
select id,name,age*10 from student;
注意:
null和任意数字做运算,结果都是NULL
字符串和数字做计算额,如果能转成数字,则会转成数字继续计算。如果无法转换成数字,把字符串当作0处理。
- 别名
select id as '编号',name as '姓名',age as '年龄' from student;
select id '编号',name '姓名',age '年龄' from student;
- 条件筛选
select * from student where id=3;
select * from student where id in(1,3,7);
select * from student where id>5;
select * from student where id between 3 and 7;
select * from student where id between 3 and 7 or age>50;
- 模糊查询
select * from student where name like "马_";
select * from student where name like "马%“;
- 排序(默认是升序)
asc:升序
desc:降序
select * from student order by age;
select * from student order by age asc;
select * from student order by age desc;
- 聚合函数(统计)
count:查询满足记录条件的记录数
select count(1) from student where gender="女”;
如果列值为空,不会进行统计
max:查询满足条件的记录中的最大值
select max(age) from student;
min:查询满足田间的记录的最小值
select min(age) from student;
sum:求和(忽略null值)
select sum(salary) from employee;
avg:平均数
select avg(age) from student;
- 分组查询
分组查询就是将原有的数据进行分组统计。group by
select gender,avg(age) from student group by gender;
select gender,avg(age) from student where gender='男' group by gender;
#先筛选人,再分组
select gender,avg(age) from student where age>50 group by gender;
#先分组,再筛选人
select gender,avg(age) from student group by gender having avg(age)>55;
面试题:
having和where的区别?、
(1)作用的位置
(2)作用的范围
(3)作用的效果
分页查询(不同的数据库产品,语法不一样)
limit关键字
select * from student limit 0,4
select * from student where gender='男' order by age desc limit 0,4;
limit字句分页查询永远在最后。
oracle:rownum
sqlserver:top
多表查询
一:笛卡尔积
如果我们的查询条件相对比较复杂,需要涉及多张表,如果是两张无关的表联合查询,列出所有可能的结果,两张表的数据的积,就是我们数据库层面的笛卡尔积。
在开发中,禁止出现笛卡尔积。
二:多表查询SQL
SQL92语法:
#查询每科课程对应的老师。
select c.name as `cname`,t.name as `tname` from course c,teacher t where c.t_id=t.id;
注意:
如果不需要查询所有列,在select后就用表名.列名的形式来查询想要的列。
表名是可以起别名,一旦表名起了别名,就必须使用别名,不能用原来的表名。
需要使用到where关键字来进行条件的关联。
SQL99语法:
内连接:
在我们刚才的sql中,使用逗号分隔两张表进行查询。
select c.id,t.name,c.name from teacher t inner join course c
on t.id=c.t_id where c.id=1;
实际上就是根据条件,找到表A和表B的数据的交集。
外连接(常用):
内连接和外连接的区别:
对于内连接中的两张表,若【驱动表】中的记录在【被驱动表】中找不到与之匹配的记录,则该记录不会被加入到最后的结果集中。
对于外连接中的两张表,即使【驱动表】中找不到与之匹配的记录,也要将该记录加入到最后的结果集中,可以分为【左外连接】和【右外连接】。
左外连接
select c.id,c.·name·,t.·name· from course c left outer join teacher t on c.t_id=t.id;
--等价于
select c.id,c.name,t.name from course c left join teacher t on c.t_id=t.id;
左表中的英语这门课是没有与之匹配的老师,但是英语课程也显示出来了,同时给他匹配了一个对应的老师的值是null。
右外连接
select c.id,c.·name·,t.·name· from course c right outer join teacher t on c.t_id=t.id;
--等价于
select c.id,c.name,t.name from course c right join teacher t on c.t_id=t.id;
右表中的孙子这个老师是没有与之匹配的课程,但是孙子也显示出来了,同时给他匹配了一个对应的课程的值是null。
全连接
select * from teacher t full outer join course c on c.t_id=t.id;
虽然我们的mysql不支持上面的写法,我们可以采用联合查询的方法来实现这种效果。
select * from teacher t left join course c on t.id=c.t_id;
union
select * from teacher t right join course c on t.id=c.t_id;
三:子查询
标量子查询:结果集只有一行一列
列子查询:结果集只有多行一列
行子查询:结果集只有一行多列
表子查询:结果为多行多列
where/having型子查询
查询比马化腾大的所有学生
SELECT * from student where age>(select age from student where name='马化腾')
查询有一门学科分数大于90分的学生的信息
select * from student where id in(select s_id from scores where score>90)
查询男生且年龄最大的学生的信息
SELECT * from student WHERE age=(select max(age) from student GROUP BY gender HAVING gender='男');
总结:
where型子查询,如果where列=内层sql,则内层sql返回的必须是单行单列。
where型子查询,如果where列in(内层sql),内层sql返回必须是单列,可以多行。
from型子查询
查询数学成绩排名前五的学生,正序排列。
select * from (
select s.id,s.gender,s.name,sc.score,c.name as cname
from student s
left join scores sc on sc.s_id=s.id left join course c on c.id=sc.c_id where c.name='数学' order by sc.score desc limit 0,3
)t where t.gender='男' order by t.score asc;
select型子查询
查询每个老师代课的数量。
select t.id,t.name,count(*) '代课的数量'
from teacher t
left join course c
on t.id=c.t_id
group by t.id,t.`name`;
--子查询
select t.id,t.name,(
select count(*) from course c where c.t_id=t.id
) as '代课的数量' from teacher t;
exists型子查询
表示判断子查询是否有返回值(true/false),有则有返回值,没有则返回false
select * from teacher t where EXISTS(
SELECT * from course c where c.t_id=t.id
)
MYSQL常用函数
聚合函数
count:统计
min:最小值
max:最大值
sum:求和
avg:平均值
数值型函数
CEILING:向上取整
FLOOR:向下取整
ROUND:四舍五入
PI:圆周率
RAND:0-1的随机数
TRUNCATE(X,D):截断 X小数 D想要几位小数。
字符串函数
日期和时间函数
获取时间和日期
获取日期
select CURDATE();
select CURRENT_DATE;
获取时间
select CURTIME();
selectt CURRENT_TIME;
获取时间和日期
select NOW();
select SYSDATE();
时间戳和日期转换
获取时间戳
select UNIX_TIMESTAMP();
时间戳的转换
select FROM_UNIXTIME(UNIX_TIMESTAMP());
根据日期获取年月日
select MONTH(SYSDATE());
select MONTHNAME(SYSDATE());
select DAYNAME(SYSDATE());
select DAYOFWEEK(SYSDATE());
时间日期计算函数
select CURDATE(),CURRENT_DATE+5;
select DATE_ADD("2023-1-31",INTERVAL 1 DAY);
计算时间间隔
select DATEDIFF("2023-1-31“,”2023-1-31");
日期的格式化
select DATE_FORMAT(SYSDATE(),"%W %M %D %Y")
select DATE_FORMAT(SYSDATE(),"%W %M %D %Y %p %h:%i")
加密函数
select MD5("123456");
流程控制函数
select IF(expr1,expr2,expr3)
expr1表达式是真,返回2,如果是假,返回3
select IF(1>2,2,3)
select IFNULL("abc","hahaha");
如果第一个函数为null,则取第二个参数的值。
select NULLIF(expr1,expr2)
如果expr1=expr2,返回null,否则返回expr1
备注:还有其他的流程控制函数,比如:
case....when...otherwise;
when...then...else;