欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

(小白)MySQL基础学习004 20201008

程序员文章站 2022-04-20 08:47:24
(小白)MySQL基础学习004 20201008历程表关系表与表之间(实体)有什么样的关系,每种关系应该如何设计表结构一对一一张表一条记录与另一张表中最多有一条明确的关系,通常此设计方案保证两个表中使用同样的主键即可《学生信息表》常用表:学生ID(PRI) 姓名、年龄、性别不常用表:学生ID(PRI) 籍贯、婚否、住址一对多(也叫作多对一)孩子对妈妈来说是多对一,而妈妈对孩子相当于一对多,类似这样的关系在多关系的表中去维护一个字段,这个字段是“一”关系的主键多对多...

(小白)MySQL基础学习004 20201008

历程

  1. 表关系
    表与表之间(实体)有什么样的关系,每种关系应该如何设计表结构

  2. 一对一
    一张表一条记录与另一张表中最多有一条明确的关系,通常此设计方案保证两个表中使用同样的主键即可
    《学生信息表》
    常用表:学生ID(PRI) 姓名、年龄、性别
    不常用表:学生ID(PRI) 籍贯、婚否、住址

  3. 一对多(也叫作多对一)
    孩子对妈妈来说是多对一,而妈妈对孩子相当于一对多,类似这样的关系
    在多关系的表中去维护一个字段,这个字段是“一”关系的主键

  4. 多对多
    一张表中的一条记录在另一张表中可以匹配多条记录,反过来也是一样
    这种情况,会用第三张表来关系

  5. 高级数据操作——新增数据
    多数据插入:
    只要写一次insert指令,但是可以直接插入多条记录
    insert into 表名 [字段列表] values(值列表),(值列表2),(值列表3)…;
    insert into my_gbk values(“张三”),(“李四”),(“王五”);
    (小白)MySQL基础学习004  20201008

  6. 主键冲突
    在有的表中,使用的业务主键(字段有业务含义),但是往往进行数据插入的时候,又不确定数据表中是否已经存在对应的主键(比如说是否有对应ID);
    create table my_student(
    stu_id varchar(10) primary key comment “主键,学生ID”,
    stu_name varchar(10) not null comment “姓名,不能为空”
    )charset utf8;

insert into my_student values(“stu001”,“张三”),(“stu002”,“张四”),(“stu003”,“张五”),(“stu004”,“张六”);
(小白)MySQL基础学习004  20201008
insert into my_student values(“stu004”,“小婷”);
(小白)MySQL基础学习004  20201008
主键重复,报错

  1. 主键冲突的解决方案
    1、主键冲突更新,如果冲突就更新
    insert into 表名 【字段列表】values[值列表] on duplicate key update 字段=新值
    insert into my_student values(“stu004”,“小婷”) on duplicate key update stu_name=“小婷”;
    (小白)MySQL基础学习004  20201008
    张六更新成了小婷
    2、主键冲突替换
    如果所有的都要更新,那么数据操作就比较多了,所以另一种方法是直接替换数据
    replace into 表名 [字段列表]values(值列表);
    replace into my_student values(“stu001”,“夏洛”),(“stu002”,“山姆”);
    (小白)MySQL基础学习004  20201008

  2. 蠕虫复制
    一分为二,成倍增加
    从已有数据中获取数据,并且将数据插入到数据表中
    insert into 表名 [(字段列表)] select */字段列表 from 表(可以是其它表);
    create table my_simple(
    name char(1) not null
    )charset utf8;

insert into my_simple values(“a”),(“b”),(“c”), (“d”),(“e”),(“f”);
(小白)MySQL基础学习004  20201008
insert into my_simple(name) select name from my_simple;
(小白)MySQL基础学习004  20201008
注意:
可以在短期内快速增加表的数据量,可以测试表的压力,还可以通过大量数据来测试表的效率(索引)
但要注意主键冲突。

  1. 更新数据
    在更新数据的时候,一般都是跟随条件更新,而不是批量更新
    update 表名set 字段名=新值 where 判断条件;
    如果没有条件,就全表更新
    但是可以使用limit来限制更新的数量
    update 表名set 字段名=新值 (where 判断条件) limit 数量;

改变4个a成g
Update my_simple set name=“e” where name=“a” limit 4;

