1. sql语句
1.1 对表和库的管理:
-
进入sql :mysql -u root -p
-
查看当前所有的数据库:show databases;
-
创建数据库:create database 数据库名 DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
create table tb5( id int not null auto_increment primary key, -- 不允许为空 & 主键 & 自增 name varchar(16) not null, -- 不允许为空 email varchar(32) null, -- 允许为空(默认) age int default 3 -- 插入数据时,如果不给age列设置值,默认值:3 )default charset=utf8;
-
删除数据库:drop database “数据库名”
具体查看文档
-
进入数据(进入文件):use “数据库名”;
-
查看此数据库下的所有表名:show tables
-
查看表里所以的内容:select * from 表名
-
查看表的属性:desc 表名
-
删除表 drop table 表名
-
清空表 delete from 表名; 或 truncate table 表名;
-
修改表
-
添加列:alter table 表名 add 列名 类型(+类型属性);
-
删除列:alter table 表名 drop column 列名;
-
修改列 类型 + 名称:alter table 表名 change 原列名 新列名 新类型;
注:
alter table tb change id id int; -- 允许为空,删除默认值,删除自增。(注意后面有属性的记得添加上,不然就全是默认的了)
-
-
常见类型看上面文档
1.2 对数据行的增删改查:
-
新增数据:
insert into 表名 (列名,列名,列名) values(对应列的值,对应列的值,对应列的值);
-
批量导入
INSERT INTO 表名 VALUES (值,值,值); -- 例如: INSERT INTO class VALUES ('1','三年二班'), ('2','三年三班'), ('3','一年二班'), ('4','二年九班');
-
删除数据
delete from 表名; delete from 表名 where 条件; 例如: delete from tb1 where id>9;
-
修改数据
update 表名 set 列名=值; update 表名 set 列名=值 where 条件; 例如: update tb1 set name="wupeiqi" where id=1; update tb1 set age=age+1 where id=2;-- 相当于python的a+=1 update L3 set name=concat(name,"123") where id=2; -- concat一个函数,可以拼接字符串
2. 查询数据(重点单独拿出来)
select * from 表名; -- 查看所有列
select 列名,列名,列名 from 表名; -- 查看指定列
select * from 表名 where 条件; -- 符合条件在查看
例如:现在创建如下两张表。
create database day26db default charset utf8 collate utf8_general_ci;
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
)default charset=utf8;
insert into depart(title) values("开发"),("运营"),("销售");
insert into info(name,email,age,depart_id) values("武沛齐","wupeiqi@live.com",19,1);
insert into info(name,email,age,depart_id) values("于超","pyyu@live.com",49,1);
insert into info(name,email,age,depart_id) values("alex","alex@live.com",9,2);
insert into info(name,email,age,depart_id) values("tony","tony@live.com",29,1);
insert into info(name,email,age,depart_id) values("kelly","kelly@live.com",99,3);
insert into info(name,email,age,depart_id) values("james","james@live.com",49,1);
insert into info(name,email,age,depart_id) values("李杰","lijie@live.com",49,1);
2.1 条件
根据条件搜索结果
where
-
select * from info where age > 30; -- 当age > 30查看此表
between
-
select * from info where id between 2 and 4; -- id大于等于2、且小于等于4 -- 也可以or not与python一样
exists
-
select * from info where exists (select * from depart where id=5); -- exists后面的数据是否存在, 如果存在就查询info表
这些都可以加not变成反义
2.2 通配符
name like
- % 一个或多个
- _ 一个
select * from info where name like "%沛%"; -- 只要name中间是“沛”的那行数据
select * from info where email like "_upeiqi@live.com";
注:两个可以一起用
2.3 映射
想要获取的列。
注意:少些select * ,自己需求。
max/min/sum 最大值/最小值/总和
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
( select sum(id) from depart) as sid, -- max/min/sum
age
from info;
**当然也可以搭配 where ** 如:
select
id,
name,
( select title from depart where depart.id=info.depart_id) as x1
from info;
# 注意:效率很低
+----+--------+------+
| id | name | x1 |
+----+--------+------+
| 1 | 武沛齐 | 开发 |
| 2 | 于超 | 开发 |
| 3 | alex | 运营 |
| 4 | tony | 开发 |
| 5 | kelly | 销售 |
| 6 | james | 开发 |
| 7 | 李杰 | 开发 |
+----+--------+------+
case when then 映射
- case 列名 when 值 then 表值存在时的结果 else 值不存在是的结果 end 表头名
select
id,
name,
case depart_id when 1 then "第1部门" else "其他" end v2
from info;
+----+--------+---------+
| id | name | v2 |
+----+--------+---------+
| 1 | 武沛齐 | 第1部门 |
| 2 | 于超 | 第1部门 |
| 3 | alex | 其他 |
| 4 | tony | 第1部门 |
| 5 | kelly | 其他 |
| 6 | james | 第1部门 |
| 7 | 李杰 | 第1部门 |
+----+--------+---------+
# 当然你可以一直 when then
case depart_id when 1 then "第1部门"
when 2 then "第2部门" else "其他" end v3,
2.4 排序
order by
- select * from 表名 order by 列名 desc; – 根据列的值倒序
desc – 倒序
asc – 顺序
-
select * from info order by age desc; +----+--------+------------------+------+-----------+ | id | name | email | age | depart_id | +----+--------+------------------+------+-----------+ | 5 | kelly | kelly@live.com | 99 | 3 | | 2 | 于超 | pyyu@live.com | 49 | 1 | | 6 | james | james@live.com | 49 | 1 | | 7 | 李杰 | lijie@live.com | 49 | 1 | | 4 | tony | tony@live.com | 29 | 1 | | 1 | 武沛齐 | wupeiqi@live.com | 19 | 1 | | 3 | alex | alex@live.com | 9 | 2 | +----+--------+------------------+------+-----------+ select * from info order by age asc,id desc; -- 优先按照age从小到大;如果age相同则按照id从大到小。
也可以跟上述方法结合
select * from info where id>6 or name like "%y" order by age asc,id desc; -- 找 id>6 或 name里有%y的 且优先按照age顺序排序,如果相同,则按照id倒序排序
2.5 取部分
一般要用于获取部分数据。
limit
- limit 数量 – 取前几条
select * from info limit 5; -- 获取前5条数据
select * from info where id > 4 order by id desc limit 3; -- 先排序,再获取前3条数据
limit offset
select * from info limit 3 offset 2; -- 从位置2开始,向后获取前3数据
2.6 分组
group by
group by
- select 列名 或 聚合函数(列名) from 表名 group by 列名(根据该列分组)
select age,count(id),max(id),min(id),sum(id),avg(id) from info group by age;
count(1) 该组的个数
select depart_id,count(id) from info group by depart_id;
+-----------+-----------+
| depart_id | count(id) |
+-----------+-----------+
| 1 | 5 |
| 2 | 1 |
| 3 | 1 |
+-----------+-----------+
group by + having
- having 筛选
select depart_id,count(id) from info group by depart_id having count(id) > 2;
+-----------+-----------+
| depart_id | count(id) |
+-----------+-----------+
| 1 | 5 |
+-----------+-----------+
2.7 左右连表
多个表可以连接起来进行查询。
left outer join on
展示用户信息&部门名称:
主表 left outer join 从表 on 主表.x = 从表.id
select info.id,info.name,info.email,depart.title from info left outer join depart on info.depart_id = depart.id;
+----+--------+------------------+-------+
| id | name | email | title |
+----+--------+------------------+-------+
| 1 | 武沛齐 | wupeiqi@live.com | 开发 |
| 2 | 于超 | pyyu@live.com | 开发 |
| 4 | tony | tony@live.com | 开发 |
| 6 | james | james@live.com | 开发 |
| 7 | 李杰 | lijie@live.com | 开发 |
| 3 | alex | alex@live.com | 运营 |
| 5 | kelly | kelly@live.com | 销售 |
+----+--------+------------------+-------+
简写:select * from depart left join info on ....
-- 内连接: 表 inner join 表 on 条件
select * from info inner join depart on info.depart_id=depart.id;
# 写在最后:多张表也可以连接。
2.8 联合
union
select id from depart
union -- union all 保留所有
select id from info;
union -- 自动去重
union all -- 保留所有
-- 联合只需要列数相同就行
2.9 SQL执行顺序
到目前为止SQL执行顺序:
join 链表
on 后面为条件
where 条件
group by 分组
having 分组的筛选
order by 排序
limit 取部分
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条
2.10 表的关系
在开发项目时,需要根据业务需求去创建很多的表结构,以此来实现业务逻辑,一般表结构有三类:
-
单表,单独一张表就可以将信息保存。
-
一对多,需要两张表来存储信息,且两张表存在 一对多或 多对一关系。
-
多对多,需要三张表来存储信息,两张单表 + 关系表,创造出两个单表之间多对多关系。
外键约束:
当一个表的一列要关联另一种表的一列时,为了让数据变的合理,我们要在”创建表时”加上约束
一对多示例:
这个depart表的id,与info表的depart_id有联系
在创建info表的depart_id哪列时,加上constraint fk_info_depart foreign key (depart_id) references depart(id)
,当在往depart_id列插入数据是如果不是depart表id那列的数值的话就会报错
alter table 当前表名 add constraint fk_info_depart foreign key 当前表(要关联的列名) references 被关联表(被关联列名);
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)
-
如果表结构已创建好了,额外想要增加外键:
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;
多对多时就是多加几个外键
小Tips
在以后项目开发时,设计表结构及其关系的是一个非常重要的技能。一般项目开始开发的步骤:
- 需求调研
- 设计数据库表结构(根据需求)
- 项目开发(写代码)
大量的工作应该放在前2个步骤,前期的设计完成之后,后续的功能代码开发就比较简单了。
2.11 用户管理
在MySQL的默认数据库 mysql
中的 user
表中存储着所有的账户信息(含账户、权限等)。
-
查看所有用户信息
select user,authentication_string,host from mysql.user;
-
创建用户
create user '用户名'@'连接者的IP地址' identified by '密码';
create user wupeiqi1@127.0.0.1 identified by 'root123'; drop user wupeiqi1@127.0.0.1; create user wupeiqi3@'%' identified by 'root123'; -- % 就是在任何ip都可连接 drop user wupeiqi3@'%'; create user 'wupeiqi4'@'%' identified by 'root123'; drop user 'wupeiqi4'@'%';
-
修改用户
rename user '用户名'@'IP地址' to '新用户名'@'IP地址';
rename user wupeiqi1@127.0.0.1 to wupeiqi1@localhost; rename user 'wupeiqi1'@'127.0.0.1' to 'wupeiqi1'@'localhost';
-
修改密码
set password for '用户名'@'IP地址' = Password('新密码') set password for 'wupeiqi4'@'%' = Password('123123');
创建好用户之后,就可以为用户进行授权了。
- 授权
grant 权限 on 数据库.表 to '用户'@'IP地址'
grant all privileges on *.* TO 'wupeiqi'@'localhost'; -- 用户wupeiqi拥有所有数据库的所有权限
grant all privileges on day26.* TO 'wupeiqi'@'localhost'; -- 用户wupeiqi拥有数据库day26的所有权限
grant all privileges on day26.info TO 'wupeiqi'@'localhost'; -- 用户wupeiqi拥有数据库day26中info表的所有权限
- 取消和查看权限
show grants for '用户'@'IP地址' -- 查看
show grants for 'wupeiqi4'@'%';
revoke 权限 on 数据库.表 from '用户'@'IP地址' -- 取消
revoke ALL PRIVILEGES on day26db.* from 'wupeiqi4'@'%';
flush privileges; -- 将数据读取到内存中,从而立即生效。