数据库基础/语法
数据库
软件开发目录
bin 启动文件
conf
core
db
lib
log =>数据库 =>elasticsearch elk
readme.txt
# data 数据
# scripts 脚本
# docs 文档
如何将单机变成联网
将数据库保存部分全部统一起来
所有人操作数据都来一个地方操作
数据库的本质
本质其实就是一款基于网络通信的应用程序 CS架构软件
那其实每个人都可以开发一款数据库软件,因为它仅仅就是一个基于网络通信的应用程序
也就意味着数据库软件其实有很多很多
关系型数据库 #有固定的表结构,可以建立表与表之间的联系
MySQL ORACLE(维护一次十几万,大型国企才用得起) db2 access sql server sqllie
非关系型数据库
redis(主要做缓存使用) mongodb(最像关系型数据库) memcache
关系型
1.数据之间彼此有关系或者约束
男生表和前女友表
2.存储数据的表现形式通常是以表格存储
每个字段还会有存储类型的限制
比如姓名只能存字符串。。。
非关系型
存储数据通常都是以kv键值对的形式
MySQL
任何基于网络通信的应用程序底层用的都是 socket
服务端
基于 socket通信
收发消息
基于 socket通信
收发消息
如何兼容
1.本身牛逼 自动区分对应语言
2.统一标准
MySQL不仅仅支持MySQL自己编写的客户端app还支持其他编程语言来充当客户端操作
如何解决语言沟通的障碍
1.让五福短兼容所有的语言(一个人精通多国语言)
2.采用统一的语言(SQL语句)
概念
库 》》》 文件夹
表 》》》 文件
记录 》》》 文件内一行行的数据
name password hobby
Jason 123 学习
egon 123 女教练
tank 123 吃生蚝
表头 表格的第一行字段
字段 name、 password、hoby 字段名+字段类型
服务端和客户端
服务端
mysqld.exe
客户端
mysql.exe
ps
在前期配置MySQL的时候 cmd终端尽量以管理员的身份运行
windows + r 输入cmd 进入的是普通用户终端 有一些命令是无法执行的
搜索 cmd右键以管理员身份运行
常见软件的默认端口号
MySQL 3306
redis 6379
mongodb 27017
django 8000
flask 5000
第一次连接的时候是没有密码的,直接回车即可
mysql -h 127.0.0.1 -p 3306 -uroot -p
port端口 管理员用户 密码
sql语句初识
1. MySQL 中的sql语句是以分号作为结束的标志
2.基本命令
show databases 查看所有的库名
3.连接服务端的命令可以简写
mysql -uroot -p
4.当输入的命令部队 又不想让服务器执行并返回报错信息 可以用\c取消
5.客户端退出 退出命令加不加分号都能执行
quit
exit
6.当你在乱接客户端的时候 发现只输入mysql也能连接
但是不是管理员身份 而只是一个游客模式
环境变量配置及服务制作
1.如何查看当前进程
tasklist
tasklist |findstr mysqld
2.如何杀死具体进程(只有在管理员cmd窗口下才能成功)
taskkill /F/PID PID号
设置密码
mysqladmin -uroot -p(写原密码) password(写新密码)
该命令直接在终端输入即可 无需进入客户端
破解密码(了解)
可以将mysql获取用户名和密码校验的功能看成是一个装饰器,装饰在了客户端请求访问的功能上
移除装饰器:
1.先关闭当前mysql服务器
命令行的方式启动(跳过用户名和密码验证功能)
mysql --skip-grant-tables
2.直接以无密码的方式连接
mysql -uroot -p 直接回车
3.修改当前用户的密码
update mysql.user set password=password(123456) where user='root' and host='localhost'
存储用户表的密码字段 存储的是密文
只有用户自己知道明文是什么 其他人都不知道 这样更加安全
密码比对也只能比对密文
4.立刻将修改数据刷到硬盘
flush privileges;
5.关闭当先服务端 然后以正常校验授权表的形式登录
统一编码
mysql默认的配置文件
my-default.ini
ini结尾的一般都是配置文件
程序启动会先加载配置文件中的配置之后才真正的启动
mysqld 一旦服务端启动会立刻加载下面的配置
[mysql]一旦客户端启动会立刻加载下面的配置
[client]其他客户端
需要你自己建一个my.ini的配置文件
验证配置是否真的是自动加载
[mysql]
print('hello world')
修改配置文件后一定要重新启动
统一编码的配置 无需掌握
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
偷懒 将管理员的用户名和密码也添加到配置文件中
[mysql]
user="root"
password=xxxxx
基本sql语句介绍
针对库的增删改查(文件夹)
增create database db1;create database db1 charset='gbk';
查show databases; # 查所有show create database db2;
# 查单个改alter database db2 charset='utf-8';
删drop database db2;
针对表的增删改查(文件)
在操作表(文件)的时候 需要指定所在的库(文件夹)
# 查看当前所在库的名字select databases();
# 切换库use db1;
# 增create table t1(id int,name char(4)); #char name只能存字符串 最大位数为4
# 查show tables;
# 查看当前库下所有的表名show create table t1;
# 查单个describe t1; #支持简写 desc t1;
# 改字段 alter table t1 modify name char(16);
# 删drop table t1;create table db2.t1(id int); 也可以用绝对路径的形式操作不同的库
针对数据的增删改查(一行行数据)
一定要先有库 有表 最后才能操作记录
#增insert into t1 values(1,'jason');
#insert into t1 values(1,'jason'),(2,'egon'),(3,'tank');
#查select * from t1; #该命令当数据量特别大的时候不建议使用 *代表全部select name from t1;
#改update t1 set name='DSB' where id>1;
#删delete from t1 where id>1;delete from t1 where name='jason';
#将表所有的数据清空delete from t1;
存储引擎
日常生活中文件格式有很多中,并且针对不同的文件格式会有对应不同存储方式和处理机制( txt, pdf,word, mp4…)
针对不同的数据应该有对应的不同的处理机制来存储
存储引擎就是不同的处理机制
MySQL主要存储引擎
lnnodb
是MySQL5.5版本之后默认的存储引擎
存储数据较安全
# 功能:
1. 支持事务
2. 行级锁
3. 外键
Mylsam
是MySQL5.5版本之前默认的存储引擎
速度比lnnodb快,但是我们更注重数据安全
# 不支持事务
# 表级锁
memory
内存引擎(数据全部存放在内存中)断电数据流失
blackhole
无论存什么都立刻消失(黑洞)
查看所有的数据库的存储引擎
show engines;
不同的存储引擎在存储表的时候 异同点
create table t1(id int) engine=lnnodb
t1.frm 表结构 t1.ibd 表数据
create table t2(id int) engine=Mylsam
t2.frm 表结构 t2.MYD 表数据 t2.MYI 索引(index:就类似于书的目录,基于目录查找对应的数据,速度更快)
create table t3(id int) engine=memory
t3.frm 数据在内存,无需文件储存
create table t4(id int) engine=blackhole
t4.frm 没有数据
创建表的完整语法
#语法crete table 表名
字段名1 类型(宽度) 约束条件, 字段名2 类型(宽度) 约束条件, 字段名3 类型(宽度) 约束条件,
#注意
1.在同一张表中字段名不能重复
2.宽度和约束条件是可选的(可写可不写)而字段名和字段类型是必须的
约束条件写的话 也支持写多个 字段名1 类型(宽度) 约束条件1 约束条件2..., create table t5(id int); #必须有int
3.最后一行不能有逗号
#宽度 一般情况下指的是对存储数据的限制 create table t7(name char);
默认宽度是1 insert into t7 values('jason'); insert into t7 values('null');
关键字NULL 类似于 None 不同版本结果不同
5.6版本没有开启严格模式 固定只能存一个字符或者多个字符,给了多个字符,会自动截取
5.7版本及以上或者开启了严格模式 规定只能存几个 就不能超过 一旦超出范围立刻报错约束条件
null not null 不能插入nullcreate table t8 (id int,name char not null);
宽度和约束条件到底是什么关系 宽度是用来限制数据的存储 约束条件是在宽度的基础之上增加的额外的约束
基本数据类型
整型:
tinyint smallint int bigint
浮点型
float double decimal
字符串
char varchar
# 集合
create table user2(
id int not null,
name varchar(16),
gender enum('male', 'female', 'others'),
hobbies set('read', 'sleep', 'play ball', 'run')
);
整型
分类
tinyint smallint int bigint
作用
存储年龄、登记、id、号码等等
以TINYINT为例
是否有符号
默认情况下是带符号的
超出最大值会怎样
超出限制只存最大可接受值
create table t9(id tinyint );
insert into t9 values(-129),(256);
#约束条件 就是,对于数据库表插入数据时加以约束限制。
create table t10(id tinyint unsigned);
create table t11(id int );
#int 默认也是带符号的
#整型默认情况下都是带有符号的
# 针对整型 括号内的宽度到底是干嘛的
create table t12(id int(8));
insert into t12 values(123456789)
特例:只有整型括号里面的数字不是表示限制位数,而是显示长度
id int(8)
如果数字没有超出8位 那么默认用0填充
如果数字超出了8位 那么有几位就存几位(但是还是要遵守最大值)
create table t13(id int(8) unsigned zerofill);
#用0填充至8位
#总结:
针对整型字段 括号内无需指定宽度 因为它默认的宽度已经足够显示所有的数据了
严格模式
#查看严格模式
show variables like "%mode"
模糊匹配/查询
关键字 like
%:匹配任意多个字符
_:匹配任意单个字符
#修改严格模式
set session 只在当前窗口有效
set global 全局有效
代码:
set global aql_mode = 'STRICT_TRANS_TABLES';
修改完之后重新进入客户端才可以
#浮点型
分类
FLOAT DOUBLE DECIMAL
作用
身高 体重 薪资
#存储限制
FLOAT (255,30) #总共255位,小数部分占30位
DOUBLE (255,30)
DECIMAL(65,30) #最多只能存65位
#精确度验证
create table t15(id float(255,30));
create table t16(id double(255,30));
create table t17(id decimal(65,30));
#精确度
FLOAT < DOUBLE < DECIMAL
字符类型
char
定长
char(4) 超过四个字符直接报错 不够四个 空格补全
varchar
变长
varchar(4) 数据超过四个直接报错 不够四个 有几个存几个
create table t18 (name char (4));
create table t18 (name varchar (4));
insert into t18 values('a');
insert into t19 values('a');
#char_length 统计字段长度
select char_length(name) from t18;
select char_length(name) from t19;
现实的时候MySQL会自动将多余的空格剔除
#再次修改aql_mode 让MySQL 不要做自动剔除操作
set global sql_mode = 'STRICT_TRANS_TABLES,PAD_CHAR_TO_FULL_LENGYH';
对比
char
优点:存储都很简单
直接按照固定的字符存取数据即可
缺点:浪费空间
varchar
优点:节省空间
缺点:存取较为麻烦
前面会加一个报头 1bytes+jason 1bytes+egon
存的时候需要制作报头
取的时候也需要先读取报头 之后才能读取真实数据
以前基本上都是用的char 现在用varchar的也比较多
时间类型
分类
date: 年月日
datetime:年月日时分秒 2020-5-4 11:11:11
time:时分秒
Year:2020
create table student(id int,
name varchar(16),
born_year year,
birth date,
study_time time,
reg_time datetime);
insert into student values(1,'egon','1999','1880-11-11','11:11:11','2020-11-11 11:11:11');
枚举
分类
枚举(enum) 多选一
集合(set) 多选多
具体使用
create table user(
id int,
name char(16),
gender enum('male','female','others')
);
insert into user values(1,'jason','male');
insert into user values(2,'egon','xxxxooo');
#枚举字段 后期在存数据的时候只能从枚举里面选一个储存
create table teacher(
id int,
name char(16),
gender enum('male','female','others'),
hobby set('read','DBJ','hecha' #列举
);
insert into teacher values(1,'jason','male','read');
insert into teacher values(1,'egon','female','DBJ,hecha');
insert into teacher values(1,'tank','others','生蚝'); #错误
集合可以只写一个,但是不能写没有列举的 注意:枚举里面有什么数据,就选择什么数据插入即可;没有5.7以上的版本会报错
约束条件
defult 默认值
#补充知识点 插入数据的时候可以指定字段
create table t1(
id int,
name char(16)
);
insert into t1(name,id) values('jason',1);
create table t2(
id int,
name char(16)
gender enum('male','female','others') defult 'male'
);
insert into t2(id,name) values (1,'jason');
insert into t2 values (2,'egon','female');
有就传 没有就不传
unique唯一
#单列唯一
create table t3(
id int unique,
name char(16)
);
insert into t3 values(1,'jason'),(1,'egon'); 报错
insert into t3 values(1,'jason'),(2,'egon');
#联合唯一
ip和port
单个都可以重复 加载到一起不可重复
create table t4(
ip int,
ip char(16),
port int,
unique(ip,port)
);
insert into t4 values(1,'127.0.0.1',8080);
primary key 主键
1.单单从约束效果上来看primary key等价于not null + unique
非空且唯一!!!
create table t5(id int primary key);
insert into t5 values(null); #报错
insert into t5 values(1),(1); #报错
insert into t5 values(1),(2);
2.他除了有约束条件之外 他还是innodb存储引擎组织数据的依据
innodb 存储引擎在创建表的时候必须要有primary key
因为它类似于书的目录 能够帮助查询效率并且也是建表的依据
#1. 一张表中有且只有一个主键 如果你没有设置主键 name会从上往下搜索直到遇到一个非空且唯一的字段将它自动升级为主键
create tables t6(
id int,
name char(16),
age int not null unique,
addr char(32) not null unique
);
#2. 如果表中没有主键也没有其他任何的非空且唯一字段 那么Innodb会采用自己内部提供的一个隐藏字段作为主键,隐藏意味着你无法使用到它 就无法提示查询速度
#3.一张表中通常都应该有一个主键字段,并且通常将id(编号,也可以是其他的,比如uid)字段作为主键
#单个字段主键
create table t5(
id int primary key
name char(16)
);
#联合主键(多个字段联合起来作为表的主键 本质还是一个主键)
create table t7(
ip int,
ip char(16),
port int,
primary key(ip,port)
);
在创建表的时候id字段一定要加primary key
auto_increment自增
#当编号特别多的时候 人为的去维护太麻烦
creatr table t8(
id int primary key auto_increment,
name char(16)
);
insert into t8(name) valus('jason'),('egon'),('kevin');
# auto_increment只能加在K键上 不能给普通字段加
以后在创建表的id(数据的唯一标识id、uid、sid)字段的时候
直接写就可以
id int primary key auto_increment
在删除表中数据的时候 主键的自增不会停止
# truncate t8
# select * from t8
就会重置
外键
外键就是用来帮助我们建立表与表之间关系的
foregin key
表关系
表与表之间四种关系
一对多关系
多对多关系
一对一关系
没有关系
在确定表与表之间关系的时候 一定要换位思考
先站在员工表考虑
员工表里面的一个员工能否对应部门表里面的多个部门 不能
再站在部门表考虑
部门表里面的一个部门能否对应员工表里面的多个员工 可以
结论:
员工表与部门表只是单向的一对多成立,那么员工表和部门表就是'一对多'表关系
一对多关系
foreign key dep
1.一对多表关系 外键字段建在多的一方
2.在创建表的时候 一定要先建被关联关系
3.在录入数据的时候 也必须先录入被关联表
create table dep(
id int primary key auto_increment,
dep_name char(16),
dep_desc char(32)
);
create table emp(
id int primary key auto_increment,
name char(16),
gender enum('male','female','others') defult 'male',
dep_id int,
foreign key(dep_id) references dep(id)
);
insert into dep(dep_name,dep_desc) valus('sb教学部','教书育人'),('外交部','多人外交'),('nb技术部','技术能力有限部门');
insert into emp(name,dep_id) values('jason',2),('egon',1),('tank',1),('kevin',3);
#修改emp里面的dep_id字段或者dep表里面的id字段
update dep set id=200 where id=2; #报错
#删除dep表里面的数据
delete from dep; #报错
#1.先删除教学部对应的员工数据,之后再删除部门
#2.真正做到数据之间有关系
更新就同步更新
删除就同步删除
级联更新 级联删除
同步更新 同步删除
create table dep(
id int primary key auto_increment,
dep_name char(16),
dep_desc char(32)
);
create table emp(
id int primary key auto_increment,
name char(16),
gender enum('male','female','others') defult 'male',
dep_id int,
foreign key(dep_id) references dep(id)
on update cascade #同步更新
on delete cascade #同步删除
);
多对多
在多对多中由于二者是互相被关联的,所以将不适用一对多的方法,需要一个'中间商'
create table dep(
id int primary key auto_increment,
title varchar(32),
print int,
);
create table author(
id int primary key auto_increment,
name varchar(32),
age int,
);
create table book2author( #中间商
id int primary key auto_increment,
author_id int,
book_id int,
foreign key(author_id) references author(id)
on update cascade
on delete cascade
foreign key(book_id) references book(id)
on update cascade
on delete cascade
);
一对一关系
外键字段建在任意一方都可以 但是最好建在查询频率比较高的表中
create table authordetail(
id int primary key auto_increment,
phone int,
addr varchar(64)
)
create table author(
id int primary key auto_increment,
name varchar(32),
age int,
authordetail_id int unique,
foreign key(authordetail_id) references authordetail(id)
on update cascade
on delete cascade
)
总结
表关系的建立需要用到foreign key 一对多
外键字段建在多的一方 多对多
自己开设第三张存储 一对一
建在任意一方都可以 推荐查询频率较高的表中
修改表
MySQL不区分大小写
1.修改表名
alter table 表名 rename 新表名;
2.增加字段
alter table 表名 add 字段名 字段类型(宽度) 约束条件;
alter table 表名 add 字段名 字段类型(宽度) 约束条件 first;
alter table 表名 add 字段名 字段类型(宽度) 约束条件 after 字段名;
3.删除字段
alter table 表名 drop 字段名;
4.修改字段
alter table 表名 modify 字段名 字段类型(宽度)
alter table 表名 change 旧字段名 新字段名 字段类型(宽度) 约束条件;
复制表
每次查询的结果都是一张虚拟表
create table 表名 select * from 新表名
不能复制主键 外键 索引
create table 表名 select * from 新表名 where id>3;
当字段特别多的时候 展示的时候错乱 可以使用\G分行展示
select * from emp\G;
几个重要关键字的执行顺序
select id,name from emp where id>3;
执行顺序
from
where
select
创建表准备
create table emp(
id int primary key auto_increment,
name varchar(20) not null,
sex enum('male','female') not null default 'male', #大部分是男的
age int(3) unsigned not null default 28,
hire_date date not null,
post varchar(50),
post_comment varchar(100),
salary double(15,2),
office int, #一个部门一个屋子
depart_id int
);
#插入记录
#三个部门:教学,销售,运营
insert into emp(name,sex,age,hire_date,post,salary,office,depart_id) values
('tom','male',78,'20150302','teacher',1000000.31,401,1),
('kevin','male',81,'20130305','teacher',8300,401,1),
('tony','male',73,'20140701','teacher',3500,401,1),
('owen','male',28,'20121101','teacher',2100,401,1),
('jack','female',18,'20110211','teacher',9000,401,1),
('jenny','male',18,'19000301','teacher',30000,401,1),
('sank','male',48,'20101111','teacher',10000,401,1),
('哈哈','female',48,'20150311','sale',3000.13,402,2),#以下是销售部门
('呵呵','female',38,'20101101','sale',2000.35,402,2),
('西西','female',18,'20110312','sale',1000.37,402,2),
('乐乐','female',18,'20160513','sale',3000.29,402,2),
('拉拉','female',28,'20170127','sale',4000.33,402,2),
('僧龙','male',28,'20160311','operation',10000.13,403,3), #以下是运营部门
('程咬金','male',18,'19970312','operation',20000,403,3),
('程咬银','female',18,'20130311','operation',19000,403,3),
('程咬铜','male',18,'20150411','operation',18000,403,3),
('程咬铁','female',18,'20140512','operation',17000,403,3);
where约束条件
# 1.查询id大于等于3小于等于6的数据
select id,name from emp where id >= 3 and id <= 6;
select * from emp where id between 3 and 6;
# 2.查询薪资是20000或者18000或者17000的数据
select * from emp where salary = 20000 or salary = 18000 or salary = 17000;
select * from emp where salary in (20000,18000,17000); # 简写
"""
模糊查询
关键字
like
关键符号
%:匹配任意个数的任意字符
_:匹配单个个数的任意字符
show variables like '%mode%';
""" elasticsearch
# 3.查询姓名中带有字母o的员工姓名和薪资
select name,salary from emp where name like '%o%';
# 4.查询姓名由四个字符组成的员工姓名和薪资
select name,salary from emp where name like '____';
select name,salary from emp where char_length(name) =4;
# 5.查询id小于3或者大于6的数据
select * from emp where id not between 3 and 6;
# 6.查询薪资不在20000,18000,17000范围的数据
not in 不走索引
select * from emp where salary not in (20000,18000,17000);
# 7.查询岗位描述为空的员工名与岗位名 针对null不能用等号,只能用is
select name,post from emp where post_comment = NULL; # 查询为空!
select name,post from emp where post_comment is NULL;
select name,post from emp where post_comment is not NULL;
查询关键字之group by分组
分组
将单个单个的个体按照指定的条件分成一个个整体
"""
分组之后默认只能直接获取到分组的依据
其他字段无法再直接获取(可以间接获取)
"""
# 严格模式
set global sql_mode='STRICT_TRANS_TABLES,PAD_CHAR_TO_FULL_LENGTH,only_full_group_by'
# 1.每个部门的最高薪资
select post,max(salary) from emp group by post;
# 2.每个部门的最低薪资
select post,min(salary) from emp group by post;
# 3.每个部门的平均薪资
select post,avg(salary) from emp group by post;
# 4.每个部门的人数
select post,count(id) from emp group by post;
# 5.每个部门的月工资总和
select post,sum(salary) from emp group by post;
"""
可以给字段起别名(as还可以给表起别名)
select post as '部门',sum(salary) as '总和' from emp group by post;
"""
# 查询分组之后的部门名称和每个部门下所有的员工姓名
"""
group_concat() 获取分组以外的字段数据 并且支持拼接操作
select post,group_concat(name) from emp group by post;
select post,group_concat(name,':',salary) from emp group by post;
concat() 未分组之前使用的拼接功能
select concat(name,':',sex) from emp;
concat_ws()
select concat_ws(':',name,sex,salary,age) from emp;
"""
聚合函数
分组之后频繁需要使用的
max 最大值
min 最小值
sum 求和
count 计数
avg 平均值
分组注意事项
#关键字where和group by同时出现的时候group by必须在where的后面
where 先对整体数据进行过滤之后再分组操作
聚合函数只能在分组之后使用
select max(salary) from emp; #不分组 默认整体就是一组
统计各部门年龄在30岁以上的员工平均薪资
1.先求所欲年龄大于30岁的员工
select * from emp where age >30
2.再对结果进行分组
select * from emp where age >30 group by post;
select post.avg(salary) from emp where age >30 group by post;
3.查询每组性别的平均年龄
select gender,avg(age) from emp group by gender;
4.查询平均年龄超过30岁的性别,以及姓名 having avg(age)>30(重点)
# having是对每个组中的数据进行筛选和 group by联合使用
# where是对所有的数据进行筛选
select gender, group_concat(name) from emp group by gender having avg(age)>30
5.查询每种性别的平均年龄和名字
select gender, avg (age), group_ concat(name from emp group by gender:
6.查询每种性别中的人数多于2个的性别和姓名(重点)
select gender, group_concat(name)from emp group by gender having count(*)>2:
having分组之后的筛选条件
having的语法跟where是一致的
只不过having是在分组之后进行的过滤操作
即having是可以直接使用聚合函数的
统计各部门年龄在30岁以上的员工平均工资并且保留平均薪资大于10000的部门
select post,avg(salary) from emp
where age >30
group by post
having avg(salary) >1000
;
## select gender,group_concat(name) from students
group by gender
having avg(age)>30;
distinct去重
一定要注意 必须是'完全'一样的数据才可以去重
一定不要忽视主键 有主键存在的情况下是不可能去重的
ORM 对相关系映射
表 类
一条条的数据 对象
字段对应的值 对象的属性
select distinct id,age from emp;
order by排序
select * from emp order by salary;
select * from emp order by salary asc; #asc 可以不写 #默认升序
#对工资进行排序
# 降序
select * from emp order by salary desc;
#年龄降序 相同年龄以工资升序排列
select * from emp order by age desc,salary asc;
#统计各部门年龄在10岁以上的员工平均工资并且保留平均薪资大于1000的部门,然后对平均工资降序排序
select post.avg(salary) from emp
where age >10
group by post
having avg(salary) >1000
order by avg(salary) desc
;
limit限制展示条数
select * from emp;
针对数据过多的情况 我们通常进行分页处理
select * from emp limit 3; #只展示三条数据
select * from emp limit 0,5; #第一个参数是起始位置 第二个参数是展示条数
多表查询
1.子查询,一个SQL语句的结果作为另外一个SQL的条件
# 查询egon所在的部门
1) 查询egon所在部门的id
select dep_id from emp where name='egon';
2) 在拿着 dep_id取dep表中查询部门名称
select from dep where id =(select dep_id from emp where
name=egon)
2.连表查询
正则表达式
# 以j开头 以y结尾
select * from emp where name regexp '^j.*(n|y)$';
# mysql支持正则表达式,不会用就百度cv
表查询(内连接)
select * from dep,emp;#笛卡尔积
# 拼表
select * from dep,emp where emp.dep_id = dep.id;
inner join 内连接
#select 字段 from 表1 inner join 表2 表1.字段1 =表2.字段2
查询 有能够对应班级的学生以及班级信息:
select * from students inner join classes on students.cls_id = classes.id;
'''
注意:
内连接根据连接条件取出两个表‘交集’
on是连接条件 where是连接后筛选条件
'''
select * from emp inner join dep on emp.dep_id = dep.id;
连接查询(重点)
inner Join .. on
select.from表 A inner join表B;
select from students inner join classes:
#查询有能够对应班级的学生以及班级信息
select from students inner join classes on students. cls_id=classes. id;
#按照要求显示姓名、班级
select students. name, classes. name from students inner join classes on students. cls_ id=cLasses. id;
#给数据表起名字
select s name, C name from students as s inner join classes as c on s cls_id=c id;
#查询有能够对应班级的学生以及班级信息了显示学生的所有信息 students,*,只显示班级名称 classes,name
select students. * classes name from students inner join classes on students. cls id=classes. id;
#在以上的查询中,将班级姓名显示在第1列
select classes. name, students.* from students inner join classes on students. cls_id=classes. id;
#查询有能够对应班级的学生以及班级信息,按照班级进行排序
select C xxx S, xxX from students as s inner join classes as c on ., order by
表查询(外连接)
(left join) 左连接 以左表为基表,查询出左表所有数据,右表用NULL表示
# 主表 left join 从表 on 连接条件;
select * from emp left join dep on emp.dep_id=dep.id;
(right join) 右连接 以右表为基表,查询出右表所有数据,左表用NULL表示
# 从表 right join 主表 on 连接条件;
select * from emp right join dep on emp.dep_id=dep.id;
union 全连接
select * from emp left join dep on emp.dep_id=dep.id
union
select * from emp right join dep on emp.dep_id=dep.id;

浙公网安备 33010602011771号