(小白)MySQL基础学习004  20201008
成功改变了前4个。

  1. 删除数据
    删除数据一般无法重置auto_increment;
    (小白)MySQL基础学习004  20201008
    mysql有一个能够重置选项中自增长的语法:
    truncate表名:相当于先drop,再create;
    (小白)MySQL基础学习004  20201008

  2. 查询数据
    完整的查询语句:
    select select选项 字段列表 from 数据源 where 条件 group by 分组 having 条件 order by 排序 limit 限制;
    select选项:系统该如何对待查询得到的结果
    All:默认的,表示保存所有的记录
    Distinct:去除重复的记录,只保留一条(这里的重复指所有的字段都相同)
    select all * from my_simple;
    (小白)MySQL基础学习004  20201008

    select distinct * from my_simple;
    (小白)MySQL基础学习004  20201008
    已经自动去重了

字段列表:
有的时候需要从多张表中获取数据,在获取数据的时候,可能存在不同表中有同名的字段,这时候就需要将同名的字段命名成不同名的。利用别名:alias
字段名 [as] 别名;
select distinct name as name1,name name2 from my_simple;
(小白)MySQL基础学习004  20201008
from数据源:
sql为前面提供查询的数据源,只要是一个符合二维表结构的数据即可,一张表,多张表,甚至是一张虚拟的表数据都可以
多张表:from 表1,表2,。。。
(小白)MySQL基础学习004  20201008
select * from my_int,my_date;
(小白)MySQL基础学习004  20201008
这里相当于把字段叠加,数据数量相乘得到了一份新的数据
这种结果的专业说法叫:笛卡尔积,这个结果给数据库造成压力,没有其它意义
动态数据
from后面跟的数据不是一个实体表,而是一个从表中查询出来得到的二维结果(子查询)
基本语法:from (select 字段列表 from 表) as 别名
select * from (select int_1,int_8 from my_int) as int_my;

(小白)MySQL基础学习004  20201008

  1. where子句
    用来从数据表获取数据的时候进行条件筛选
    原理:一条条获取,拿到一条判断一条,符合就保存,不符合就不拿到内存中,
    where 通过运算符进行判断数据

  2. group by 子句 分组统计
    表示分组的含义,根据指定的字段,将数据进行分组,分组的目标是为了统计
    基本语法:

添加班级id
alter table my_student add class_id int;
(小白)MySQL基础学习004  20201008
修改班级:
update my_student set class_id =1 where stu_id in (“stu001”,“stu002”);
(小白)MySQL基础学习004  20201008
update my_student set class_id =2 where stu_id in (“stu003”,“stu004”);
update my_student set class_id =3 where stu_id in (“stu0001”,“stu0002”);
(小白)MySQL基础学习004  20201008
根据班级id进行分组
select * from my_student group by class_id;
(小白)MySQL基础学习004  20201008
发现数据反而变少了
group by只是为了数据统计,如果想用它看数据,结果会很让你失望。分组之后,只会保留每组的第一条数据
如何统计:
利用统计函数:统计函数(聚合函数)
count():统计每组数中的数量,如果统计的目标字段为NULL,则不统计,如果为*(count(*))就表示为统计记录。
avg():求平均值
sum():求和
max():
min():
alter table my_student add stu_age tinyint unsigned;

(小白)MySQL基础学习004  20201008
alter table my_student add stu_height tinyint unsigned;
(小白)MySQL基础学习004  20201008
update my_student set stu_age=18,stu_height=177 where stu_id=“stu001”;
update my_student set stu_age=17,stu_height=165 where stu_id=“stu002”;
update my_student set stu_age=19,stu_height=170 where stu_id=“stu003”;
update my_student set stu_age=16,stu_height=180 where stu_id=“stu004”;
update my_student set stu_age=17,stu_height=175 where stu_id=“stu0001”;
update my_student set stu_age=18,stu_height=171 where stu_id=“stu0002”;

(小白)MySQL基础学习004  20201008
按照班级统计:
每班人数,最大的年龄,最矮的身高,平均年龄:
select class_id,count(),max(stu_age),min(stu_height),avg(stu_age) from my_student group by class_id;
(小白)MySQL基础学习004  20201008
此处如果不用group by class_id;也没问题,默认group by anything;
select class_id,count(
),max(stu_age),min(stu_height),avg(stu_age) from my_student;
(小白)MySQL基础学习004  20201008
发现这里就只剩下一条数据了,因为class_id没有分组
我们再试试用max(stu_age)分组呢:
select class_id,count(*),max(stu_age),min(stu_height),avg(stu_age) from my_student group by max(stu_age);
报错:
(小白)MySQL基础学习004  20201008

  1. group_concat():为了将分组中指定的字段进行合并;
    select class_id, group_concat(stu_name),count(*),max(stu_age),min(stu_height),avg(stu_age) from my_student group by class_id;

