结构化查询SQL
SQL是结构化查询语言(Structure Query Language),它是关系型数据库的通用语言。SQL主要可以划分为以下 3 个类别:
- DDL(Data Defifinition Languages)语句数据定义语言,这些语句定义了不同的数据库、表、列、索引等数据库对象的定义。常用的语句关键字主要包括 create、drop、alter等。
- DML(Data Manipulation Language)语句数据操纵语句,用于添加、删除、更新和查询数据库记录,并检查数据完整性,常用的语句关键字主要包括 insert、delete、update和select等
- DCL(Data Control Language)语句数据控制语句,用于控制不同的许可和访问级别的语句。这些语句定义了数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括 grant、revoke等。
库操作
查询数据库
show databases;
创建数据库
create database ChatDB;
删除数据库
drop database test;
选择数据库
use test;//test是库名
表操作
查看表
show tables;
创建表
create table user(
id int unsigned primary key not null auto_increment,
name varchar(50) not null,
age tinyint not null,
sex enum('M','W') not null
)engine=INNODB default charset=utf8;
查看表结构
desc user;
查看创建的sql
show create table user\G;
删除表
drop table user;
CRUD操作
insert增加
insert into user(nickname, name, age, sex) values('fixbug', 'zhang san', 22, 'M');
insert into user(nickname, name, age, sex) ('888', 'gao yang', 20, 'M');
insert into user(nickname, name, age, sex) values('666', 'li si', 21, 'W'), ('888', 'gao yang', 20, 'M');
值得一提的是,上面三条sql虽然第三条跟前两条的存储结果一样,但是效率不一样,因为client要跟server进行TCP三次握手,需要建立通信线路、发送SQL语句、处理并且返回结果、释放链路。这个过程中一条SQL的效率要比多条SQL效率要高。
一般采用数据库连接池
update更新
update user set age=23 where name='zhang san';
update user set age=age+1 where id=3;
delete删除
delete from user where age=23;
delete from user where age between 20 and 22; delete from user;
select查询
常规查询用法
select * from user;
select id,nickname,name,age,sex from user;
select id,name from user;
select id,nickname,name,age,sex from user where sex='M' and age>=20 and age<=25;
select id,nickname,name,age,sex from user where sex='M' and age between 20 and 25;
select id,nickname,name,age,sex from user where sex='W' or age>=22;
去重distinct
select distinct name from user;
控制查询
select * from user where name is null;//或者not null
union合并查询
合并两个sql语句的结果,默认去重,all显示所有结果不去重
SELECT country FROM Websites UNION ALL SELECT country FROM apps ORDER BY country;
in子查询
select * from user where id in(10, 20, 30, 40, 50)
select * from user where id not in(10, 20, 30, 40, 50)
select * from user where id in(select stu_id from grade where average>=60.0)
分页查询
limit M,N从表中第一项偏移M项后,显示之后N行
select id,nickname,name,age,sex from user limit 10;
select id,nickname,name,age,sex from user limit 2000,10;
值得一提的是,limit可以提高效率,比如业务上只需要一条记录可以limit 1,这样全表扫描的时候找到了一条记录就不需要继续往下查找
分页查询算法:
select * from user limit (pageno-1)*pagenum,pagenum;
- pageo是指页号
- pagenum是指每一个的数据行数
值得一提的是,有些业务场景可以通过自增id进行分页偏移量的优化
排序order by
select id,nickname,name,age,sex from user where sex='M' and age>=20 and age<=25 order by age asc; select id,nickname,name,age,sex from user where sex='M' and age>=20 and age<=25 order by age desc;
分组查询
group by性能跟索引是相关的,否则很容易引起外排序跟临时文件
select sex from user group by sex;
select count(id),sex from user group by sex;
select count(id),age from user group by age having age>20;
连接查询
个人感想其实连接查询可以看成是跟from同一等级的,是表级的操作,连接查询是用于多表查询,主要有内连接跟外连接,外连接又分左连接跟右连接,如下图
内连接
内连接就是两表求交集,取共有部分
SELECT a.属性名1,a.属性名2,…,b,属性名1,b.属性名2… FROM table_name1 a inner join table_name2 b on a.id = b.id where a.属性名 满足某些条件;
预置条件:uid:1 cid:2
select score
from exame
where uid=1 and cid=2;
select a.uid,a.name,a.age,a.sex
from student a
where a.uid=1;
select c.score from exame c where c.uid=1 and c.cid=2;
// on a.uid=c.uid 区分大表 和 小表,按照数据量来区分,小表永远是整表扫描,然后去大表搜索
// 从student小表中取出所有的a.uid,然后拿着这些uid去exame大表中搜索
// 对于inner join内连接,过滤条件写在where的后面和on连接条件里面,效果是一样的
select a.uid,a.name,a.age,a.sex,c.score
from student a inner join exame c on a.uid=c.uid
where c.uid=1 and c.cid=2;
select b.cid,b.cname,b.credit
from course b
where b.cid=2;
select a.uid,a.name,a.age,a.sex,b.cid,b.cname,b.credit,c.score
from exame c inner join student a on c.uid=a.uid inner join course b on c.cid=b.cid
where c.uid=1 and c.cid=2;
select a.uid,a.name,a.age,a.sex,b.cid,b.cname,b.credit,c.score
from exame c inner join student a on c.uid=a.uid inner join course b on c.cid=b.cid where c.cid=2 and c.score>=90.0;
select b.cid,b.cname,b.credit,count(*)
from exame c inner join course b on c.cid=b.cid
where c.score>=90.0
group by c.cid having c.cid=2;
select b.cid,b.cname,b.credit,count(*) cnt
from exame c inner join course b on c.cid=b.cid
where c.score>=90.0
group by c.cid order by cnt;
外连接
值得一提的是,内连接有可能会产生中间表,但外连接一般不会。写外连接要注意过滤条件。左连接先扫描左表,右连接先扫描右表。
左连接
SELECT a.属性名列表, b.属性名列表 FROM table_name1 a LEFT JOIN table_name2 b on a.id = b.id;
// 把left这边的表所有的数据显示出来,在右表中不存在相应数据,则显示NULL
select a.*
from User a left outer join Orderlist b on a.uid=b.uid
where a.orderid is null;
右连接
SELECT a.属性名列表, b.属性名列表 FROM table_name1 a RIGHT [OUTER] JOIN table_name2 b on a.id = b.id;
// 把right这边的表所有的数据显示出来,在左表中不存在相应数据,则显示NULL
select a.*
from User a right outer join Orderlist b on a.uid=b.uid
where b.orderid is null;
个人常用课程