MySQL基础知识

MySQL简介

数据库的概念:

长期存放在计算机内,有组织、可共享的大量数据的集合,是一个数据“仓库”

作用:存放,管理数据

分类:关系型数据库,NoSQL数据库

MySQL特点:1操作便捷 2小巧,功能齐全3免费、开源的数据库 4可运行于windows或linux系统

数据库结构

  • 数据库(Database):以文件的形式存放在磁盘上,即对应于一个或多个物理文件
  • 字段(Field):也叫域,表中的每一列称为一个字段,每个字段都有相应的描述信息
  • 索引(Index):索引实际上是一种特殊类型的表,其中含有关键字段的值和指向实际记录位置的指针,可以提高访问数据库的效率。
  • 数据表(Table):简称表,由一组数据记录组成,数据库中的数据是以表为单位进行组织的,一个表是一组相关的按行排列的数据;每个表中都含有相同类型的信息。

DDL建库建表

库的操作 代码书写
创建一个库 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值,必须给定具体的数据

  • 默认,所有类型的值都能为null,包括INT ,FLOAT等数据类型
  • 非空约束只能出现在对象的列上,只能某个列单独限制非空,不能组合非空
  • 一个表可以有很多列都分别限定了非空
  • 空字符串‘’不等于null,0也不等于null‘’

唯一约束

unique约束的字段,具有唯一性,不可重复,但可以为null

  • 同一个表可以有多个唯一约束
  • 唯一约束可以是某一个列的值是唯一,也可以多个列组合的值唯一
  • 唯一约束允许列值为空
  • 在创建唯一约束的时候,如果不给唯一约束命名,就默认和列名相同
表级约束
create table test(
	id int(10),
	name varchar(32) not null,
	email varchar(123),
	unique(email)
);

主键约束(primary key)PK

主键(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) -- 外键约束,表级定义方式
)

Mysql 对 数 据 的 增 删 改

增加数据(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…);

其中:

  • 查询的字段值,至少与IN后的括号中的一个值相等
  • 多个值用逗号隔开
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 和having 分组

GROUP BY

  1. 对所有的数据进行分组统计;
  2. 分组的依据字段可以有多个,并依次分组。
-- 统计出男同学 和 女同学的人数
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]

  • 升序 从小到大 asc
  • 降序 从大到小 desc
  • order by 后面可以使用多个字段排序,先写先排
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

**子查询:**子查询,也叫内部查询(查询语句中又有一个查询(里面的查询称为子查询)执行子句,再执行父句)

  1. where 子查询

查询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
)
  1. from 子查询

把内层的查询结果当成临时表,供外层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
  1. exists 子查询

子句有结果父句执行,子句没结果父句不执行

学生表中有外星人同学查询出所有的老师

select * from teacher 
where exists (select * from student where ssex = '外星人')
  1. any,some,all 子查询

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 语句

  • 简单的case
select tid,tname,
case tsex
	when 1 then '男'
	when 0 then '女'
	else '未知'
end
,
tmoney from teacher
  • 搜索case (常用
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原则(特性)

  • 原子性:意味着数据库中的事务执行是作为原子粒度。即不可再分,整个语句要么执行,要么不执行
  • 一致性:即在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
  • 隔离性:事务的执行是互不干扰的,一个事务不可能看到其他事务运行时,中间某一时刻的数据。
  • 持久性:意味着在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

事务的隔离性

  • 什么是事务的隔离性:为了让不同的事务之间相互不存在干扰,就需要对事务的操作进行隔离,事务的隔离性也就是将操作同一个数据的事务相互分离,让操作之间分开有序的执行

  • 用什么方式实现事务的隔离性:通常数据库里都是采用锁的机制,保证事务之间的隔离性。

事务的隔离级别

  1. 读未提交,造成的问题:脏读,不可重复读,幻读
  2. 读提交(不可重复读),造成的问题:不可重复读,幻读
  3. 可重复度,造成的问题:幻读
  4. 串行化,没有问题,但是不管读取还是修改所有的事务串行化执行,一个事务的执行必须等其他事务结束
慢查询

什么是慢查询 ?

MySQL默认10秒内没有响应SQL结果,则为慢查询

索引

什么是索引?

索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。

索引的优点

  1. 高效性:利用索引可以提高数据库的查询效率
  2. 唯一性:索引可以确保所查的数据的唯一性
  3. 完整性:用户可以加速表和表之间的连接,实现表与表之间的参照完整性
  4. 特殊能力:通过使用索引,可以在查询过程中,使用优化隐藏器,提高系统性能

索引的缺点

  1. 虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。
  2. 因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。建立索引会占用磁盘空间的索引文件
  3. 如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快。

索引的分类

  • 主键索引:在数据库关系图中为表定义一个主键将自动创建主键索引。
  • 唯一索引:不允许具有索引值相同的行,从而禁止重复的索引或键值。
  • 常规索引:最基本的索引类型,没有唯一性之类的限制。
  • 全文索引:搜索引擎的关键技术,用于检索文本信息,可以是词语或者段落。
视 图 、 存 储 过 程 和 触 发 器

视图是从一个或者几个基本表(或视图)导出的表。它与基本表不同,是一个虚表。

  • 视图不能做增删改,只能用来查询
  • 使用的时候每次都会获取到最新的数据
  • 不允许有重复的字段名

创建一个视图

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 语句集,存储在数据库中,经过第一次编译后,再次调用不需要重复编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。

为什么使用存储过程

  • 业务流程复杂:业务复杂时,SQL语句相互依赖,顺序执行;
  • 频繁访问数据库:每条SQL语句都需单独连接和访问数据库;
  • 先编译后执行:SQL语句的执行需要先编译。

创建存储过程

CREATE PROCEDURE 存储过程名【proc_xxx】 (形参列表)
BEGIN
    DECLARE  变量   变量类型
END

delimiter $$ 定制定界符

创建一个简单的存储过程

delimiter $$
create procedure proc_stu()
begin 
	select * from student;
end $$
delimiter ;

使用存储过程

call proc_stu()

带参的存储过程

参数:

  • in 只入参
  • out 只出参
  • inout 出入参
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 ;

存储过程与函数的区别

  • 语法:关键字不同,存储过程是procedure,函数是function;
  • 执行:存储过程可以独立执行,函数必须依赖表达式的调用;
  • 返回值:存储过程可以定义多个返回结果,函数只有一个返回值;
  • 功能:函数不易做复杂的业务逻辑,但是存储过程可以。

存储过程的缺陷

  • 维护性:存储过程的维护成本高,修改调试较为麻烦。
  • 移植性:大多数关系型数据库的存储过程存在细微差异。
  • 协作性:没有相关的版本控制或者IDE,团队中对于存储过程的使用大多是依赖文档。
触发器

什么是触发器

触发器是数据库中针对数据库表操作触发的特殊的存储过程。

# 触发器
-- 隐式执行
-- 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

存储过程和触发器的区别

  • 语法:关键字不同,存储过程是procedure,触发器是trigger;
  • 执行:存储过程需要调用才执行,触发器自动执行;
  • 返回值:存储过程可以定义返回值,但是触发器没有返回值;
  • 功能:存储过程是一组特定功能的SQL语句,触发器则是SQL语句前后执行,本身不影响原功能。

你可能感兴趣的:(mysql,数据库)