数据库的概念:
长期存放在计算机内,有组织、可共享的大量数据的集合,是一个数据“仓库”。
作用:存放,管理数据
分类:关系型数据库,NoSQL数据库
MySQL特点:1操作便捷 2小巧,功能齐全3免费、开源的数据库 4可运行于windows或linux系统
数据库结构
库的操作 | 代码书写 |
---|---|
创建一个库 | create database 库名 |
删除一个库(危险操作) | drop database 库名 |
使用库(切换工作库) | use 库名 |
表的操作 | 代码书写 |
---|---|
查看库中的所有的表 | show tables |
创建一个表 | create table 表名(字段名 字段类型,字段名 字段类型) |
查看表结构 | desc 表名 / show create table 表名 |
查看mysql的存储引擎 | show engines; |
修改表结构 | alter table 表名 关键词 属性 |
给表添加字段 | alter table 表名 add 字段名 数据类型 |
删除一个字段(危险操作) | alter table 表名 drop 字段名 |
删除表(危险操作) | drop table 表名 |
方法 | 代码书写 |
---|---|
modify —覆盖式,类型和属性修改,不能修改字段名 | alter table 表名 modify 字段名 数据类型 |
change — 覆盖式 ,字段名 类型 属性 都可以修改 | alter table 表名 change 旧字段名 新的字段名 类型 属性 |
非空约束 | 唯一约束 | 主键约束 | 外建约束 |
---|---|---|---|
not null | unique | primary key | foreign key |
用not null约束的字段不能为null值,必须给定具体的数据
unique约束的字段,具有唯一性,不可重复,但可以为null
create table test(
id int(10),
name varchar(32) not null,
email varchar(123),
unique(email)
);
主键(primary key)是表中的一个或多个字段,它的值用于唯一的标识表中的某一条记录
表中的某个字段添加主键约束后,该字段为主键字段,主键字段中出现的每一个数据都称为主键值
主键约束与“not null unique”区别
1、作为Primary Key的域/域组不能为null,而Unique Key可以。
2、在一个表中只能有一个Primary Key,而多个Unique Key可以同时存在。unique not null 可以
将表的一列或多列定义为唯一性属性,而primary key设为多列时,仅能保证多列之和是唯一的,
具体到某一列可能会重复。
3、更大的区别在逻辑设计上。Primary Key一般在逻辑设计中用作记录标识,这也是设置
Primary Key的本来用意,而Unique Key只是为了保证域/域组的唯一性。
一张表应该有主键字段,如果没有,表示该表无效
主键值:是当前行数据的唯一标识、是当前行数据的身份证号
即使表中两行记录相关数据相同,但由于主键值不同,所以也认为是两行不同的记录
按主键约束的字段数量分类
无论是单一主键还是复合主键,一张表主键约束只能有一个(约束只能有一个,但可以作用到好几个字段)
单一主键:给一个字段添加主键约束
复合主键:给多个字段联合添加一个主键约束(只能用表级定义)
create table tb7(
id char(18) primary key, -- 主键约束
name varchar(10),
age int
)
一个表只能有一个主键约束,一个表中可以有多个not null unique
逻辑上的主键标识
create table tb10(
name varchar(10),
age int,
sex char(1),
primary key(name,age) -- 联合主键约束
)
自增的主键约束
create table tb11(
id int primary key auto_increment, -- 自增的主键约束
name varchar(10),
age int
)
外键可以为null
一张表中可以有多个外键
create table a(
aid int primary key auto_increment,
aname varchar(10)
)
create table b(
bid int primary key auto_increment,
bname varchar(10),
aid int, -- b表外键
foreign key(aid) references a(aid) -- 外键约束,表级定义方式
)
增加数据(insert)
insert into 表名(字段名,字段名,…,字段名) values(值,值,…,值)
-- 日期类型的值 用字符串的形式来表示
-- 全字段插入
insert into student(sid,sname,birthday,ssex,classid) values(9,'张三','2000-1-1','男',3);
insert into student values(10,'李四','2001-2-2','女',2);
插入默认值default
-- 插入默认值
insert into student values(default,'王五','2002-3-3','女',3);
设置默认值修改表结构
alter table student MODIFY ssex varchar(10) not null default '男';
非空约束必须不能为null
-- 非空约束必须不能为null
insert into student values(null,'钱七','2004-5-5',null,2);
选择字段插入,非空的字段必须要有默认值否则报错
-- 选择字段插入
-- 非空的字段必须要有默认值否则报错
insert into student(sname) values('老八');
一次性插入多条数据
-- 一次性插入多条数据
-- 方式一(最常用的,一定要学会哟~)
insert into student(sname,birthday)
values('张大宝','2006-2-2'),('张小宝','2007-3-3'),('张中宝','2007-1-1')
修改 update
update 表名 set 字段名=值,字段名=值,…,字段名=值 【where 条件】
update newstu set sname='赵蕾蕾' where sid = 1
例题: 如果这个学生不是女 就把性别改为猛男
update newstu set ssex = '猛男' where ssex <> '女'
-- 范围型
-- 方式一:
update newstu set ssex ='帅哥' where sid >= 2 and sid <=8
-- 方式二: between and 语句
update newstu set ssex='靓女' where sid between 2 and 8
-- 错误逻辑 (正确: between 后面的数值较小 and 后面数值较大)
update newstu set ssex = '美女' where sid between 8 and 2
-- mysql 尽量减少IO操作,来降低磁盘的负载
update newstu set ssex = '猛男' where sid >= 1 and sid <=10
-- 1,3,4,6,8 靓女
update newstu set ssex = '靓女'
where sid = 1 or sid = 3 or sid = 4 or sid = 6 or sid = 8;
删除
-- 删除
-- delete from 表名 【where 条件】
全删
-- 全删
delete from stu1
根据条件删除
delete from newstu where sid = 1
delete from newstu where ssex = '猛男'
delete from newstu where sid between 3 and 15
清空表
truncate 表名
truncate newstu
# DQL 数据查询语言
-- 所有的查询都会得到一个虚拟表
-- 最简单的查询
select 1
select 'hello'
select 2+3
-- 从表中查询数据
-- 全字段查询
select sid,sname,birthday,ssex,classid from student
-- 不推荐 * 代替字段
select * from student
-- 选择字段查询
select sname,ssex from student
-- 给字段起别名
select sname as '姓名',ssex '性别',birthday 生日 from student
-- 添加一个常量字段
select sname as '姓名',ssex '性别',birthday 生日,1 学校 from student
-- 去除重复
-- distinct 修饰的所有字段的值一致时去除重复
select distinct sid, sname, ssex from student
-- 带条件的查询
-- where 关键词数据表中的每一条数据进行条件筛选
select * from student where sid = 2
select * from student where ssex = '女'
-- 班级编号为1班的男同学
select * from student where ssex = '男' and classid = 1
-- 学生编号3-6的学生
select * from student where sid >=3 and sid <=6
select * from student where sid between 3 and 6
-- 查询出学生表中大于1990-1-1出生的学生
select * from student where birthday < '1990-1-1'
like模糊查询
select * from student where sname like '%侯%'
_ 一个任意字符
select * from student where sname like '侯_'
in 某个特定的范围(推荐,不推荐使用or)
语法:SELECT * FROM 表名 WHERE 字段 IN (值1,值2…);
其中:
select * from student where sid in(1,3,4,7,9,300,4000,50000)
is是对null的处理
其中:
NULL代表“无值”;
区别于零值0和空符串;
只能出现在定义允许为NULL的字段;
须使用 IS NULL 或 IS NOT NULL 比较操作符去比较。
select * from student where birthday is null
select * from student where birthday is not null
函数名 | 返回值 |
---|---|
avg() | 返回指定列的平均值 |
count() | 返回指定列中非null值的个数 |
min() | 返回指定列的最小值 |
max() | 返回指定列的最小值 |
sum() | 返回指定列的所有制之和 |
count() —统计个数,但不统计null
select count(sid) from student
select count(sname) from student
select count(ssex) from student
select count(*) from student
select count(1) from student
select count('猿究院') from student where classid = 1
sum() — 总和
select * from sc
select sum(score) from sc where sid=2
avg() – 平均值
select avg(score) from sc
max() — 最大值
select max(score) from sc
min() — 最小值
select min(score) from sc
GROUP BY
-- 统计出男同学 和 女同学的人数
select count(*) from student where ssex = '男'
select count(*) from student where ssex = '女'
select ssex,count(*) from student group by ssex
-- 每个学生的平均分
select sid,avg(score) from sc group by sid
-- 每个学生及格成绩的总分数
select sid,sum(score) from sc where score >= 60 group by sid
HAVING
与GROUP BY结合使用,进行分组后的数据筛选。
-- 统计学生及格成绩总成绩 高于100分 拿到
-- having 分组聚合后结果集进行条件筛选
select sid,sum(score) from sc group by sid having sum(score) > 100
select sid,sum(score) from sc where score >= 60 group by sid having sum(score)>100
order by排序
语法:SELECT * FROM 表名 ORDER BY 字段名 [DESC|ASC]
select * from student order by sid desc
select * from sc order by score desc , cid asc
limit 分页
语法:SELECT * FROM 表名 LIMIT [0开始下标,索引, 步长 ]
select * from student limit (页码-1)*步长,步长
-- limit 确定的常量(Java逻辑中)
-- select * from student limit (1-1)*3,3
非等值联查(语法是没有问题的,但查到的是笛卡尔积)
select * from student,class
等值查询(交集)内联查询
方式一:使用and连接
select * from student ,class,sc
where student.classid = class.classid and
student.sid = sc.sid and ssex = '男'
方式二:使用inner join
select * from student
inner join class on student.classid = class.classid
inner join sc on student.sid = sc.sid
where ssex = '男'
连接查询:
语法:SELECT * FROM 表1 LEFT|right|INNER JOIN 表2 ON 条件
外联查询
left join 左外联 查询语句中left join 前面的是主查表
1. left join 左外联
select * from student
left join class on student.classid = class.classid
left join sc on student.sid = sc.sid
right join 右外联 查询语句中 right join 后面的是主查表
2. right join 右外联
select student.*,class.*,sc.* from class
right join student on student.classid = class.classid
left join sc on student.sid = sc.sid
union 将两个结果集并一个结果集中
-- 学校的人名
select sname from student
union -- 将两个结果集并一个结果集中
select tname from teacher
union all 是求两个查询的并集,但是不会把重复的过滤掉,而是全部显示出来
select sname from student
union all
select tname from teacher
**子查询:**子查询,也叫内部查询(查询语句中又有一个查询(里面的查询称为子查询)执行子句,再执行父句)
查询id最大的一个学生(使用排序+分页实现)
select * from student order by sid desc limit 1
查询id最大的一个学生(使用where子查询实现)
select * from student where sid = (select max(sid) from student)
查询每个班下id最大的学生(使用where子查询实现)
select * from student where sid in (
select max(sid) from student group by classid
)
把内层的查询结果当成临时表,供外层sql再次查询。查询结果集可以当成表看待。临时表要使用一个别名。
查询大于5人的班级名称和人数(不使用子查询)
select classname,cound(sid) from class left join student on class.classid = student.classid group by classname having count(sid) >5
查询大于5人的班级名称和人数(使用from型子查询)
select classname,c from class
left join (select classid,count(sid) c from student group by classid) t
on class.classid = t.classid
where c > 5
子句有结果父句执行,子句没结果父句不执行
学生表中有外星人同学查询出所有的老师
select * from teacher
where exists (select * from student where ssex = '外星人')
any 子查询:表示满足其中任意一个条件(some 子查询和any 子查询一样)
select * from student where ssex = any("男","女")
all 子查询:表示满足所有条件,用法和all 一样
5.特殊的语句格式
IF(expr1,expr2,expr3)
expr1 表达式
expr2 成立结果
expr3 不成立结果
select tid,tname,if(tsex=1,'男','女') tsex,tbirthday,taddress from teacher
IFNULL(expr1,expr2)
expr1 字段
expr2 如果字段为null时显示
select sid,sname,ifnull(birthday,'这个人太可怜了,没有生日')bir,ssex from student
case when then end 语句
select tid,tname,
case tsex
when 1 then '男'
when 0 then '女'
else '未知'
end
,
tmoney from teacher
select tid,tname,
case
when tsex > 1 then '男'
when tsex = 1 then '女'
when tsex < 1 then '零'
else '意外'
end
,tmoney from teacher
事务(Transaction),就是将一组SQL语句放在同一批次内去执行,如果一个SQL语句出错,则该批次内的所有SQL都将被取消执行。
事务的特点:
一个事务中如果有一个数据库操作失败,那么整个事务的所有数据库操作都会失败,数据库数据就会回滚到该事务开始之前的状态。
事务的ACID原则(特性)
事务的隔离性
什么是事务的隔离性:为了让不同的事务之间相互不存在干扰,就需要对事务的操作进行隔离,事务的隔离性也就是将操作同一个数据的事务相互分离,让操作之间分开有序的执行
用什么方式实现事务的隔离性:通常数据库里都是采用锁的机制,保证事务之间的隔离性。
事务的隔离级别
什么是慢查询 ?
MySQL默认10秒内没有响应SQL结果,则为慢查询
什么是索引?
索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。
索引的优点:
索引的缺点
索引的分类
视图是从一个或者几个基本表(或视图)导出的表。它与基本表不同,是一个虚表。
创建一个视图
create view 视图名【view_xxx\v_xxx】 as 查询语句
create view v_stu_man as
select * from student
where ssex = '男';
使用视图
select
*
from
v_stu_man;
删除视图
drop view 视图名
drop view v_stu_man
什么是存储过程
存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后,再次调用不需要重复编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。
为什么使用存储过程
创建存储过程
CREATE PROCEDURE 存储过程名【proc_xxx】 (形参列表)
BEGIN
DECLARE 变量 变量类型
END
delimiter $$ 定制定界符
创建一个简单的存储过程
delimiter $$
create procedure proc_stu()
begin
select * from student;
end $$
delimiter ;
使用存储过程
call proc_stu()
带参的存储过程
参数:
delimiter $$
create procedure proc_test(
in x int, -- in 只入参
out y int, -- out 只出参
inout z int -- inout 出入参
)
begin
set x = x+1;
set y = y+100;
set z = z+1000;
end $$
delimiter ;
存储过程与函数的区别
存储过程的缺陷
什么是触发器
触发器是数据库中针对数据库表操作触发的特殊的存储过程。
# 触发器
-- 隐式执行
-- CREATE TRIGGER 触发器名【trig_xxx】
-- BEFORE/AFTER -- 触发顺序
-- INSERT/UPDATE/DELETE -- 触发事件
-- ON 数据库.表名 -- 事件表
-- FOR EACH ROW
-- BEGIN
-- 触发器内容 -- 事件出发后要写的语句
-- END$$
-- 删除学生
delete from student where sid = 2;
select * from student;
select * from sc;
delimiter $$
create trigger trig_delstu_delsc
before delete on student for each row
BEGIN
-- old 已经存在的数据 new 还不存在
delete from sc where sid = old.sid;
END $$
delimiter ;
-- 只显示受影响行数是当前执行的sql的行数
[SQL] delete from student where sid = 2;
受影响的行: 1
时间: 0.022ms
存储过程和触发器的区别