(小白)MySQL基础学习004  20201008
这里将stu_name拼接显示了出来

  1. 多分组
    将数据按照某个字段进行分组后,对已经分组的数据进行再次分组
    基本语法:group by 字段1,字段2 先按照字段1分组,再按照字段2分组,以此类推
    先加一个性别字段:
    alter table my_student add gender enum(“男”,“女”,“保密”);
    update my_student set gender = 1 where stu_id in (“stu001”,“stu003”,“stu0001”);
    update my_student set gender = 2 where stu_id in (“stu002”,“stu004”,“stu0002”);

(小白)MySQL基础学习004  20201008
多分组:
select class_id,gender,count(*),group_concat(stu_name) from my_student group by class_id,gender;
(小白)MySQL基础学习004  20201008

  1. 分组排序
    mysql中,分组默认有排序的功能,按照分组字段进行,默认是升序
    基本语法:group by字段[asc|desc],字段[asc|desc]
    班级升序,性别降序
    select class_id,gender,count(*),group_concat(stu_name) from my_student group by class_id asc,gender desc;
    (小白)MySQL基础学习004  20201008

  2. 回溯统计
    当分组进行多分组之后,往上统计的过程中,需要进行层层上报,将这种层层上报统计的过程称之为回溯统计,每一次分组向上统计的过程都会产生一次新的统计数据,而且当前数据对应的分组字段为NULL
    基本语法:group by字段[asc|desc] with rollup
    select class_id,count() from my_student group by class_id;
    (小白)MySQL基础学习004  20201008
    select class_id,count(
    ) from my_student group by class_id with rollup;
    (小白)MySQL基础学习004  20201008
    select class_id,gender,count(*),group_concat(stu_name) from my_student group by class_id,gender with rollup;
    (小白)MySQL基础学习004  20201008

  3. having字句:
    本质和where一样,是用来进行数据条件筛选,
    having在group by子句之后,是可以对group by的分组进行筛选的,但where在它之前,所以where是不能的
    insert into my_student values(“stu005”,“小江”,1,19,178,1);
    (小白)MySQL基础学习004  20201008
    查询一个班级人数大于等于3的结果:
    我们先试试where,这里发现number只有在group by之后才会计算,所以报错!
    select class_id,count(*) as number from my_student where number>=3 group by class_id;
    (小白)MySQL基础学习004  20201008
    where不能使用聚合函数

select class_id,count() as number from my_student group by class_id having number>=3;
(小白)MySQL基础学习004  20201008
这里number 也可以用count(
)
说明having可以做where能做的所有事,但where却不能做having的

hvaing是对统计结果进行操作的

另外,sql语句的母子句中,子句可以不存在,但一旦存在,就需要按从左往右去执行

where是内存操作

  1. order by子句
    基本语法:order by 字段 esc|desc
    create table my_student(
    stu_id int,
    stu_name varchar(10),
    stu_gender enum(“男”,“女”,“保密”),
    stu_class int
    )charset utf8;

(小白)MySQL基础学习004  20201008
insert into my_student values(2020001,“王二”,1,3);
insert into my_student values(2020004,“王三”,2,2);
insert into my_student values(2020002,“王四”,2,7);
insert into my_student values(2020007,“王五”,1,4);
(小白)MySQL基础学习004  20201008

排序:
select * from my_student order by stu_class asc;
(小白)MySQL基础学习004  20201008
order by 也可以像group by一样进行多字段排序

insert into my_student values(2020002,“张二”,1,3);
insert into my_student values(2020005,“张三”,2,2);
insert into my_student values(2020008,“张四”,2,7);
insert into my_student values(2020009,“张五”,1,4);

select * from my_student order by stu_class asc,stu_id desc;
(小白)MySQL基础学习004  20201008

  1. limit子句
    用于限制子句,主要是限制记录数量获取
    select * from my_student order by stu_class asc limit 3;
    (小白)MySQL基础学习004  20201008
    limit在查询的时候,如果限定为一条记录的时候,使用的比较多,有时候获取多条记录并不能解决业务问题,但会增加服务器压力。

  2. 分页
    limit用来限制指定区间的数据
    limit offset,length //offset偏移量,从哪儿开始,length长度
    mysql记录的数量从0开始
    limit 0,2表示获取前两条数据
    select * from my_student limit 0,2;
    select * from my_student limit 2,2;

(小白)MySQL基础学习004  20201008
limit后面的length表示最多获取的数量,但是如果数量不够,系统不会强求

  1. 算术运算符
    通常不在条件中使用,而是用在结果运算(select字段中)
    ±*/%
    create table ysf1(
    int_1 int,
    int_2 int,
    int_3 int,
    int_4 int
    )charset utf8;

