数据库(DQL,多表设计,事务,索引)

目录

查询数据库表中数据

where  条件列表

group by  分组查询

having  分组后条件列表

order  by  排序字段列表

limit  分页参数 

多表设计

一对多

多对多

一对一

多表查询

事物

索引


查询数据库表中数据

关键字:SELECT

 中间有空格,加引号

select  字段列表

查询多个字段:select  字段1, 字段2, 字段3  from   表名; 

查询所有字段(通配符):select  *  from   表名;

设置别名:select  字段1  [ as  别名1 ] , 字段2  [ as  别名2 ]   from   表名;

去除重复记录:select  distinct  字段列表  from   表名;

from    表名列表

where  条件列表

条件查询:select  字段列表  from   表名   where   条件列表 ;

比较运算符

功能

>

大于

>=

大于等于

<

小于

<=

小于等于

=

等于

<>  或 !=

不等于

between ... and ...

在某个范围之内(含最小、最大值)

in(...)

在in之后的列表中的值,多选一

like  占位符

模糊匹配(  _匹配单个字符, %匹配任意个字符)

is null

是null

逻辑运算符

功能

and  或  &&

并且 (多个条件同时成立)

or  或  ||

或者 (多个条件任意一个成立)

not  或  !

非 , 不是

-- 1. 查询 姓名 为 杨逍 的员工
select * from emp where name = '杨逍';

-- 2. 查询在 id小于等于5 的员工信息
select * from emp where id <= 5;

-- 3. 查询 没有分配职位 的员工信息  -- 判断 null , 用 is null
select * from emp where job is null;

-- 4. 查询 有职位 的员工信息  -- 判断 不是null , 用 is not null
select * from emp where job is not null ;

-- 5. 查询 密码不等于 '123456' 的员工信息
select * from emp where password != '123456';

-- 6. 查询入职日期 在 '2000-01-01' (包含) 到 '2010-01-01'(包含) 之间的员工信息
select * from emp where entrydate between '2000-01-01' and '2010-01-01' ;

-- 7. 查询 入职时间 在 '2000-01-01' (包含) 到 '2010-01-01'(包含) 之间 且 性别为女 的员工信息
select * from emp where (entrydate between '2000-01-01' and '2010-01-01') and  gender = 2;

-- 8. 查询 职位是 2 (讲师), 3 (学工主管), 4 (教研主管) 的员工信息
select * from emp where job = 2 or job = 3 or job = 4;

select * from emp where job in (2,3,4);

-- 9. 查询姓名为两个字的员工信息
select * from emp where name like '__';

-- 10. 查询姓 '张' 的员工信息  ---------> 张%
select * from emp where name like '张%';

-- 11. 查询姓名中包含 '三' 的员工信息
select * from emp where name like '%三%';                                                                                       

group by  分组查询

聚合函数

定义:将一列数据作为一个整体,进行纵向计算

语法:select  聚合函数(字段列表)  from   表名 ;

函数

功能

count

统计数量

max

最大值

min

最小值

avg

平均值

sum

求和

null值不参与所有聚合函数运算。

统计数量可以使用:count(*)   count(字段)   count(常量),推荐使用count(*)。 

-- 聚合函数

-- 1. 统计该企业员工数量 -- count
-- A. count(字段)
select count(id) from emp;
select count(job) from emp; -- null值不参与聚合函数运算

-- B. count(*)
select count(*) from emp;

-- C. count(值)
select count(1) from emp;

-- 2. 统计该企业员工 ID 的平均值
select avg(id) from emp;

-- 3. 统计该企业最早入职的员工的入职日期
select min(entrydate) from emp;

-- 4. 统计该企业最近入职的员工的入职日期
select max(entrydate) from emp;

-- 5. 统计该企业员工的 ID 之和
select sum(id) from emp;

having  分组后条件列表

分组查询:select  字段列表  from   表名  [ where   条件 ]  group   by  分组字段名  [ having  分组后过滤条件 ];

-- 1. 根据性别分组 , 统计男性和女性员工的数量  -- count(*)
select gender , count(*) from emp group by gender;

-- 2. 先查询入职时间在 '2015-01-01' (包含) 以前的员工 , 并对结果根据职位分组 , 获取员工数量大于等于2的职位 -- count
select job ,count(*)  from emp where entrydate <= '2015-01-01'  group by job having count(*) >= 2;
 

here与having区别

1.执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组;而having是分组之后对结果进行过滤。

2.判断条件不同:where不能对聚合函数进行判断,而having可以。

注意:分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义。

执行顺序: where  >  聚合函数 > having 。

