MySQL数据库基础篇-2

本文章是菜鸟在学习 MySQL数据库时做的记录,从基础 到 进阶 到 运维,实现轻松掌握MySQL数据库技能知识。

本文围绕以下展开介绍:    1.外键约束、2.多表查询 DQL、3.联合查询-union,union all、 4.子查询

        1.约束
-- 约束 概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据。
        目的:保证数据库中数据的正确、有效性和完整性。
        种类:  
                1)非空约束NOT NULL、
                2)唯一约束UNIQUE、
                3)主键约束PRIMARY KEY、
                4)默认约束DEFAULT、
                5)检查约束(8.0.16版本之后)CHECK、
                6)外键约束FOREIGN KEY;
  (1)非空约束   
  (2)唯一约束 
(3)主键约束
(4)默认约束
(5)检查约束

        先创建两个表 emp_1、dept

# 创建部门表dept
# (1)非空约束name用‘not null’限制非空,name必须有"数据"
# (3)主键约束id用 ‘primary key’,id 表示主键;

create table dept(
    id int auto_increment comment 'ID' primary key ,
    name varchar(50) not null comment '部门名称'
)comment '部门表';

insert into  yfdb.dept values (1,'研发部'),
                              (2,'市场部'),
                              (3,'财务部'),
                              (4,'销售部'),
                              (5,'总经办');

# 创建员工表 emp_1
# (2)员工id 用‘unique’限制唯一,id不能重复
# (5) age用 ‘check’限制,检查年龄是否在范围内 
create table emp_1(
    id int unique comment '编号',
    name varchar(10) comment '姓名',
    age tinyint unsigned check ( age>0 && age<=120 ) comment '年龄',
    job varchar(20) comment '职位',
    salary int comment '薪资',
    entrydate date comment '入职时间',
    managerid int comment '直属领导',
    dept_id int comment '部门ID'
) comment '员工表';

# 插入数据
insert into 
    emp_1(id,name,age,job,salary,entrydate,managerid,dept_id)
    values  (1,'金庸',66,'总裁',20000,'2000-01-01',null,5),
            (2,'张无忌',18,'项目经理',18000,'2005-09-01',1,1),
            (3, '韦一笑', 38, '开发',11000,'2002-08-01',2,1),
            (5,'小昭',16,'程序员鼓励员',6600,'2007-07-01',2,1),
            (6,'杨道',33,'开发',8400,'2000-11-01',2,1),
            (7,'范瑶',40,'开发',10550,'2004-05-01',2,1);
(6)外键约束FOREIGN KEY;
# 建立外界关联,添加外键,将dept_id、id关联
alter table yfdb.emp_1 add constraint fk_emp1_dept_id foreign key (dept_id) references yfdb.dept(id);

 在datagrip 中可以只管的看到两表的关系,

# 删除外键
alter table yfdb.emp_1 drop foreign key fk_emp1_dept_id;

  外键约束的 删除/更新行为

         no action 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与RESTRICT一致) -

         restric 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与NOACTION一致)

         casecade 当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则也删除/更新外键在子表中的记录。

# 用 cascade 约束 创建外键
alter table yfdb.emp_1 add constraint fk_emp1_dept_id foreign key (dept_id) references yfdb.dept(id) on update cascade on delete cascade ;
     set null 当在父表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为nul(前提要求该外键允许取null)
alter table yfdb.emp_1 add constraint fk_emp1_dept_id foreign key (dept_id) references yfdb.dept(id) on update set null on delete set null;
     set default 父表有变更时,子表将外键列设置成一个默认的值(Innodb不支持)

        2.多表查询 DQL
 (1)多表关系: 一对多(多对一)、多对多  解决方法:建立中间表

 创建表,学生表:student、课程表:course、中间表:student_course

#创建学生表
create table student(
    id int primary key auto_increment comment '主键ID',
    name varchar(10)  comment '姓名',
    no varchar(10) unique comment '学号'
)comment '学生表';
insert into yfdb.student values (1,'黛丽丝',20240101),
                                (2,'Jack',20240102),
                                (3,'欧文',20240103);
