MySQL数据库(2)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介: MySQL数据库(2)

通配符

一般用于模糊搜索。

select * from info where name like "%本%";
select * from info where name like "%伟";
select * from info where email like "%@live.com";
select * from info where name like "卢%伟";
select * from info where name like "k%y";
select * from info where email like "lubenwei%";
select * from info where email like "_@live.com";
select * from info where email like "_ubenwei@live.com";
select * from info where email like "__benwei@live.com";
select * from info where email like "__benwei_live.co_";

注:数量少的时候用。

映射

想要获取的列。

select * from info;
select id, name       from info;
select id, name as NM     from info; 给name起了个别名
select id, name, 123  from info; 输出的时候又额外增加一列全是123
select id, name, 123 as age  from info; 全是123的表头起名为age
注意:少些select * ,自己需求。
select 
  id,
  name,
  666 as num,
  ( select max(id) from depart ) as mid, -- max/min/sum
  ( select min(id) from depart) as nid, -- max/min/sum
  age
from info;
select 
  id,
  name,
  ( select title from depart where depart.id=info.depart_id) as x1
from info;
# 注意:效率很低

case when then else

select 
  id,
  name,
  case depart_id when 1 then "第1部门" end v1
from info;
select 
  id,
  name,
  case depart_id when 1 then "第1部门" else "其他" end v2
from info;
select 
  id,
  name,
    -- 如果depart_id等于1
  case depart_id when 1 then "第1部门" end v1,  --注:没有就是Null
  case depart_id when 1 then "第1部门" else "其他" end v2,
  case depart_id when 1 then "第1部门" when 2 then "第2部门" else "其他" end v3,
    -- 如果age<18  范围外为Null
  case when age<18 then "少年" end v4,
  case when age<18 then "少年" else "油腻男" end v5,
  case when age<18 then "少年" when age<30 then "青年" else "油腻男" end v6
from info;
-- 直接case when不能用于等于如case when depart_id=1 报错
-- 别忘记逗号 且最后一条数据都不加逗号
select 
  id,
  name,
  case depart_id when 1 then "开发" when 2 then "运营" else "销售" end v3,
  case when age<18 then "少年" when age<30 then "青年" else "油腻男" end v6
from info;

如:打印出表中信息,年龄小于18的为少年,年龄。。。。

排序

select * from info order by age asc;  -- 顺序
select * from info order by age desc; -- 倒序
select * from info order by id desc;
select * from info order by id asc;
select * from info order by age asc,id desc; -- 优先按照age从小到大;如果age相同则按照id从大到小。
select * from info where id>10 order by age asc,id desc;
select * from info where id>6 or name like "%y" order by age asc,id desc;

取部分 limit offset

一般要用于获取部分数据。

select * from info limit 5;                       -- 获取前5条数据
select * from info order by id desc limit 3;            -- 先排序,再获取前3条数据
select * from info where id > 4 order by id desc limit 3;     -- 先排序,再获取前3条数据
select * from info limit 3 offset 2;  -- 从位置2开始,向后获取前3数据

数据库表中:1000条数据。


第一页:select * from info limit 10 offset 0;


第二页:select * from info limit 10 offset 10;


第三页:select * from info limit 10 offset 20;


第四页:select * from info limit 10 offset 30;

分组

这个要注意不用where用having了。

select age,max(id),min(id),count(id),sum(id),avg(id) from info group by age;
select age,count(1) from info group by age;
select depart_id,count(id) from info group by depart_id;
select depart_id,count(id) from info group by depart_id having count(id) > 2;
select count(id) from info;
select max(id) from info;
select age,max(id),min(id),sum(id),count(id) from info group by age;
select age,name from info group by age;  -- 不建议
select * from info where id in (select max(id) from info group by age);
select age,count(id) from info group by age having count(id) > 2;
select age,count(id) from info where id > 4 group by age having count(id) > 2;  -- 聚合条件放在having后面