order  by  排序字段列表

条件查询:select  字段列表  from   表名   [ where   条件列表 ] [ group by  分组字段 ] order  by  字段1  排序方式1 , 字段2 排序方式2;

ASC:升序(默认值)

DESC:降序

如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序。

-- 1. 根据入职时间, 对员工进行升序排序  -- 排序条件
select * from emp order by entrydate asc ; -- 默认升序, asc可以省略的

-- 2. 根据 入职时间 对公司的员工进行 升序排序 , 入职时间相同 , 再按照 ID 进行降序排序
select * from emp order by entrydate asc , id desc ;
 

limit  分页参数 

分页查询:select  字段列表  from   表名  limit  起始索引, 查询记录数 ;

-- 1. 查询第1页员工数据, 每页展示10条记录
select * from emp limit 0,10;

select * from emp limit 10;


-- 2. 查询第2页员工数据, 每页展示10条记录
select * from emp limit 10,10;

-- 公式 : 页码 ---> 起始索引  ------->  起始索引 = (页码 - 1) * 每页记录数

 案例:select *from emp where name like '%张' and gender = 1 and entrydate between '2000-01-01' and '2015-12-31' order by update_time desc  limt 10 ;

多表设计

一对多

一对多关系实现:在数据库表中多的一方,添加字段,来关联一的一方的主键。

(父表)部门及员工(子表)模块的表结构

create table tb_dept(

      id int unsigncd primary kcy auto increment commont '上键ID',

     name varchar(10) not null unique comment '部门名称',

    create_time datetime not null comment  '创建时间',

    update_time datetime not null commenl  '修改时间'

comment '部门表';

dept_id int unsigned comment '归属的部门 ID';

create table tb_emp(
id int unsigned primary key auto_increment comment 'ID',
username varchar(20) not null unique comment '用户名',
password varchar(32) default '123456 comment '密码',
name varchar(10) not null comment '姓名',
gender tinyint unsigned not null comment "性别,说明:1 男,2 女',
image varchar(300) comment '图像',
job tinyint unsigned comment '职位,说明:1 班主任,2 讲师,3 学工主管,4 教研主管',
entrydate date comment '入职时间',

dept_id int unsigned comment '归属的部门ID';
create time datetime not null comment '创建时间,
update time datetime not null comment '修改时间'
) comment '员工表';

在数据库层面,并未建立关联,所以是无法保证数据的一致性和完整性的

外键约束

-- 1.创建表时指定

create table 表名(     

            字段名    数据类型,   

             ...   

            [constraint]   [外键名称]  foreign  key (外键字段名)   references   主表/父表 (字段名)    

);

-- 2.建完表后,添加外键

alter table  表名  add constraint  外键名称  foreign key (外键字段名) references  主表(字段名);

概念:在业务层逻辑中,解决外键关联。

通过逻辑外键,就可以很方便的解决上述问题。

多对多

案例: 学生 与 课程的关系

关系: 一个学生可以选修多门课程,一门课程也可以供多个学生选择

实现:建立第三张中间表,中间表至少包含两个外键,分别

一对一

案例: 用户 与 身份证信息 的关系

关系: 一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他字段放在另一张表中,以提升操作效率

实现:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)

constraint fk_user_id foreign key (user_id) references  tb_user(id)

案例

数据库(DQL,多表设计,事务,索引)_第1张图片

 

主键:int unsigned  无符号int

tinyint unsigned  排序(0-99数字)

varchar(20)   长度不固定   变相说明不能为空

decimal(8,2)  总长8,2位的小数

图片 varchar(300)

多表查询

select * from tb_emp,tb_dept;

笛卡尔积,在数学中,两个集合的所用组合情况

select * from tb_emp,tb_dept where tb_emp.dept_id = tb_dept.id;

内连接:相当于查询A,B交集部分数据

隐式内连接:select 字段列表 from 表1,表2 where 条件 ...;

查询员工的姓名,及所属的部门名称

select tb_emp.name , tb_dept.name from tb_emp,tb_dept where tb_emp.dept_id =

tb_dept.id;

起别名

select e.name,d.name from tb_emp e,tb_dept d where e.dept_id = d.id;

显示内连接:select 字段列表 from 表1 [inner] join 表2 on 连接条件...;

查询员工的姓名,及所属的部门名称

select tb_emp.name , tb_dept.name from tb_emp inner join tb_dept on  tb_emp.dept_id = tb_dept.id;

外连接

左外连接:查询左表所有数据(包括两张表交集部分数据)

select 字段列表 from 表1 left join 表2 on 连接条件...;