#创建课程表
create table course(
    id int primary key auto_increment comment '主键ID',
    name varchar(50) unique comment '课程名称'
)comment '课程表';
insert into yfdb.course values (null,'java'),
                               (null,'C++'),
                               (null,'MySQL'),
                               (null,'Python');

 通过 ”constraint 外键名 foreign key(本表列) references 关联表的列 “语句,创建外键

#创建中间表
# constraint 外键名 foreign key(本表列) references 关联表的列 
create table student_course(
    id int auto_increment comment '主键' primary key ,
    studentid int not null comment '学生ID',
    courseid int not null comment  '科目ID',
    constraint fk_courseid foreign key (courseid) references yfdb.course(id),
    constraint fk_studentid foreign key (studentid) references yfdb.student(id)
) comment '学生课程中间表';
insert into yfdb.student_course values(null,1,1),
                                      (null,1,2),
                                      (null,1,3),
                                      (null,2,2),
                                      (null,2,3),
                                      (null,3,4);

datagrip工具展示三表的关系如图所示:

 例子:展示学生所选的课程(多对多的关系),运行下面指令,结果如下图所示

select s.*,c.name from yfdb.student s,yfdb.course c,yfdb.student_course sc where s.id = sc.studentid and sc.courseid = c.id;

 (2)一对一 表关系

        创建表  员工表tb_user、学历表 tb_user_edu、

create table tb_user(
    id int primary key auto_increment comment '主键ID',
    name varchar(10) comment '姓名',
    age int comment '年龄',
    gender char(1) comment '性别',
    phone char(11) comment '电话号码'
)comment '用户基本信息表';

create table tb_user_edu(
    id int primary key auto_increment comment '主键ID',
    degree varchar(20) comment '学历',
    major varchar(50) comment '专业',
    primaryschool varchar(50) comment '小学',
    middleschool varchar(50) comment '中学',
    university varchar(50) comment '大学',
    userid int unique comment '用户ID',
    constraint fk_userid foreign key(userid) references yfdb.tb_user(id)
)comment '用户基本信息表'

insert into yfdb.tb_user(id, name, age, gender, phone)
values (null,'Ros',30,'男','13888888888'),
       (null,'Hipy',30,'男','13999999999'),
       (null,'Tom',30,'男','13800000000'),
       (null,'Jack',30,'男','13811111111');

insert into yfdb.tb_user_edu(id, degree, major, primaryschool, middleschool, university, userid)
values (null,'硕士','舞蹈','1小学','第一中学','第1学院',1),
       (null,'本科','表演','1小学','第二中学','第2学院',2),
       (null,'本科','美声','1小学','第三中学','第3学院',3),
       (null,'本科','播音','1小学','第四中学','4学院',4);

连接方式:内连接、外连接、自连接
(1)内连接
-- 查询每一个员工的姓名,及教育背景(隐式内连接)
    -- 表结构tb_user,tb_user_edu
    -- 连接条件tb_user.id= tb_user_edu.userid; 
隐式内连接: select 字段列表 from 表1,表2 where 条件;
-- 2.多表查询 查询时消除无效的笛卡尔积
select * from yfdb.tb_user u,yfdb.tb_user_edu ue where u.id = ue.userid;

显式内连接 "select 字段列表 from 表1,[inner] jion 表2 on 连接条件", inner 可以省略

-- 查询每一个员工的姓名,及关联的部门名称(显式内连接)

select * from yfdb.tb_user u inner join yfdb.tb_user_edu ue where u.id = ue.userid;

(2)外连接 emp_1表、dept表在第一篇mysql学习有创建

