结构化查询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同一等级的,是表级的操作,连接查询是用于多表查询,主要有内连接跟外连接,外连接又分左连接跟右连接,如下图

mysql 我想知道库里面哪些表字段包含某些关键字 mysql数据库所有关键字_sql

内连接

内连接就是两表求交集,取共有部分

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;

个人常用课程

C/C++Linux服务器开发/后台架构师

Golang DevOps项目实战