到目前为止SQL执行顺序:

   where

   group by

   having

   order by

   limit


在id大于2的数据中统计不同年龄的各有多少个,把个数大于1的按照年龄从大到小显示出来,且只显示一个。


select age,count(id) from info where id > 2 group by age having count(id) > 1 order by age desc limit 1;


- 要查询的表info

- 条件 id>2

- 根据age分组

- 对分组后的数据再根据聚合条件过滤 count(id)>1

- 根据age从大到小排序

- 获取第1条

左右连表

多个表可以连接起来进行查询。

展示用户信息&部门名称:

主表 left outer join 从表 on 主表.x = 从表.id 
select * from info left outer join depart on info.depart_id = depart.id;
select info.id,info.name,info.email,depart.title from info left outer join depart on info.depart_id = depart.id;
从表 right outer join 主表 on 主表.x = 从表.id
select info.id,info.name,info.email,depart.title from info right outer join depart on info.depart_id = depart.id;

为了更加直接的查看效果,我们分别在 depart 表 和 info 中额外插入一条数据。

insert into depart(title) values("运维");

这样一来主从表就有区别:

  • info主表,就以info数据为主,depart为辅。
select info.id,info.name,info.email,depart.title from info left outer join depart on info.depart_id = depart.id;

depart主表,,就以depart数据为主,info为辅。

select info.id,info.name,info.email,depart.title from info right outer join depart on info.depart_id = depart.id;
select * from info left outer join depart on ....
select * from depart left outer join info on ....

简写:select * from depart left join info on ....

-- 内连接:    表  inner join 表  on 条件
select * from info inner join depart on info.depart_id=depart.id;
​到目前为止SQL执行顺序:
    join 
    on 
    where 
    group by
    having 
    order by
    limit 

写在最后:多张表也可以连接。

联合

select id,title from depart 
union
select id,name from info;
select id,title from depart 
union
select email,name from info;
-- 列数需相同
select id from depart 
union
select id from info;
-- 自动去重
select id from depart 
union all
select id from info;
-- 保留所有

表关系

  • 单表:

       略

  • 一对多:
create table depart(
  id int not null auto_increment primary key,
    title varchar(16) not null
)default charset=utf8;
create table info(
  id int not null auto_increment primary key,
    name varchar(16) not null,
    email varchar(32) not null,
    age int,
    depart_id int not null,
    constraint fk_info_depart foreign key (depart_id) references depart(id)
)default charset=utf8;

如果表结构已创建好了,额外想要增加外键:

alter table info add constraint fk_info_depart foreign key info(depart_id) references depart(id);

删除外键:

alter table info drop foreign key fk_info_depart;
  • 多对多
create table boy(
  id int not null auto_increment primary key,
    name varchar(16) not null
)default charset=utf8;
create table girl(
  id int not null auto_increment primary key,
    name varchar(16) not null
)default charset=utf8;
create table boy_girl(
  id int not null auto_increment primary key,
    boy_id int not null,
    girl_id int not null,
    constraint fk_boy_girl_boy foreign key boy_girl(boy_id) references boy(id),
    constraint fk_boy_girl_girl foreign key boy_girl(girl_id) references girl(id)
)default charset=utf8;

如果表结构已创建好了,额外想要增加外键:

alter table boy_girl add constraint fk_boy_girl_boy foreign key boy_girl(boy_id) references boy(id);
alter table boy_girl add constraint fk_boy_girl_girl foreign key boy_girl(girl_id) references girl(id);

删除外键:

xxxxxxxxxx alter table info drop foreign key fk_boy_girl_boy;alter table info drop foreign key fk_boy

用户管理

在MySQL的默认数据库 mysql 中的 user 表中存储着所有的账户信息(含账户、权限等)。

  • 创建和删除用户