insert into ysf1 values(100,-100,0,default);
(小白)MySQL基础学习004  20201008
select int_1+int_2-int_2,int_1-int_2,int_1*int_2,int_1/int_2,int_2/int_3,int_2/6,int_4/5 from ysf1;
(小白)MySQL基础学习004  20201008
int_1/int_2 获得的是浮点数
在mysql中除法是用浮点数计算的
结果如果是0,系统会给NULL,用NULL进行任何算术运算结果都是NULL,这里的计算错误,会给NULL

  1. 比较运算
    =,或者<=>都是表示等于
    select * from my_student where stu_class>=4;
    (小白)MySQL基础学习004  20201008
    特殊运算:
    select “1”<=>1,0.02<=>0,0.02<>0;
    (小白)MySQL基础学习004  20201008
    此处只能用<=>进行判断,而不能用=,这里用=就相当于赋值了;
    另外,在mysql中,会将相比较的类型自动转换成同类型,再比较
    在mysql中没有bool值,只有0和1,正确就是1
    在条件判断的时候,还有相对应的比较运算符,计算区间:
    between 条件1 and 条件2;
    select * from my_student where stu_class between 2 and 5;
    (小白)MySQL基础学习004  20201008
    这种查找是闭区间查询,也就是2<=x<=5
    这里的条件1必须小于条件2
    如果是5 and 2,就会一条数据也没有

  2. 特殊运算符
    and or not
    与 或 非
    select * from my_student where stu_id>2020001 and stu_class>2;

(小白)MySQL基础学习004  20201008

  1. IN运算符
    在……里面,是用来替代=,当结果不是一个值,而是一个结果集的时候;基本语法 in(结果1,结果2……),只要结果在其中满足条件,返回1 即true

  2. Is运算符
    Is是专门用来判断字段是否为NULL的运算符
    基本语法:is null…
    insert into my_student values(2020011,default,default,8);
    (小白)MySQL基础学习004  20201008
    查找为空:
    select * from my_student where stu_name = NULL;//无结果
    select * from my_student where stu_name is NULL;//有结果

(小白)MySQL基础学习004  20201008

  1. LIKE运算符
    用来进行模糊匹配
    基本语法 like 匹配模式
    匹配单个字符
    %匹配多个字符
    select *from my_student where stu_name like "张
    ";
    (小白)MySQL基础学习004  20201008

  2. 联合查询
    联合查询是合并多个相似的选择查询的结果集,等同于将一个表追加到另一个表,从而实现将两个表查询组合到一起,使用谓词为UNION或UNIONALL
    联合查询:将多个查询结果合并到一起(纵向合并),字段数不多,多个查询的记录数合并
    应用场景:
    将同一张表中不同的结果(需要多条查询语句来实现)合并到一起展示数据;
    最常见,在数据量大的情况下,会对表进行分表操作,需要对每张表进行分数据统计,使用联合查询来将数据存放到一起显示;

  3. 基本语法
    select 语句
    union(union 选项)
    select 语句
    union选项,与select 选项基本一样
    distinct 去重,去掉完全重复的数据(默认的)
    all保存所有的结果

alter table my_student add stu_height int;
update my_student set stu_height=180 where stu_id=2020001;
update my_student set stu_height=173 where stu_id=2020002;
update my_student set stu_height=182 where stu_id=2020004;
update my_student set stu_height=181 where stu_id=2020005;
update my_student set stu_height=170 where stu_id=2020007;
update my_student set stu_height=182 where stu_id=2020008;
update my_student set stu_height=177 where stu_id=2020009;
update my_student set stu_height=169 where stu_id=2020011;
(小白)MySQL基础学习004  20201008
select * from my_student where stu_gender=1 order by stu_height asc;
select * from my_student where stu_gender=2 order by stu_height desc;
(小白)MySQL基础学习004  20201008
我们可以在两个语句之间加上一个union --默认选项distinct
select * from my_student where stu_gender=1 union select * from my_student where stu_gender=2;
(小白)MySQL基础学习004  20201008
select * from my_student where stu_gender=1 order by stu_height asc union select * from my_student where stu_gender=2 order by stu_height desc;
这样是报错的,具体原因见第32条
(小白)MySQL基础学习004  20201008

只要字段数相同,不需要类型相同
select stu_id,stu_name,stu_height from my_student
union all
select stu_height,stu_id,stu_name from my_student;
我的这两句单独执行没问题,但是连在一起就报错了,
(小白)MySQL基础学习004  20201008
经测试,我是在网页中写的代码,可能和txt中写的格式不同,把换行换成空格即可
select stu_id,stu_name,stu_height from my_student union all select stu_height,stu_id,stu_name from my_student;

