赞
踩
如何将单机变成连网
将数据库保存部分全部统一起来
所有人操作数据都来一一个地方操作
本质其实就是一款基于网络通信的应用程序 那其实每个人都可以开发一款数据库软件 因为它仅仅就是一个基 于网络通信的应用程序 也就意味着数据库软件其实有很多很多 """ 关系型数据库 MySQL、oracle、 db2、 access. sq1 server 非关系型数据库 redis、mongodb. memcache """ # 关系型 1 数据之间彼此有关系或者约束 男生表和前女友表 2 存储数据的表现形式通常是以表格存储 name password hobby jason 123 read egon 123 女教练 tank 123 ssfda 每个字段还会有存储类型的限制 比如姓名只能存字符串... # 非关系型 存储数据通常都是以k,V键值对的形式
任何基于网络通信的应用程序底层用的都是socket
-服务端
-基于socket通信
-收发消息
-SQL语句
-客户端
-基于socket通信
-收发消息
-SQL语句
MySQL不单单支持MySQL自己的客户端app还支持其他编程语言来充当客户端操作
如何解决语言沟通的障碍?
# 1 让服务端兼容所有的语言(一个人精通多国语韵)
# 2 采用统一-的语言(SQL语句)
""" 库 --------------------- 文件夹 表 --------------------- 文件 记录 --------------------- 文件内一行行的数据 name password hobby jason 123 read egon 123 女教练 tank 123 ssfda 表头 表格的第一行字段 字段 name password hobby """
"""
在前期配置MySQL的时候cmd终端尽量以管理员的身份运行
windows+r输入cmd进 入的是普通用户终端有一些命令是无法执行的
搜索cmd右键 以管理员身份运行
"""
常见软件的默认端口号
MySQL 3306
redis 6379
mongodb 27017
django 8000
flask 5000
tomcat 8080
""" 1 MySQL 中的sq1语句是以分号作为结束的标志 2 基本命令 show databases; 查看所有的库名 3 连接服务端的命令可以简写 mysq1 -uroot -p 4 当你输入的命令不对 又不想让服务端执行并返回报错信息可以用\c取消 错误命令\c 5 客户端退出退 出命令加不加分号都可以执行 quit exit 6 当你在连接服务端的时候发现只输入mysq1也能连接 但是你不是管理员身份而只是一个游客模式 """
小知识点补充
1 如何查看当前具体进程
task1ist
tasklist |findstr mysqld
2 如何杀死具体进程(只有在管理员cmd窗口下才能成功)
taskkill \F \PID PID号
"""
每次启动mysq1d需要先切到对应的文件路径下才能操作太多紧琐
将mysqld所在的文件路径添加到系统环境变量中
"""
还是繁琐需要起两个cmd窗口不好
将mysq|服务端制作成系统服务(开机自启动)
"""
查看当前计算机的运行进程数
services . msc
将mysq1制作成系统服务
mysq1d --install
移除mysq1系统服务
mysq1d --remove
"""
mysqladmin -uroot -p 原密码password新密码
改命令直接在终端输入即可无序进入客户端
mysqladmin -uroot -p123 password 123456
你可以将mysq1获取用户名和密码校验的功能看成是一个装饰器 装饰在了客户端请求访问的功能上 我们如果将该装饰器移除那么mysq1服 务端就不会校验用户名和密码了 # 1先关闭当前mysq1服务端 命令行的方式启动(让mysql跳过用户名密码验证功能) mysq1d --skip -grant -tables # 2直接以无密码的方式连接 mysq1 -uroot -p 直接回车 # 3修改当前用户的密码 update mysq1.user set password=password(123456) where user='root' and host='locaThost' ; 真正存储用户表的密码字段存储的肯定是密文 只有用户自己知道明文是什么其他人都不知道这样更加的安全 密码比对也只能比对密文 # 4立刻将修改数据刷到硬盘 flush privileges; # 5关闭当前服务端然后以正常校验授权表的形式启动
my-defau1t. ini ini结尾的一般都是配置文件 程序启动会先加载配置文件中的配置之后才真正的启动 [mysq1d] #一旦服务端启动立刻加载下面的配置 sq1_ .mode=NO_ ENGINE_ SUBSTITUTION, STRICT. _TRANS_ TABLES [mysq1] #一旦客户端启动立刻加载下面的配置 [client] #其他客户端 #需要你自己新建一-个my.ini的配置 文件 #验证配置是否真的是自动加载 [mysq1] print('he11o world') #修改配置文件后-定要重启服务才能生效 #统一编码的配置无需掌握直接拷贝即可 #偷懒将管理员的用户名和密码也添加到配置文件中 [mysq1d] character-set-server=utf8 collation-server=utf8_ genera_ ci [client] default-char acter-set=utf8 [mysq1] user= "root password=123456 default-char acter-set=utf8
#增
create database db1;
create database db2 charset= 'gbk';
#查
show databases; # 查所有
show create database db1; #查单个
#改
alter database db2 charset='utf8' ;
#删
drop database db2;
""" 在操作表(文件)的时候需要指定所在的库(文件夹) """ #查看当前所在的库的名字 select database(); #切换库 use db1; #增 create tab1e t1(1d int,name char(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,pdfword,mp4…).
针对不同的数据应该有对应的不同的处理机制来存储
存储引擎就是不同的处理机制
#查看所有的存储引肇
show engines ;
#不同的存储引擎在存储表的时候异同点
create table t1(id int) engine=innodb;
create table t2(id int) engine=myisam ;
create tab1e t3(id int) engine=blackhole;
create table t4(id int) engine=memory;
#存数据
insert into t1 values(1) ;
insert into t2 values (1);
insert into t3 values (1);
insert into t4 values(1) ;
#语法 create table表名( 字段名1类型(宽度)约束条件, 宇段名2类型(宽度)约束条件, 字段名3类型(宽度)约束条件, ) # 注意 1 在同一张表中字段名不能重复 2 宽度和约束条件是可选的(可写可不写)而字段名和字段类型是必须的 约束条件写的话 也支持写多个 字段名1类型(宽度)约束条件1约束条件2.... create table t5(id); 报错 3 最后一行不能有逗号 create table t6( id int, name char , ); 报错 """ 补充 """ #寬度 一般情况 下指的是对存储数据的限制 create table t7(name char); 默认宽度是1 insert into t7 values('jason'); 针对不同的版本会出现不同的效果 5.6版本默认没有开启严格模式规定只能存一个字符你给了多个字符,那么我会自动帮你截取 5.7版本及以上或者开启了严格模式那么规定只能存几个就不能超,一旦超出范围立刻报错Data too long for .... """'格模式到底开不开呢? """ MySQL5.7之后的版本默认都是开启严格模式的使用数据库的准则: 能尽量少的让数据库干活就尽量少不要给数据库增加额外的压力 # 约束条件nu11 not nu11不能插入nu11 create table tB(id int,name char not nu11) ; """ 宽度和约束条件到底是什么关系 宽度是用来限制数据的存储 约束条件悬在宽度的基础之上增加的额外的约束 """
以TINYINT 是否有符号 默认情况下是带符号的 超出会如何 超出限制只存最大可接受值 create table t9(id tinyint); insert into t9 values (-129) ,(256) ; # 约束条件之unsigned 无符号 create tab1e t10(id tinyint unsigned); create table t11(id int); # int默认也是带符号的 #整型默认情况下都是带有符号的 #针对整型括号内的宽度到底是干嘛的 create table t12(id int(8)); insert into t2 values () """ 特例:只有整型括号里面的数字不是表示限制位数 id int(8) 如果数字没有超出8位那么默认用0填充至8位 如果数字超出了8位那么有几位就存几位(但是还是要遵守最大范围) """ create table t13(id int(8]个 unsigned zerofi11); #用0填充至8位 #总结: 针对整型字段括号内无需指定宽度因为它默认的宽度以及足够显示所有的数据了
# 如何查看严格模式 show variab1es 1ike "%mode"; 模糊匹配/查询 关键字 1ike %: 匹配任意多个字符 _ : 匹配任意单个字符 # 修改严格模式 set session 只在当前窗口有效 set g1obal 全局有效 set g1oba1 sq1_mode = ' STRICT TRANS_ TABLES' ; 修改完之后重新进入服务端即可
#存储限制 float(255,30) # 总共255位小数部分占30位 doub1e(255,30) # 总共255位小数部分占30位 decima7(65,30) # 总共65位小数部分占30位 #精确度验证 create table t15(id float(255,30)); create table t16(id doub1e(255 ,30)); create table t17(id decima1(65,30)); """ 前期不要用反向键 所有的命令全部手敲! ↑ !增加熟练度 """ insert into t15 values(1.111111111111111111111111111); insert into t16 values(1.111111111111111111111111111); insert into t17 values(1.111111111111111111111111111); float < double < decimal # 要结合实际应用场景三者都能使用
""" char 定长 char(4)数据超过四个字符直接报错 不够四个字符空格补全 varchar 变长 varchar(4) 数据超过四个字符直接报错不够有几个存几个 """ create table t18(name char[4)); create table t19(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; """ 首先可以肯定的是char硬 盘上存的绝对是真正的数据带有空格的 但是在显示的时候MySQL会自动将对于的空格剔除 """ # 再次修改sq1_ mode让MySQL 不要做自动剔除操作 set g1oba1 sq1. _mode = 'STRICT_ TRANS_ TABLES,PAD_ .CHAR_ _TO_ FULL_ LENGTH ';
char 缺点: 浪费空间 优点: 存取都很简单 直接按照固定的字符存取数据即可 jason egon alex wusir tank 存按照五个字符存取也直接按照五个字符取 varchar 优点:节省空间 缺点:存取较为麻烦 1bytes+jason 1bytes+egon 1bytes+alex 1bytes+tank 存的时候需要制作报头 取的时候也需要先读取报头之后才能读取真实数据 以前基本上都是用的char其实现在用varchar的也挺多 补充: 进来公司之后你完全不需要考虑字段类型和字段名 因为产品经理给你发的邮件.上已经全部指明了
分类
date:年月日2020-5-4
datetime:年月日时分秒2020-5-4 11:11:11
time:时分秒11:11:11
Year:2020
create tab1e student (
id int,
name varchar(16) ,
born_ year year ,
birth date,
study_ .time time,
reg_ time datetime
);
insert into student values (1,'egon', 1880',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', 'xXXX00o'); 报错 #枚举字段 后期在存数据的时候只能从枚举里面选择一个存储 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(2,'egon', 'female','DBJ ,heha ') : 正常 insert into teacher values(3,'tank', 'others','生蚝'); 报错 # 集合可以只写一一个 但是不能写没有列举的
#补充知识点 插入数据的时候可以指定字段 create table tl( id int, name char(16) ); insert into t1(name,id) values('jason' ,1); create tab1e t2( id int, name char(16), gender enum('male', 'female',. others') default 'male ' ) insert into t2(id,name) values(1, 'jason'); insert into t2 values(2,'egon', 'female');
#单列唯一 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 tab1e t4( id intp ip char(16), port int, ) insert into t4 values(1, '127.0.0.1' ,8080) ; insert into t4 values(2, '127 .0.0.1' ,8081); insert into t4 values(3, '127 .0.0.2' ,8080); insert into t4 values(4, 127 .0.0.1',8080) ;
""" 单单从约束效果上来看primary key 等价于 not nu11 + unique 非空且唯一!!!! """ create table t5(id int primary key) ; insert into t5 values (nu11);报错 insert into t5 values (1), (1);报错 insert into t5 values (1),(2); 2. 它除了有约束效果之外 它还是Innodb存储引擎组织数据的依据 Innodb存储引擎在创建表的时候必须要有primary key 因为它类似于书的目录能够帮助提示查询效率并且也是建表的依据 # 1 一张表中有且只有一个主键如果你没有设置主键那么会从上往下搜索直到遇到一个非空且唯一的字段将它自动升级为主键 create table t6( id int, name char(16), age int not nu11 unique, addr char(32) not nu11 unique ); # 2 如果表中没有主键也没有其他任何的非空且唯一 字段那么Innodb会采用自己内部提供的一个隐藏字段作为主键,隐藏意味着你无法使用到它就无法提示查询速度 #联合主键(多个字段联合起来作为表的主键本质还是:一个主键) create table t7( ip char(16), port int , primary key(ip,port) ); """ 也意味着以后我们在创建表的时候1d字段一定要 primary key """
#当编号特别多的时候人为的去维护太麻烦
create tab1e t8(
id int primary key auto increment,
name char (16)
);
insert into t8(name) values('jason'),('egon'),('kevin');
"""
以后在创建表的id(数据的唯一标识id、 uid、sid)字段的时候
id int primary key auto_ _increment
"""
delete from在删除表中数据的时候主键的自增不会停止
truncate t1 清空表数据并且重置主键
定义一张员工表表中有很多字段
id name gender dep_name dep_desc
# 1该表的组织结构不是很清晰(可忽视)
# 2浪费硬盘空间(可忽视)
# 3数据的扩展性极差(无法忽视的)
#如何优化?
"""上述问题就类似于你将所有的代码都写在了- -个py文件中"""
将员工表拆分 员工表 和 部门表
"""
外键就是用来帮助我们建立表与表之间关系的
foreign key
"""
"""
表与表之间最多只有四种关系
一对多关系
多对多关系
一对-关系
没有关系
"""
""" 判断表与表之间关系的时候前期不熟悉的情况下- 。定要按照我给你的建议 换位思考 分别站在两张表的角度考虑 员工表与部门表为例 先站在员工表 思考一个员工能否对应多个部门(- -条员工数据能否对应多条部门数据) 不能! ! ! (不能直接得出结论一定 要两张表都考虑完全) 再站在部门表 思考一个部门能否对应多个员工(-一个部门数据能否对应多条员工数据) 能! ! ! 得出结论 员工表与部门表示单向的一对多 所以表关系就是一对多 """ foreign key 1. 一对多表关系 外键字段建在多的一-方 2. 在创建表的时候一 -定要先建被关联表 # SQL语句建立表关系 create table dep( id int primary key auto_ _incr ement, dep_ name char(16) , dep_ _desc char(32) ); create table emp( id int primary key auto_ .1ncrement, name char (16), gender enum( 'male','female' , 'others') default 'male' , dep_ id int, foreign key(dep. _id) references dep(id) ) insert into dep(dep_ name ,dep_ _desc) values('sb教学部', '教书育 人'),('外交部’,'多人外交'),('nb技术部”,'技术能力有限部门'); insert into emp (name,dep. _id) values('jason' ,2),(' egon',1), ('tank' ,1),('kevin',3); #修改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') defau1t' 'male' , dep_ _id int, foreign key(dep_ _id) references dep(id) on update cascade #同步更新 on delete cascade #同步删除 ); insert into dep(dep_ name,dep. _desc) values('sb教学部','教书育 人'),('外交部','多人外交'),('nb技术部','技术能力有限部门'); insert into emp(name ,dep_ _id) values(' jason' ,2),('egon',1), ('tank' ,1),( 'kevin',3);
""" 图书表和作者表 """ create table book ( id int primary key auto_ increment, title varchar(32), price int, author. _1d int, foreign key(author_ .id) references author(id) on update cascade #同步更新 on delete cascade #同步删除 ); create tab1e author( id int primary key auto. _increment, name varchar(32) , age int , book. _id int, foreign key(book. _id) references book(id) on update cas cade # 同步更新 on delete cascade # 同步删除 ); """ 按照上述的方式创建一 一个都别想成功! ! ! 其实我们只是想记录书籍和作者的关系 针对多对多字段表关系不能在两张原有的表中创建外键 需要你单独再开设张专门用 来存储两张表数据之间的关系 """ create table book( id int primary key auto_ .increment, title varchar(32) , price int, ); create tab1e author( id int primary key auto _increment, name varchar(32) , age int , ); create table book 2author ( id int primary key auto_ _increment, author. _id int , book_ _id int, foreign key(author. _1d) references author(id) on update cascade # 同步更新 on delete cascade, #同步删除 foreign key(book_ :id) references book(i d) on update cascade # 同步更新 on delete cascade #同步删除 )
id name age addr phone hobby email........ 如果一个表的字段特别多每次查询又不是所有的字段都能用得到 将表一分为二 用户表 用户表 id namyl age 用户详情表 id addr phone hobby email. ....... 站在用户表 一个用户能否对应多个用户详情 不能 站在详情表 一个详情能否属于多个用户 不能 结论:单向的一对多都不成立那么这个时候两者之间的表关系 就是一对一 或者没有关系(好判断) 客户表和学生表 在你们报名之前你们是客户端 报名之后是学生(期间有一些客户不会报名) 一对一外键字段建在任意-方都可以但是推荐你建在查询频率比较高的表中 create table authordetail( id int primary key auto. _increment, phone int, addr varchar (64) ); create tab1e 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 旧字段名 新字段名 字段类型(宽度) 约束条件;
"""
我们sq1语句查询的结果其实也是一-张虚拟表
"""
create table 表名 select * from 旧表; 不能复制主键外键...
create table new_ ,dep2 select *from dep where id>3;
""" select where group by having distinct order by limit regexp 1ike ........ """ #当表字段特别多展示的时候错乱可以使用G分行展示 select * from emp\G; #个别同学的电脑在插入中文的时候还是会出现乱码或者空白的现象你可以将字符编码统一设置成GBK
# 书写顺序 select id,name from emp where id > 3; #执行顺序 from where select 。。。。 """ 虽然执行顺序和书写顺序不一致你在写sq1 语句的时候可能不知道怎么写 你就按照5写顺序的方式写sql """ 虽然执行顺序和书写顺序不一-致你在写sq1 语句的时候可能不知道怎么写 你就按照书写顺序的方式写sq1 select * 先用 * 号占位 之后去补全后而的sq1语句 最后将 * 号替换后你想要的具体字段
#作用:是对整体数据的一个筛选操作 # 1.查询id大于等于3小于等于6的数据 se1ect id,name,age from emp where id>=3 and id<=6; select id,name 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) ; # 3.查询员工姓名中包含字母o的员工的姓名和薪资 模糊查询 1ike % 匹配任意多个字符 _ 匹配任意单个字符 select name,salary from emp where name llke '%0%' ; # 4.查询员工姓名是由四个字符组成的姓名和薪资char_1ength() select name,salary from emp where name like '----' select name,salary from emp where char_length(name) = 4; # 5.查询id小于3或者id大于6的数据 se1ect * from emp where id not between 3 and 6; # 6.查询薪资不在20000,18000 ,17000范围的数据 select * from emp where salary not in (20000 , 18000 ,17000) ; # 7.查询岗位描述为空的员工姓名和岗位名 针对nu11不用等号 用is select name,post from emp where post_ comment = NULL ; select name, post from emp where post_ comment is NULL ;
# 分组实际应用场景 分组应用场景非常的多 男女比例 部门平均薪资 部门秃头率 国家之间数据统计 # 1 按照部门分组 select * from emp group by post; """ 分组之后最小可操作单位应该是组 不再是组内的单个数据 上述命令在你没有设置严格模式的时候是可正常执行的返回的是分组之后每个组的 第一条数据但是这不符合分组的规范:分组之后不应该考虑单个数据而应该以组为操作 单位(分组之后没办法直接获取组内单个数据) 如果设置了严格模式那么上述命令会直接报错 """ set global sq1_ mode = 'strict_ trans_ _tables,only_fu11_ group _by' ; 设置严格模式之后分组 默认只能拿到分组的依据 select post from emp group by post; 按照什么分组就只能拿到分组 其他字段不能直接获取需要借助于一些方法 """ 什么时候需要分组啊? ? ? 关键字 每个 平均 最高 最低 """ # 1.获取每个部[ ]的最高薪资 select post, max(salary) from emp group by post; select post as ' 部门' , max(salary) as '最高薪资’ from emp group by post; select post‘部门' , max(salary) '最高薪资' from emp group by post; # as可以给字段起别名也可以直接省略不写但是不推荐因为省略的话语意不明确容易错乱 # 2. 获取每个部[]的最薪资 select post,min(salary) from emp group by post; # 3.获取每个部门的平均薪资 select post, avg(salary) from emp group by post; # 4.获取每个部门的工资总和 select post,sum(salary) from emp group by post; # 5.获取每个部门的人数 select post,count(id) from emp group by post; select post, count(salary) from emp group by post; select post, count(age) from emp group by post; select post, count(post_ comment) from emp group by post; nu11不行 # 6.查询分组之后的部门名称和每个部门下所有的员工姓名 # group_ .concat 不单单可以支持你获取分组之后的其他字段值还支持拼接操作 select post, group_ concat(name) from emp group by post; select post, group_ concat(name, '_DSB') from emp group by post ; select post, group_ concat(name,' :' ,salary) from emp group by post; # concat不分组的时候用 select concat ('NAME', name), concat ('SAL:', salary) from emp; # 补充as语法不单单可以给字段起别名还可以给表起别名 select emp. id, emp.name from emp ; select emp.id, emp.name from emp as t1 ; # 报错 select t1.id, t1.name from emp as t1; #查询每个人的年薪 12薪 select name, salary*12 from emp;
# 关键宁where 和group by 同时出现的时候group by 必须在 where 的后面
where先对整体数据进行过滤之后再分组操作
where筛选条件不能使用聚合函数
select id,name,age from emp where max(salary) > 3000;
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;
"""
having的语法是where是一致的
只不过having是在分组之后进行的过滤操作
即having是可以直接使用聚合函数的
"""
# 统计各部门年龄在30岁以上的员工平均工资并且保留平均薪资大于10000的部门
select post,avg(salary) from emp
where age>30
group by post
having avg(salary) > 10000
一定要注意必须是完全- 一样的数据才可以去重 一定不要将逐渐忽视了 有逐渐存在的情况下是不可能去重的 {'id':1,' name': 'jason', 'age' :18}, {'id':2,'name': 'jason', 'age' :18}, {'id' :3,'name' : 'egon' , 'age' :18} ORM 对象关系映射 让不懂SQL语句的人也能够非常牛逼的操作数据库 表 类 条条的数据 对象 字段对应的值 对象的属性 你再写类就意味着在创建表 用类生成对象就意味着再创建数据 对象点属性就是在获取数据字段对应的值 目的就是减轻python程序员的压力 只需要会python面向对象的知识点就可以操作MySQL select distinct id,age from emp; select distinct age from emp ;
select * from emp order by salary; select * from emp order by salary asc; select * from emp order by salary desc; """ order by默认是升序 asc该asc可以省略不写 也可以修改为降序 desc """ select * from emp order by age desc,salary asc; # 先按照age降序排如果 碰到age相同则再按照salary升序排 # 统计各部门年龄在10岁以上的员工平均工资并且保留平均薪资大于1000的部门,然后对平均工资降序排序 select post , avg(salary) from emp where age>10 group by post having avg(salary) > 1000 order by avg(salary) desc ;
select * from emp;
"""针对数据过多的情况我们通常都是做分页处理"""
select * from emp 1imit 3; # 只展示三条数据
select * from emp 1imit 0,5;
select * from emp 1imit 5,5;
第一个参数是起始位置
第二个参数是展示条数
select * from emp where name regexp '^j.*(n|y)$';
MySQL也知道你在后而查询数据过程中肯定会经常用到拼表操作 所以特地给你开设了对应的方法 inner join 内连接 1eft join 左连接 right join 右连接 uni on 全连接 select * from emp inner join dep on emp.dep_id = dep.id; # 只拼接两张表中公有的数据部分 select * from emp left join dep on emp.dep. _1d = dep, id; # 左表所有的数据都展示出来没有对应的项就用NULL select白from emp right join dep on emp.dep- _id = dep.id; #右表所有的数据都展示出来没有对应的项就用NULL # union 全连接 左右两表所有的数据都展示出来
子查询就是我们平时解决问题的思路 分步骤解决问题 第一步 第二步 ........... 将一个查询语句的结果当做另外一个 查询语句的条件去用 #查询部门是技术或者人力资源的员工信息 1先获取部门的id号 2再去员工表里面筛选出对应的员工 select id from dep where name='技术’ or name = '人力资源'; select name from emp where dep. _id in (200 , 201); select * from emp where dep_ id in (select id from dep where name='技术’or name ='人力资源'); 表的查询结果可以作为其他表的查询条件 也可以通过起别名的方式把它作为一个张虚拟表根其他表关联 """ 多表查询就两种方式 先拼接表再查询 子查询一步一步来 """
# 查询平均年龄在25岁以上的部门名称 """ 只要是多表查询就有两种思路 联表 子查询 """ # 联表操作 1 先拿到部门和员工表拼接之后的结果 2 分析语义得出需要进行分组 select dep.name from emp inner join dep on empIdep_id = dep.id group by dep.name having avg(age) > 25 """涉及到多表操作的时候一定 要加上表的前缀""" #子查询 select name from dep where id in (select dep. _1d_ from emp group by dep. _1d having avg(age) > 25); # 关键字exists(了解) 只返回布尔值True False 返回True的时候外层查询语句执行 返回False的时候外层查询语句不再执行 select台from emp where exists (select id from dep where id>3); select from emp where exists (select id from dep where id>300) ;
""" 支持python代码操作数据库MySQL """ 利用一些语法的特性书写一些特点的语句实现固定的语法 MySQL利用的是MySQL的注释语法 conn = pymysql. connect ( host. =’ 127. 0.0.1’, port = 3306, user = 'root', password ='123456' database ='day48' charset = 'utf8' #编码千万不要加 - ) # 链接数据库 cursor = conn. cursor () #产生一个游标对象 (就是用来帮你执行命令的) """ cursor = conn. cursor (cursor =pymysq1. cursors .DictCursor) pymysq1. cursors .DictCursor 将查询结果以字典的形式返回 """ sql = select * from teacher ; res = cursor. execute (sql) #print(res) #execute返回的是你当前sql语句所影响的行数 该返回值一般不用 #获取命令执行的查询结果 print (cursor. fetchone () ) #只拿一条 # print (cursor. fetchall() # 拿所有 # print (cursor. fetchmany(2)) #可以指定拿几条 print (cursor. fetchone()) # 读取数据类似于文件光标的移动 # cursor. scroll(1,' relative')# 相对于光标所在的位置继续往后移动1位 cursor. scroll(1.' absolute' )# 相对于数据的开头往后继续移动1位
conn = pymysql. connect ( host. =’ 127. 0.0.1’, port = 3306, user = 'root', password ='123456' database ='day48' charset = 'utf8' #编码千万不要加 - ) # 链接数据库 # 敏感的数据不要自己做拼接 cursor = conn. cursor () #产生一个游标对象 (就是用来帮你执行命令的) cursor = conn. cursor (cursor =pymysq1. cursors .DictCursor) username = input('>>>:') password = input('>>>:') sq1 = "select * from user where name= %s and password=%s" #不要手动拼接数据先用%s占位之后将需要拼接的数据直接交给 execute方法即可 print(sq1) rows = cursor. execute (sql, (username, password)) # #自动识别sql里面的%s用后面元组里面的数据替换 识别sq1里面的%s用后面元组里面的数据替换 if rows : print('登录成功') print (cursor. fetcha11()) else: print('用户名密码错误')
# 1.针对增删改 pymysq1需要二次确认才能真正的操作数据 import pymysq1 conn = pymysql. connect ( host. =’ 127. 0.0.1’, port = 3306, user = 'root', password ='123456' database ='day48' charset = 'utf8' #编码千万不要加 - ) # 链接数据库 #产生一个游标对象 (就是用来帮你执行命令的) cursor = conn. cursor (pymysq1. cursors .DictCursor) #增 sq1 = 'insert into user (name,password) values (%S ,%s) ' # rows = cursor. execute (sq1,('jackson',123)) rows = cursor . executemany(sq1,[(' xx' ,123),('ooo' ,123),('yyy',123)]) print(rows ) # conn.commit() # 确认 #修改 # sq1 = 'update user set name="jasonNB" where id=1' # rows = cursor. execute(sq1) # print(rows) # conn.commit() # 确认 #删除 sq1 = 'delete from user where id=7 ' rows = cursor .execute(sq1) print (rows) conn .commit () #确认 #查 # sq1 ='select出from user # cursor .execute(sq1) # print (cursor .fetcha11()) """ 增删改查中 删改增它们的操作 设计到数据的修改 需要二次确认 """ #还可以一-次性插入N多条数据 rows = cursor . executemany(sq1,[(' xx' ,123),('ooo' ,123),('yyy',123)])
"""
开启一 一个事务可以包含多条sq]语句这些sq1语句要么同时成功
要么一个都别想成功称之为事务的原子性
"""
"""
保证了对数据操作的安全性
"""
eg:还钱的例子
egon用银行卡给我的支付宝转账1000
1将egon 银行卡账户的数据减1000块
2将jason支付宝账户的数据加1000块
你在操作多条数据的时候可能会出现某几条操作不成功的情况
ACID A:原子性 一个事务是一个不可分割的单位,事务中包含的诸多操作 要么同时成功要么同时失败 C:一致性 事务必须是使数据库从一个一致性的状态变到另外:一个一致性的状态 一致性跟原子性 是密切相关的 I:隔离性 一个事务的执行不能被其他事务干扰 (即一个事务内部的操作及使用到的数据对并发的其他事务是隔离的,并发执行的事务之间也是互相不干扰的) D:持久性 也叫"永久性” 一个事务一旦提交成功执行成功那么它对数据库中数据的修改应该是永久的 接下来的其他操作或者故障不应该对其有任何的影响
# 事务相关的关键字 # 1开启事务 start t ransaction ; # 2回滚(回到事务执行之前的状态) ro11back; # 3确认(确认之后就无法回滚了) commit: """ 模拟转账功能 """ create table user( id int primary key auta _increment, name char(16) , balance int ); insert into user (name,balance) values ('jason' ,1000) , ('egon' ,1000), ('tank' ,1000) ; #1先开启事务 start trans action ; # 2多条sq1语句 update user set balance=900 where name= jason ' ; update user set balance=1010 where name= ' egon ' ; update user set balance=1090 where name='tank' ; """ 总结 当你想让多条sq]语句保持- -致性要么同时成功要么同时失败 你就应该考虑使用事务 """
r .execute(sq1)
“”"
增删改查中
删改增它们的操作 设计到数据的修改
需要二次确认
“”"
#还可以一-次性插入N多条数据
rows = cursor . executemany(sq1,[(’ xx’ ,123),(‘ooo’ ,123),(‘yyy’,123)])
### 事务
- 什么是事务
```python
"""
开启一 一个事务可以包含多条sq]语句这些sq1语句要么同时成功
要么一个都别想成功称之为事务的原子性
"""
"""
保证了对数据操作的安全性
"""
eg:还钱的例子
egon用银行卡给我的支付宝转账1000
1将egon 银行卡账户的数据减1000块
2将jason支付宝账户的数据加1000块
你在操作多条数据的时候可能会出现某几条操作不成功的情况
ACID A:原子性 一个事务是一个不可分割的单位,事务中包含的诸多操作 要么同时成功要么同时失败 C:一致性 事务必须是使数据库从一个一致性的状态变到另外:一个一致性的状态 一致性跟原子性 是密切相关的 I:隔离性 一个事务的执行不能被其他事务干扰 (即一个事务内部的操作及使用到的数据对并发的其他事务是隔离的,并发执行的事务之间也是互相不干扰的) D:持久性 也叫"永久性” 一个事务一旦提交成功执行成功那么它对数据库中数据的修改应该是永久的 接下来的其他操作或者故障不应该对其有任何的影响
# 事务相关的关键字 # 1开启事务 start t ransaction ; # 2回滚(回到事务执行之前的状态) ro11back; # 3确认(确认之后就无法回滚了) commit: """ 模拟转账功能 """ create table user( id int primary key auta _increment, name char(16) , balance int ); insert into user (name,balance) values ('jason' ,1000) , ('egon' ,1000), ('tank' ,1000) ; #1先开启事务 start trans action ; # 2多条sq1语句 update user set balance=900 where name= jason ' ; update user set balance=1010 where name= ' egon ' ; update user set balance=1090 where name='tank' ; """ 总结 当你想让多条sq]语句保持- -致性要么同时成功要么同时失败 你就应该考虑使用事务 """
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。