数据库MySql
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
数据库是一类软件,能组织很多数据,然后进行增删改查,与之和数据结构有点相似之处,都是对数据进行管理.
但也有不同的地方,数据结构是数据库内部实现的基础,其中数据提供了一个更高层次的抽象,使得用户不必关注底层数据结构的细节,就能进行数据的存储,检索和管理
文章目录
- 数据库MySql
- 前言
- 一、数据库基础
- (一)数据库操作
- (二)数据类型
- 二、表的增删改查
- (一)查看表 ---> show tables;
- (二)创建表 ---> create table(列名 类型,列名 类型 .....);
- (三) 查看表(属性) ---> desc 表名;
- (三)删除表 ---> drop 表名;
- 三丶行列的增删查改
- N1.新增
- N2.查询
- N3.修改
- N4.删除
- 对比
- 四丶数据库的约束
- 主键和外键
- 五丶聚合查询和联合查询
- 分组查询 ---> groud by
- 联合查询(多表查询)
- 外连接
- 总结
前言
重要的是! MySQL 是一个客户端–服务器结构的程序,客服端和服务器是两个独立的程序,通过"网络"进行通信.
主动发起网络通信的一方称为"客户端",对应的是被动接收网络通信的是"服务器";
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/75f100a51163408883787838d17370ef.png
一、数据库基础
(一)数据库操作
查看,创建,选中,删除数据库
show databasess;
create database 数据库名
use 数据库名
drop database 数据库名
(二)数据类型
1.数字
2.字符串
3.时间日期
注意:在创建数据库的时候,需要指定一个"字符集",如果不嫩正确的指定字符集,后续想要保存中文就会出现问题.
MySQL 5 默认的字符集是"拉丁文",此时如果想要插入中文数据是会出错的,因此我们需要把数据库指定为"utf8"
二、表的增删改查
一个数据库含有多个"数据库";
一个"数据库"含有多个表;
一个表含有多个行,列;
在进行表的操作的时候,需要先对某个数据库进行选中 就要用到 use 数据库名;
进行以下操作前提是,选中某个数据库,再进行当前数据库的操作;
(一)查看表 —> show tables;
(二)创建表 —> create table(列名 类型,列名 类型 …);
举列:创建一个学生表 包含学生id ,名字,成绩
create table students(id int,name varchar(20),score decimal(3,1));
命令行演示;
(三) 查看表(属性) —> desc 表名;
describe : 描述 当前情况下 指的是该表的结构 查询每个列的属性 但无具体内容
(三)删除表 —> drop 表名;
注意:在MySQL中进行的删除的操作是非常危险的,有可能一不注意就会把数据整出问题来 带来不必要的麻烦删表往往比删库的危险性更大,但直觉上来讲,删库,意味着把所有的表删完了,为啥说删表比删库更危险呢?
对于删库操作,一般都是第一时间能发现问题的,程序在操作数据库时.第一时间就会反馈出问题,此时 监控报警系统就会发出警告给相关人员 处理的越及时,损失就越小
对于删表操作,就更隐蔽了.比如一个数据库有100个表,不小心删除了其中一个 ,程序员使用数据库的时候,绝大部分的逻辑都是正常的 但在使用99个表的过程中.输入数据库能访问 但是逻辑已经出问题了 不知道要过多久 才能触发一次访问到第100个表这样操作 才能触发一次报错 指不定又过了多久,这样的报错积累到一定程度 才触发报警 时间过得越久 损失就越严重
三丶行列的增删查改
N1.新增
关键词 : insert ..into ..
格式 : insert into 表名 values(值,值,值);
//注意这里的"值"必须要与对应表的属性一一对应 具体包含列的个数,类型,顺序 结构必须保持一致;同时 在插入数据类型为字符串的时候 : 需要用双引号 或者 单引号!!!若之前在指定了该数据库的字符集 为utf8 则此时用中文表示字符串依然不成问题 反之,会报错.
如果在某种情况下: 插入数据时与原指定的类型不匹配 SQL会采用"隐式类型转换"
譬如:字符串类型 “100” ==> 100 整数类型 50 ⇒> “50”; 与java的自动拆箱类似
形式一:指定某些行插入 (要保证结构相同)
格式:insert into 表名(列名,列名) values (值,值);// 对一个表中需要的列进行插入val 当前行未插入的值 默认为null;形式二:多行数据插入(要保证格式相同)
格式:insert into 表名 values(值,值,值),(值,值,值);最后 两种形式结合 也可以配合使用
我们知道MySQL 是一个"客服端—服务器"结构的程序
在插入3条记录时
1.一次插一行,三个sql完成
2.一次插三行,一个sql完成
在此过程中 交互的次数越多,整体的开销就越大,花的时间就越长.一个sql包含的数据多少,不是主要矛盾,除非数据差异太大了,可能会有明显影响.如果差了几条,区别是不大的~~;
insert 插入时间 类型有特殊的
其中now()表示获取当前时间日期
N2.查询
关键词: select .. from ..
全列查询:select * from 表名;
指定列查询:select 列名,列名..from 表名;
指定表达式查询:select 列名 +- 列名 .. as 表达式 from 表名;
去重查询:select distinct 列名 from 表名;
排序查询:select * from 表名 order by 列名;
条件查询:select 列名 from 表明 where 条件;
分页查询:select 列名 from 表名 limit n(个数);
注意
1.select * 是比较危险的操作. 如果表比较小,select * 都无所谓,一旦表非常大,千万/亿级别的数据量,此时,进行select就会产生大量的硬盘IO和网络IO 硬盘和网卡 读写速度
都是存在上限的.一旦触发大规模的select * 意味着可能就把你的硬盘/网卡给吃满了 (堵车)
此时其他客服端尝试访问数据库,访问操作就无法正常进行了. 因此,在以后工作中尤其是生产环境 一定要谨慎!!!
2.这里每一次查询所生成的表 都是临时创建的,而硬盘上的数据始终保持不变;
3.进行排序查询的时候,可以指定按照某个列进行查询 可升可降 升后面加上asc 可以省略 降后面加上desc 这都是基于在 order by 上面的 若没有order by 查询的数据是不可预估的是随机的
4.分页查询 可以在面临大量数据时限制每一次查询数据的个数 limit 极限 此时还可以搭配offset 表示从下标(索引)开始查询n条数据
like模糊匹配 (不要求完全相等,只要满足一定条件就可以);
% : 匹配0个和任意个字符;
_ : 匹配1个特定的字符;
如下表
查询以孙开头的:
查询以孙结尾的;
查询以孙为中的:
N3.修改
此时修改的数据就是从硬盘从的数据了 所以一定要注意准确性!!!;
关键字:update .. set;
格式:update 表名 set 列名 = 值 where 条件;
注意 : 使用 update 修改时 需要加上where 条件 来确保你要修改的信息 如若没有指定条件 那么面临的是整个表中的列 此时所有的列都会被改
N4.删除
关键字:delete from;
格式:delete from 表名 where 条件 /order by / limit;
//把筛选出来的数据进行删除
对比
提示:这里对文章进行总结:
insert into 表名
select from 表名
update 表名
delete from 表名
//以上为大概的格式 接口风格并不统一
四丶数据库的约束
not null -- 指示某列不能存储null值;
unique ---保证某列的每行必须有唯一的值;
default --- 规定没有给列赋值时的默认值;
check -- 保证列中的值符合要求
//都是在创建表的时候对列进行限制
主键和外键
主键 :约定了表里某个列为 -->身份标识 保证了唯一 非空特点;(每个表里只能存在一个主键);
create table student(id int primary key,name varchar(20));
MySQL 提供了一个 自动分配 主键值的方式 --> “自增主键” 此时可以让数据库自动指定某个列的值 从小递增;(只能针对 int 和bigint 类型的数据)
create table student(id primary key auto_increment );
外键:涉及到了两个表:用于其他表中的主键和唯一键
create table class(classid int primary key,name varchar(20));
craete table student(studentid int primary key,name varchar(20),classid int,foreign key(studentid) references class(classid));
外键约束 必须有两个表,班级表必须存在主键or唯一,学生表也要存在并且存在外键来约束;
此后,班级表中必须要有数据才能增加学生的数据 并且保持学生的id与班级的id 相同否则会出错;
学生表中的某一列必须是班级表中的某一列,通过这一个共同的列来约束添加的学生 班级表又称为父表,学生表又称为子表 ,父 约束 子 子也约束父 两者共同存在
例如,如果父表中的某个记录被子表引用了,此时不能修改或者删除子表中对应的记录了
总之 ,父表约束子表,子表也会反向进行约束;
五丶聚合查询和联合查询
针对行和行之间的"聚合操作" ,进行聚合查询,需要聚合函数
查询共有多少行
查询name这列不为空的数量
总结:在进行聚合操作的时候,利用select 查询列名的方式,遇到空值不会进行计算
分组查询 —> groud by
select 列名 from 表名 groud by 列名;
//使用groud by指定一个列,就会把相同的行归为一组中 分完组后还可以针对每个组使用聚合查询
通过角色进行分组
总结:分组之前的条件用where 分组之后的条件用having
联合查询(多表查询)
拿到两张表进行笛卡尔积的前提是每个表其中的列存在某种关系例如相等
如上表 两个表都含有班级编号 就可以对两张表进行笛卡尔积 得到结果之后通过相等条件就可以找到有意义的数据.
select * from student,class where student.id = class.id;
不能直接通过列名进行比较 因为此时存在两个表具有二义性 则通过 **表名.列名 = 表名.列名**;
具体操作
如下表
举例子;
外连接
外连接分为左外连接和右外连接。如果联合查询,左侧的表完全显示我们就说是左外连接;右侧的表完全显示我们就说是右外连接。
-- 左外连接,表1完全显示
select 字段名 from 表名1 left join 表名2 on 连接条件;
-- 右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件;
不管是内连接还是外连接,操作结果完全相同!!
总结
数据库约束
null 约束
unique唯一约束
default 默认值约束
主键约束
外键约束
check约束
表的关系
1.一对一:主键约束
2.一对多:副键约束
3.多对多:建立关联表
新增
insert into table from ......
查询
1.聚合函数:max min avg count sum;
2.分组查询: groud by... having...
3.内连接:select 列名 from 表1,表2 where 条件select 列名 from 表1 join 表2 on 条件 where 其他条件
4.外连接select 列名 from 表1 left/right join 表2 on 条件 where 其他条件
5.自连接select ...from 表1,表1 where 条件select ...from 表1 join 表1 on 条件
SQL查询中各个关键字的执行先后顺序: from > on> join > where > group by > with > having >select > distinct > order by > limit