create user '用户名'@'连接者的IP地址' identified by '密码';
create user wuyou@127.0.0.1 identified by 'root123';
drop user wuyou@127.0.0.1;
create user wuyou@'127.0.0.%' identified by 'root123';
drop user wuyou@'127.0.0.%';
create user wuyou@'%' identified by 'root123';
drop user wuyou@'%';
create user 'wuyou'@'%' identified by 'root123';
drop user 'wuyou'@'%';

修改用户

rename user '用户名'@'IP地址' to '新用户名'@'IP地址';
rename user wuyou@127.0.0.1 to wuyou@localhost;
rename user 'wuyou'@'127.0.0.1' to 'wuyou'@'localhost';

修改密码

set password for '用户名'@'IP地址' = Password('新密码')
set password for 'wuyou'@'%' = Password('123123');

授权管理

创建好用户之后,就可以为用户进行授权了。

  • 授权
grant all privileges on *.* TO 'wuyou'@'localhost';         -- 用户wuyou拥有所有数据库的所有权限
grant all privileges on day26.* TO 'wuyou'@'localhost';     -- 用户wuyou拥有数据库day26的所有权限
grant all privileges on day26.info TO 'wuyou'@'localhost';  -- 用户wuyou拥有数据库day26中info表的所有权限
grant select on day26.info TO 'wuyou'@'localhost';          -- 用户wuyou拥有数据库day26中info表的查询权限
grant select,insert on day26.* TO 'wuyou'@'localhost';      -- 用户wuyou拥有数据库day26所有表的查询和插入权限
grant all privileges on day26db.* to 'wuyou'@'%';

注意:flush privileges;   -- 将数据读取到内存中,从而立即生效。

  • 对于权限
  • all privileges  除grant外的所有权限

select          仅查权限

select,insert   查和插入权限

...

usage                   无访问权限

alter                   使用alter table

alter routine           使用alter procedure和drop procedure

create                  使用create table

create routine          使用create procedure

create temporary tables 使用create temporary tables

create user             使用create user、drop user、rename user和revoke  all privileges

create view             使用create view

delete                  使用delete

drop                    使用drop table

execute                 使用call和存储过程

file                    使用select into outfile 和 load data infile

grant option            使用grant 和 revoke

index                   使用index

insert                  使用insert

lock tables             使用lock table

process                 使用show full processlist

select                  使用select

show databases          使用show databases

show view               使用show view

update                  使用update

reload                  使用flush

shutdown                使用mysqladmin shutdown(关闭MySQL)

super                   􏱂􏰈使用change master、kill、logs、purge、master和set global。还允许mysqladmin􏵗􏵘􏲊􏲋调试登陆

replication client      服务器位置的访问

replication slave       由复制从属使用


对于数据库和表

数据库名.*            数据库中的所有

数据库名.表名          指定数据库中的某张表

数据库名.存储过程名     指定数据库中的存储过程

*.*                  所有数据库

  • 查看授权
show grants for 'wuyou'@'localhost';
show grants for 'wuyou'@'%';
  • 取消授权
revoke ALL PRIVILEGES on day26.* from 'wuyou'@'localhost';
revoke ALL PRIVILEGES on day26db.* from 'wuyou'@'%';

注意:flush privileges;   -- 将数据读取到内存中,从而立即生效。


哪怕没有A这个数据库,被授权了A数据库的操作,一样不会报错。


这里的localhost与127.0.0.1不一样。


一般情况下,在很多的 正规 公司,数据库都是由 DBA 来统一进行管理,DBA为每个项目的数据库创建用户,并赋予相关的权限。

索引

在数据库中索引最核心的作用是:加速查找。 例如:在含有300w条数据的表中查询,无索引需要700秒,而利用索引可能仅需1秒。

索引原理

       为什么加上索引之后速度能有这么大的提升呢? 因为索引的底层是基于B+Tree的数据结构存储的。

96447814-120fc980-1245-11eb-938d-6ea408716c72.png