查询员工表 所有 员工的姓名,和对应的部门名称

select e.name,d.name from tb_emp e left join tb_dept d on e.dept_id = d.id;

右外连接:查询右表所有数据(包括两张表交集部分数据)

 

查询部门表 所有 部门的名称,和对应的员工姓名

select e.name,d.name from tb_emp e right join tb_dept d on e.dept_id = d.id;

子查询

SQL语句中嵌套select语句,嵌套查询,又称子查询。

select* from t1 where colurmn1 = (select column from t2 ...);

标量子查询:子查询返回的结果为单个值

子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式

常用的操作符:=   <>    >     >=     <    <=

-- . 查询 "教研部" 的所有员工信息
-- 1. 查询 教研部 的部门ID - tb_dept
select id from tb_dept where name = '教研部';

-- 2. 再查询该部门ID下的员工信息 - tb_emp
select * from tb_emp where dept_id = (select id from tb_dept where name = '教研部');

 列子查询:子查询返回的结果为一列 (可以是多行)

常用的操作符:in  、not in等


-- A. 查询 "教研部" 和 "咨询部 " 的所有员工信息
-- a. 查询 "教研部" 和 "咨询部" 的部门ID - tb_dept
select id from tb_dept where name = '教研部' or name = '咨询部';

-- b. 根据部门ID, 查询该部门下的员工信息 - tb_emp
select * from tb_emp where dept_id in (select id from tb_dept where name = '教研部' or name = '咨询部');

行子查询:子查询返回的结果是一行(可以是多列)。

常用的操作符:=  、<> 、in 、not  in


-- A. 查询与 "韦一笑" 的入职日期 及 职位都相同的员工信息 ;
-- a. 查询 "韦一笑" 的入职日期 及 职位
select entrydate,job from tb_emp where name = '韦一笑';

-- b. 查询与其入职日期 及 职位都相同的员工信息 ;
-- 方式一
select * from tb_emp where entrydate = (select entrydate from tb_emp where name = '韦一笑') and job = (select job from tb_emp where name = '韦一笑');

-- 方式二
select * from tb_emp where (entrydate,job)=(select entrydate,job from tb_emp where name = '韦一笑');
 

表子查询:子查询返回的结果是多行多列,常作为临时表

常用的操作符:in

-- A. 查询入职日期是 "2006-01-01" 之后的员工信息 , 及其部门名称
-- a. 查询入职日期是 "2006-01-01" 之后的员工信息
select * from tb_emp where entrydate > '2006-01-01';

-- b. 查询这部分员工信息及其部门名称 - tb_dept
select e.* , d.name from (select * from tb_emp where entrydate > '2006-01-01') e , tb_dept d where e.dept_id = d.id;

事物

事务 是一组操作的集合,它是一个不可分割的工作单位。事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作 要么同时成功,要么同时失败。

注意:默认MySQL的事务是自动提交的,也就是说,当执行一条DML语句,MySQL会立即隐式的提交事务。

开启事务:start transaction;  /  begin ;

提交事务:commit;

回滚事务:rollback;

四大特性

 原子性:事务是不可分割的最小单元,要么全部成功,要么全部失败

一致性:事务完成时,必须使所有的数据都保持一致状态

隔离性:数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行

持久性:事务一旦提交或回滚,它对数据库中的数据的改变就是永久的

索引

是帮助数据库 高效获取数据 的 数据结构 /树形结构

select * from tb_sku where sn = '100000003145008'; -- 14s


select count(*) from tb_sku;


create index idx_sku_sn on tb_sku(sn);

-- 创建 : 为tb_emp表的name字段建立一个索引 .

create  [ unique ]  index 索引名 on  表名 (字段名,... ) ;
create index idx_emp_name on tb_emp(name);

-- 查询 : 查询 tb_emp 表的索引信息 .

show  index  from  表名;
show index from tb_emp;

-- 删除: 删除 tb_emp 表中name字段的索引 .

drop  index  索引名  on  表名;
drop index idx_emp_name on tb_emp;

注意:主键字段,在建表时,会自动创建主键索引。

添加唯一约束时,数据库实际上会添加唯一索引。

优点:提高数据查询的效率,降低数据库的IO成本。 通过索引列对数据进行排序,降低数据排序的成本,降低CPU消耗。

缺点:索引会占用存储空间。 索引大大提高了查询效率,同时却也降低了insert、update、delete的效率。 

结构:

MySQL数据库支持的索引结构有很多,如:Hash索引、B+Tree索引、Full-Text索引等。我们平常所说的索引,如果没有特别指明,都是指默认的 B+Tree 结构组织的索引。

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