-- 查询emp_1表的所有数据,和对应的部门信息(左外连接,完全包含左表的数据,左表指from后的前表
 -- 1.查询emp_1表的所有数据,和对应的部门信息(左外连接,完全包含左表的数据)
    -- 表结构emp_1,dept
    -- 连接条件emp_1.dept_id= dept.id;
    select e.*,d.name from emp_1 e left outer join dept d on e.dept_id = d.id;
    select e.*,d.name from emp_1 e left join dept d on e.dept_id = d.id;

-- 查询dept表的所有数据,和对应的员工信息(右外连接,包含右表的数据
 -- 2.查询dept表的所有数据,和对应的员工信息(右外连接,包含右表的数据)
    -- 表结构emp_1,dept
    -- 连接条件emp_1.dept_id= dept.id;
    select d.*,e.* from emp_1 e right outer join dept d on e.dept_id = d.id;

(3)自连接

    -- 1.查询员工 及其所属领导的名字
    -- 表结构emp_1,dept
    select a.name,b.name from yfdb.emp_1 a, yfdb.emp_1 b where a.managerid = b.id;

    -- 2.查询员工 及其所属领导的名字,如果员工没有领导也要查询出来
    -- 表结构emp_1,dept
    select a.name '员工', b.name '领导' from yfdb.emp_1 a left join yfdb.emp_1 b on a.managerid = b.id;

        3.联合查询 -union, -union all
-- 对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。
-- union all 会将全部的数据直接合并在一起,存在重复项
    select * from yfdb.emp_1 where salary < 10000
    union all
    select *from emp_1 where age > 50;

--union 会对合并之后的数据去重。union查询就是把多次查询的结果合并起来,形成一个新的查询结果集。不存在重复项
    select * from yfdb.emp_1 where salary < 10000
    union
    select *from emp_1 where age > 50;

        4.子查询
概念:SQL语句中嵌套SELECT语句,称为嵌套查询,又称子查询
子查询外部的语句可以是插入/更新/删除/选择的任何一个
SELECT * FROM t1 WHERE column1=(SELECT column1 FROM t2 );
-- 分类: 标量子查询(子查询结果为单个值)  查询研发部的所有员工信息(研发部dept_id=1)
select * from yfdb.emp_1 where dept_id =(select id from yfdb.dept where name ='研发部');
-- 查询在“张无忌”后入职的所有员工
select * from yfdb.emp_1 where entrydate > (select entrydate from yfdb.emp_1 where name ='张无忌');

    -- 列子查询(子查询结果为一列)
    -- 常用的操作符:
                -- IN(在指定的集合范围之内,多选一)、-- 查询研发部、财务部的所有员工信息
                select * from yfdb.emp_1 where dept_id in (select id from dept where name ='研发部' or name ='财务部');
                -- NOTIN(不在指定的集合范围之内)、 -- 查询研发部、财务部的所有员工信息
                select * from yfdb.emp_1 where dept_id not in (select id from dept where name ='总经办');
                -- ANY(子查询返回列表中,有任意一个满足即可)、
                -- SOME(与ANY等同,使用SOME的地方都可以使用ANY)、
                -- ALL(子查询返回列表的所有值都必须满足


    -- 行子查询(子查询结果为一行)   常用的操作符:=、<>、IN、NOT IN
        select * from emp_1 where (salary, managerid) = (select salary, managerid from yfdb.emp_1 where name='张无忌');

 -- 表子查询(子查询结果为多行多列) 常用的操作符:IN 
      
select a.name,a.age,a.job,d.name from yfdb.emp_1 a join yfdb.dept d on d.id = a.dept_id;

select a.name,a.age,a.job,d.name from yfdb.emp_1 a join yfdb.dept d on d.id = a.dept_id where a.age<30;

select * from  yfdb.emp_1 e join yfdb.dept p on p.id=e.dept_id where (not isnull(managerid)) and  (not isnull(p.name));

select * from yfdb.emp_1 e left join yfdb.dept p on p.id=e.dept_id where e.age>35;

select avg(e.salary) from yfdb.emp_1 e where dept_id =(select id from yfdb.dept where name ='研发部');

select * from  yfdb.emp_1 e where salary>(select salary from yfdb.emp_1 where name ='灭绝');

select * from yfdb.emp_1 e where salary>(select avg(e.salary) from yfdb.emp_1 e);

select * from yfdb.emp_1 e where salary<(select avg(e.salary) from yfdb.emp_1 e);

select p.name,count(e.dept_id) from yfdb.dept p left join yfdb.emp_1 e on p.id = e.dept_id group by p.name;

select s.name,s.no,c.name from student s , student_course sc , course c where s.id = sc.studentid and sc.courseid = c.id;

 以上指令需要自己动手实践,笨鸟只是在这里记个笔记,供以后查看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值