数据库的索引是基于上述B+Tree的数据结构实现,但在创建数据库表时,如果指定不同的引擎,底层使用的B+Tree结构的原理有些不同。

  • myisam引擎,非聚簇索引(数据 和 索引结构 分开存储)
  • innodb引擎,聚簇索引(数据 和 主键索引结构存储在一起)
  • 非聚簇索引(mysiam引擎)
  • 96447814-120fc980-1245-11eb-938d-6ea408716c72.png
  • 聚簇索引(innodb引擎)

96447814-120fc980-1245-11eb-938d-6ea408716c72.png

上述 聚簇索引 和 非聚簇索引 底层均利用了B+Tree结构结构,只不过内部数据存储有些不同罢了。

在企业开发中一般都会使用 innodb 引擎(内部支持事务、行级锁、外键等特点),在MySQL5.5版本之后默认引擎也是innodb。

常见索引

在innodb引擎下,索引底层都是基于B+Tree数据结构存储(聚簇索引)。

在开发过程中常见的索引类型有:

  • 主键索引:加速查找、不能为空、不能重复。 + 联合主键索引
  • 唯一索引:加速查找、不能重复。 + 联合唯一索引
  • 普通索引:加速查找。 + 联合索引

主键和联合主键索引

create table 表名(
    id int not null auto_increment primary key,   -- 主键
    name varchar(32) not null
);
create table 表名(
    id int not null auto_increment,
    name varchar(32) not null,
    primary key(id)
);
create table 表名(
    id int not null auto_increment,
    name varchar(32) not null,
    primary key(列1,列2)          -- 如果有多列,称为联合主键(不常用且myisam引擎支持)
);
alter table 表名 add primary key(列名);
alter table 表名 drop primary key;

注意:删除索引时可能会报错,自增列必须定义为键。


ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key


alter table 表 change id id int not null;

create table t7(
    id int not null,
    name varchar(32) not null,
    primary key(id)
);
alter table t6 drop primary key;

唯一和联合唯一索引

create table 表名(
    id int not null auto_increment primary key,
    name varchar(32) not null,
    email varchar(64) not null,
    unique ix_name (name),
    unique ix_email (email),
);
create table 表名(
    id int not null auto_increment,
    name varchar(32) not null,
    unique (列1,列2)               -- 如果有多列,称为联合唯一索引。
);
create unique index 索引名 on 表名(列名);
drop unique index 索引名 on 表名;

索引和联合索引

create table 表名(
    id int not null auto_increment primary key,
    name varchar(32) not null,
    email varchar(64) not null,
    index ix_email (email),
    index ix_name (name),
);
create table 表名(
    id int not null auto_increment primary key,
    name varchar(32) not null,
    email varchar(64) not null,
    index ix_email (name,email)     -- 如果有多列,称为联合索引。
);
create index 索引名 on 表名(列名);
drop index 索引名 on 表名;
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
24天前
|
SQL 存储 关系型数据库
什么时候用sql数据库
在以下情况下,使用SQL数据库是合适的: 1. **数据存储在关系型数据库中**:如MySQL、PostgreSQL、Oracle等。因为SQL是关系型数据库的标准查询语言,能够方便地从数据库中
|
10月前
|
SQL 存储 关系型数据库
MYSQL数据库2
MYSQL数据库2
123 0
|
8月前
|
存储 关系型数据库 MySQL
|
10月前
|
SQL 存储 关系型数据库
MySQL数据库(四)
MySQL数据库(四)
|
11月前
|
SQL 存储 监控
简单说一下使用SQL数据库的心得
简单说一下使用SQL数据库的心得
85 1
|
10月前
|
SQL 关系型数据库 MySQL
MYSQL数据库6
MYSQL数据库6
30 0
|
10月前
|
SQL 关系型数据库 MySQL
MYSQL数据库4
MYSQL数据库4
54 0
|
10月前
|
SQL 关系型数据库 MySQL
MYSQL数据库5
MYSQL数据库5
35 0
|
10月前
|
SQL 关系型数据库 MySQL
MySQL数据库(二)上
MySQL数据库(二)上
|
SQL 存储 Oracle