(小白)MySQL基础学习004  20201008
它只保留第一句的字段,但这样已经没意义了

  1. order by的使用
    order by如果想要在联合查询里使用,就必须用括号括起来
    (select * from my_student where stu_gender=1 order by stu_height asc) union (select * from my_student where stu_gender=2 order by stu_height desc);
    (小白)MySQL基础学习004  20201008
    实现是实现了,但我发现并没有按我想要的方式排序

  2. order by在联合查询中,必须与limit一起使用
    (select * from my_student where stu_gender=1 order by stu_height asc limit 10) union (select * from my_student where stu_gender=2 order by stu_height desc limit 10);
    (小白)MySQL基础学习004  20201008
    这样就可以了

  3. 连接查询
    将多张表连接一起进行查询(会导致记录数行和字段数列发生改变)
    在关系型数据库的设计过程中,遵循着一对一,一对多和多对多,所以通常在实际操作的过程中,需要利用这层关系保证数据的完整性。
    分类:
    交叉连接
    内连接
    外连接
    自然连接

  4. 交叉连接
    将两张表的数据与另一张表彼此交叉
    取出每一条记录后,与另外一张表的全部记录挨个匹配
    迪卡尔积
    语法:表1 cross join 表2
    select * from my_student cross join my_int;
    (小白)MySQL基础学习004  20201008
    结果是27行
    尽量不用交叉连接。

  5. 内连接
    从一张表中取出所有的记录去另一张表中匹配,利用匹配条件进行匹配,成功了则保留,失败了放弃。
    匹配到:继续匹配
    匹配失败:向下继续,如何全表匹配结束,没有返回结果
    表1 【inner】 join 表2 on匹配条件
    create table my_class(
    id int primary key auto_increment,
    name varchar(10) not null unique
    )charset utf8;

insert into my_class values(null,“1班”),(null,“2班”),(null,“3班”);
(小白)MySQL基础学习004  20201008
1、如果内联没有条件,那么就是交叉连接
select * from my_student inner join my_class;
(小白)MySQL基础学习004  20201008
2、使用匹配条件
select * from my_student inner join my_class on class_id=id;
(小白)MySQL基础学习004  20201008
3、因为表的设计通常容易产生同名字段,尤其是ID,所以为了避免发生错误,通常使用表名.字段名
select * from my_student inner join my_class on my_student.class_id=my_class.id;
(小白)MySQL基础学习004  20201008
4、通常,如果条件中使用对应的表名,而表名通常比较长,所以可以通过表别名来简化。
select * from my_student as s inner join my_class as c on s.class_id=c.id;
(小白)MySQL基础学习004  20201008
5、内联接,必须保证匹配到,记录才会保存,如果没有匹配到就不显示
6、内连接因为不强制必须使用匹配条件(on)因此可以在数据匹配完成之后,使用where 条件来限制,效果与on一样(建议使用on)
select * from my_student as s inner join my_class as c where s.class_id=c.id;
(小白)MySQL基础学习004  20201008

  1. 内连接的应用
    内连接通常在对数据有精确要求的地方使用,必须保证两种表中能进行数据匹配

  2. 外连接
    outer join 按照某一张表为主表(表中所有记录都会保留),根据条件去连接另一张表,从而得到目标数据
    左外连接:左边是主表
    右外连接:右边是主表

原理:
确定连接主表:左连接就是left join,right join就是右连接

语法:
左连接,主表left join 从表on 连接条件,主表数据在左边
右连接,从表right join 从表on 连接条件,右表数据在右边

select * from my_student as s left join my_class c on s.class_id=c.id;
(小白)MySQL基础学习004  20201008
select * from my_student as s right join my_class c on s.class_id=c.id;
(小白)MySQL基础学习004  20201008

  1. using关键字
    在连接查询中用来代替对应的on关键字,进行条件匹配
    在连接查询时,使用on的地方用using代替
    使用using的前提是对应的两张表连接的字段是同名(类似自然连接自动匹配)
    使用using关键字,那么对应的同名字段,最后在结果中只会保留一个。

语法:
表1【inner left right】
(小白)MySQL基础学习004  20201008
(小白)MySQL基础学习004  20201008

select * from my_student left join my_class using(class_id);
(小白)MySQL基础学习004  20201008

本文地址:https://blog.csdn.net/imthewiner/article/details/108969208

相关标签: mysql sql