Python学习笔记 第十二章 mysql

Python学习笔记 第十二章 mysql

1.初识数据库

image-20210414104045208

通常为了高可用,还会备份大量的数据到备用数据库,当运行的数据库死掉以后能够接替原来的数据库python

  • 数据库的优点mysql

    • 程序稳定性,这样任意一台服务器崩溃了,都不会影响数据和另外的服务
    • 数据一致性:全部的数据都存储在一块儿,全部的程序操做的数据都是统一的,就不会出现数据不一致的现象
    • 并发:数据库能够良好的支持并发,全部程序操做数据库都是经过网络,而数据库自己支持并发的网络操做,不用本身写sicket
    • 效率:使用数据库对数据进行增删改查的效率要高出咱们本身处理文件不少
  • 什么是数据linux

    • 描述事物的符号记录称之为数据,能够是数字、文字、图片、图像、声音、语言等
    • 在计算机中描述一个事物,须要抽取这事物的典型特征,组成一条记录,至关于文件的每一行
  • 什么是数据库面试

    • 数据库即存放数据的仓库,只不过这个仓库是计算机存储设备上,并且数据是按必定的格式存放的
    • 数据库是长期存放在计算机内、有组织、可共享的数据集合
    • 数据库中的数据按必定的数据模型组织、描述和储存,具备较小的冗余度、较高的数据独立性和以扩展性,并可为各类用户共享
  • 什么是数据库管理系统(DataBase Management System)简称DBMSredis

    • 如何科学地组织和存储数据,如何高效获取和维护数据成了关键
    • 这用到一个系统软件-数据库管理系统:MySQL\Oracle\SQLite]Access\MS SQL Server
    • mysql主要用于大型门户,如搜狗、新浪,开源(甲骨文)
    • oracle用于银行、铁路、飞机场,费用高(甲骨文)
    • sql server,微软公司的产品,主要应用于大中型企业,如联想、方正
    • 数据库管理员(DBA)
  • 概念sql

    • 表:文件 ,存放多行内容、记录
    • 数据库:文件夹,用来组织文件、表
    • 数据库管理系统:软件,如mysql,管理数据库
    • 数据库服务器:一台计算机(对内存要求较高),运行数据库管理软件
  • 数据库的分类mongodb

    • 相对快
    • key-value来存储的,没有表结构
    • {'apple':[名字 年龄 电话号码 地址]} 只能根据apple查询,而不能经过电话号码查询
    • 通常用于如:快递 用快递单号查询
    • 视频 电影的id:电影的内容/电影的地址
    • 相对慢
    • 须要表结构
    • sql语句通用
    • 关系型:sqllite\db2\oracle\access\sql server\mysql
    • 非关系型:mongodb\redis\memcache
  • mysql数据库

    • 是一个关系型数据库,关系数据库将数据存放在不一样的表中,而不是将全部的数据存放在一个大仓库内,增长速度和灵活性

2.安装数据库

https://downloads.mysql.com/archives/community/windows

image-20210414113732405

下载以后点击安装包进行安装安全

image-20210414113754664

image-20210414113842436

image-20210414113949799

image-20210414114015927

image-20210414113914824

环境变量的配置:

在任何目录下都能找到对应的文件

才能在任意位置输入命令启动该应用

windows下

mysql install 安装mysql服务 mysql服务就被注册到操做系统中

net start mysql 启动mysql

net stop mysql 关闭mysql

启动客户端链接server

mysql -u root -p

输入密码

或者 mysql -uroot -p123456

mysql -uroot -p123456

3.操做数据

mysql帐号操做

#进入mysql客户端
$mysql
mysql> select user();  #查看当前用户
mysql> exit     # 也能够用\q quit退出

# 默认用户登录以后并无实际操做的权限
# 须要使用管理员root用户登录
$ mysql -uroot -p   # mysql5.6默认是没有密码的
#遇到password直接按回车键
mysql> set password = password('root'); # 给当前数据库设置密码

# 建立帐号
# create user '用户名'@'主机ip/主机域名' identified by '密码';
mysql> create user 'wrr'@'192.168.10.%'   IDENTIFIED BY '123';# 指示网段
mysql> create user 'wrr'@'192.168.10.5'   # 指示某机器能够链接
mysql> create user 'wrr'@'%'                    #指示全部机器均可以链接  
mysql> show grants for 'wrr'@'192.168.10.5';查看某个用户的权限 
# 远程登录
$ mysql -uroot -p123 -h 192.168.10.3

# 给帐号受权
#grant select on 数据库名.* to '用户名'@'主机的ip/主机域名'
mysql> grant all on *.* to 'wrr'@'%';
#grant 权限类型
#grant all 给全部的权限
#grant select,insert 给查询和插入的权限
mysql> flush privileges;    # 刷新使受权当即生效

# 建立帐号并受权
mysql> grant all on *.* to 'wrr'@'%' identified by '123'
  • 基本操做
    • show databases; 查看全部数据库
    • create database 数据库名; 建立一个数据库
    • use 数据库; 切换到数据库下
    • show tables; 查看这个库下有多少表
    • drop database 数据库名;删除数据库
  • 操做表
    • 能看到多少个字段、类型,可是看不到编码,引擎,具体的约束信息只能看到一部分
    • 能查字段、类型、长度、编码、引擎、约束
    • 字段名 类型[(宽度) 约束条件]
    • create table 表名(name char(20), age int); 建立一张表
    • show create table 表名;
    • desc student; describe 表名; 查看表结构
    • drop table 表名; 删除表
  • 操做数据
    • delete from 表; 是不会清空自增字段的offset(偏移量)值
    • truncate table 表; 会清空表和自增字段的偏移量
    • 写入数据的方式
    • insert into 表 values (值1,值2, 值3) 这张表有多少的字段就须要按照字段的顺序写入多少个值
    • insert into 表 values (值1,值2,值3),(值1,值2,值3)一次性写入多条数据
    • insert into 表 (字段1,字段2) values (值1,值2) 制定字段名写入,能够任意选择表中你须要写入的字段进行写入
    • 插入数据:insert into student values('apple', 18);
    • 查询数据: select * from student;
    • 修改数据:update student set age=20 where name='apple'; 注意修改的须要加上where
    • 删除数据:delete from student where name='apple';

4.SQL语句

SQL语言主要用于存取数据、查询数据、更新数据和管理关系数据库系统,SQL语言由IBM开发。SQL语言分为3种类型:

  一、DDL语句 数据库定义语言(defined): 数据库、表、视图、索引、存储过程,例如CREATE DROP ALTER

  二、DML语句 数据库操纵语言(manager): 插入数据INSERT、删除数据DELETE、更新数据UPDATE、查询数据SELECT

  三、DCL语句 数据库控制语言(control): 例如控制用户的访问权限GRANT、REVOKE

5.存储引擎- 存储数据的方式

show engines; 查看支持的存储引擎

image-20210414151358374

show variables like '%engin%'; 查看默认的引擎

image-20210414154412699

Support:mysql是否支持这种存储引擎

mysql5.6 默认为Innodb存储引擎

Myisam 在mysql5.5以前默认的存储引擎 表锁

操做数据的代码-》 存储引擎 - 〉数据

(1)数据存储在硬盘上

数据和索引存储在一块儿 2个文件  Innodb存储引擎 数据持久化

  • 数据索引一个文件

  • 表结构一个文件

  • Transactions:事务,保持数据安全

    Supports transactions:支持事务,保证数据的完整性,将多个操做变成原子性操做

    开启事务-》 执行原子性操做-〉提交事务

    row-level locking:行级锁:修改的行少的时候使用,修改数据频繁的时候

    表级锁:批量修改多行,对于大量数据的同时修改

    foreign keys:外键,约束两张表中的关联字段不能随意的添加、删除,下降数据增删改的出错率

    学生表中能够添加学生的姓名和年龄,再设置一个id 一、2

    在班级表里设置id 一、2分别表示一班和二班,显示对应的班级人数

    可是想要在学生表中id能够设置为3,若是想要学生表的id根据班级表存在的id进行设置,那么可给id加上外键,当id设置为3会报错

    而且当学生表中有设置id为2的,那么班级表中的二班不能删除

数据和索引不须要存储在一块儿 3个文件 Myisam存储引擎 数据持久化

  • 数据
  • 表的结构
  • 索引(查询的时候使用的一个目录结构)
  • 只支持表锁

(2)数据存在内存中,也就是说断电数据消失 1个文件 Memory 存储引擎

  • 表结构

  • MEMORY:Hash based基于哈希的,存储在内存中,useful for temporary tables对临时表很是有用

通常像首页的热点新闻就会存储在memory中,查找不到再到大表中查找

面试题:

你了解mysql存储引擎吗?

你的项目用了什么存储引擎?

  • innodb
  • 多个用户操做的过程当中对同一张表的数据同时作修改
  • innodb支持行级锁,因此咱们是用来这个存储引擎
  • 为了适应程序将来的扩展性,扩展新功能的时候可能会用到...涉及到要维护数据的完整性
  • 项目中有一两张xx表,之间的外键关系是什么,一张表的修改或者删除比较频繁,怕出错因此作了外键约束

6.mysql数据类型

  • 数字 和 bool

    • 最多表示10位数
    • 默认是有符号的
    • 无符号 unsigned 0, + 若是填入负数会显示warning 并查看的时候显示为可表示范围的最小值如0
    • tinyint 一个字节 有符号数范围 -128,127
    • int 四个字节 有符号数范围 -2147483648,2147483647 超过最大的位数显示的仍是2147483647 不约束长度
    • float 四个字节 float(5,2) 123.32 前面表示一共多少位,后面表示小数点位数 会四舍五入
    • double 八个字节 同float 表示的范围更广
    • decimal 默认为decimal(10, 0) 十位整数 依赖于前面和后面的值
  • 字符串

    • 变长存储,节省空间,存取速度慢
    • 'apple' 'apple5'
    • 定长存储,浪费空间,节省时间
    • 'apple' 'apple .......'
    • char  0-255字节 经常使用于身份证号、手机号、qq号(12位的qq更多)、username(12-18)、password(10-16)

    • varchar 0-65535字节 经常使用于评论、朋友圈、微博

      image-20210414165233853

  • 时间

    • 若是像datetime也实现相似的功能,能够利用show create table 表名 查看timestamp的字段后面的内容
    • 在新建datetime数据类型的时候也加上一样的内容便可
    • create table t5(id int, dt datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
    • datetime 八个字节20210415121900 表示范围1000-01-01 00:00:00/9999-12-31 23:59:59

    • year 一个字节 1901/2155

    • date 三个字节 20210415 表示范围1000-01-01/9999-12-31

    • time 三个字节 121900 表示范围 '-838:59:59'/'838:59:59'

    • timestamp 四个字节 1970-01-01 00:00:00/2038 默认值为当前时间戳 不能为空 更新其余数据的时候自动按照当前的时间戳更新最新的时间戳,像登录的时候,能够记录最后一次登录的时间

      image-20210414164226282

  • enum/set

    按照必定的范围选择

    • hobby set('抽烟', '喝酒', '烫头'); 爱好能够多选
    • gender enum('male', 'female');  性别能够设置为单选
    • enum 单选行为
    • set 多选行为

7.完整性约束

无符号的:只和数字有关 unsigned

不能为空 not null

默认值 default

不能重复 unique 值不能重复,null能够写入多个 第一个被定义为非空+惟一的那一列会成为这张表的primary key

联合惟一 unique

create table t14(
	id int,
  server_name char(12),
  ip char(15),
  port char(5),
  unique(ip, port)
);

自增 auto_increment 只能对数字有效,自带非空约束,至少是unique的约束以后才能使用auto_increment

create table t16(
	id int primary key auto_increment,
	name char(12)
)

主键:非空+惟一约束 = 主键 primary key 一张表只能定义一个主键 若是不指定主键 默认是第一个非空+惟一

联合主键 primary key( )

create table t17(
	id int,
  server_name char(12),
  ip char(15),
  port char(5),
  primary key(ip, port)
);

外键: foreign key (本身的字段) references 外表(外表字段)

外表字段必须至少是惟一的

学生表

create table student(
	id int primary key auto_increment,
  name char(12) not null,
  gender enum('male', 'female') default 'male',
  class_id int,
  foreign key(class_id) references class_t(cid)
);

班级表

create table class_t(
	cid int primary key auto_increment,
  cname char(12) not null,
  startd date
);

须要先创建班级表,而且写入数据,让学生表能够关联到

且学生表内有关联到班级表的,须要修改班级或者删除,才能对班级表进行修改或者删除

须要级联更新、级联删除,能够在foreign key(class_id) references class_t(cid) on update cascade on delete cascade

删除班级表中一个班,那学生表中关联这一个班的数据也会删除

注意空字符串' '和空null在数据库中不同

8.修改表

语法:
1. 修改表名
      ALTER TABLE 表名 
                      RENAME 新表名;

2. 增长字段
      ALTER TABLE 表名
                      ADD 字段名  数据类型 [完整性约束条件…],
                      ADD 字段名  数据类型 [完整性约束条件…];
                            
3. 删除字段
      ALTER TABLE 表名 
                      DROP 字段名;

4. 修改字段
      ALTER TABLE 表名 
                      MODIFY  字段名 数据类型 [完整性约束条件…];
      ALTER TABLE 表名 
                      CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…];
      ALTER TABLE 表名 
                      CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];

5.修改字段排列顺序/在增长的时候指定字段位置
    ALTER TABLE 表名
                     ADD 字段名  数据类型 [完整性约束条件…]  FIRST;
    ALTER TABLE 表名
                     ADD 字段名  数据类型 [完整性约束条件…]  AFTER 字段名;
    ALTER TABLE 表名
                     CHANGE 字段名  旧字段名 新字段名 新数据类型 [完整性约束条件…]  FIRST;
    ALTER TABLE 表名
                     MODIFY 字段名  数据类型 [完整性约束条件…]  AFTER 字段名;

9.表与表之间的关系

多对一:

  • 学生-班级

  • 多个学生是一个班级的

  • 学生表有一个外键关联班级

  • 书籍-做者

  • 商品-订单

多对多:

  • 学生-班级  多对一 多个学生对应一个班级
  • 班级-学生 多对一 多个班级对应一个学生
  • 多建立一张表,关联两个外键,表示学生id和班级id

一对一:

  • 客户-学生
  • 客户id unique
  • 学生id foreign key unique

10.查询

select * from employee;

select id,name from employee;               查询几个字段

select id,name as n from employee;        查询出来的时候重命名(加as)

select id,name n from employee;             查询出来的时候重命名(空格)

select distinct post from employee;         查询结果去除重复项

select distinct age,sex from employee;    查询的结果只有当年龄和性别都重复才会是重复项

select emo_name,salary*12 as annual_salary from employee;  四则运算(计算年薪)

select concat(emp_name,':',salary) from employee;  拼接concat,有时候姓和名的拼接

select concat_ws('|','apple','male'); 默认以第一个字符为拼接符进行拼接后面的内容

结合case语句  case ... end

selcet
	(
		case
    when emp_name = 'apple' then
    	emp_name
    when emp_name = 'banana' then
    	concat(emp_name, 'BIGSB')
    else
    	concat(emp_name, 'SB')
  	end
  ) as new_name
from employee;

where 约束

筛选符合条件的行

  • 比较运算符: > < >= <=  !=
  • between 80 and 100 值在80到100之间
  • in(80, 90, 100) 值是80或者90或者100
  • like 'e%' 模糊匹配
    • 通配符能够是%或者'_',%表示任意多个字符,'_'表示一个字符
  • 逻辑运算符: and or not
  • 正则
    • regexp '^j' 以j开头的
    • regex 'g$' 以g结尾

分组

group by :

根据谁分组,能够求这个组的总人数,最大值,最小值,平均值,求和,可是求出来的值只和分组字段对应

并不和其余任何字段对应,这个时候查出来的全部字段都不生效

聚合

count(根据分组计数) max min sum avg

select sex,count(sex) from employee group by sex; 显示男女分别有多少人

select age,count(age) from employee group by age; 显示不一样的年龄有多少人

更好的查看

select post,group_concat(emp_name) from employee group by post; 会自动拼接,可是拿不到每个的值

选择各个部门最低工资的人

select post,emp_name,min(salary) from employee group by post;  这是错误的,由于分组显示的姓名不是真正工资最低的,是分组出来

找不到对应的人

having 过滤语句

在having条件中可使用聚合函数

适合去筛选符合条件的某一组数据,而不是某一行数据

先分组,再过滤:求人数大于xx的性别,求年龄大于多少人的年龄

获取每一个部门的平均工资筛选出平均值大于10000的部门

select post,avg(salary) from employee group by post having avg(salary) > 10000;

order by 查询排序

默认升序排 asc

降序 desc

select * from employee order by selery; 根据薪资从小到大排

select * from employee order by age desc; 根据年龄从大到小排

select * from employee order by age,salary desc; 先根据年龄从小到大排,年龄相同,再根据薪资从大到小排

limit m,n

limit n 取前几条数据 不写m默认为0

select * from employee order by selery desc limit 3; 只取薪资最高的前三我的的数据

limit m,n 从第m+1项开始取n项

limit n offset m 与上面相同,从m+1项开始取n项

11.多表查询

连表查询

一张department表,一张employee员工表

select * from department, employee; 会产生一个大表,表是笛卡尔积的形式产生的

select * from department, employee where department.id = dep_id; id有多个须要指定是department仍是employee表里的

所谓连表:

  • 老是在链接的时候建立一张大表,里面存放的是两张表的笛卡尔积
  • 再根据条件进行筛选就能够了
  • where 条件 group by 分组 order by limit 均可以正常使用

表与表之间的链接方式:

  • select * from 表1,表2 where 条件
  • 内链接 inner join ... on ...
    • 必须左表和右表中条件相互匹配的项才会显示出来
    • select * from 表1inner join 表2 on 条件
    • select * from department inner join employee on department.id = employee.dep_id;
    • select * from department as d1 inner join employee as e1 on d1.id = e1.dep_id;           注意是先作连表,因此重命名能够用
  • 外链接
    • mysql不支持 经过
    • select * from 表1 left join 表2 on 条件
    • union
    • select * from 表1 right join 表2 on 条件
    • 右表显示所有,左表中的数据必须和右表条件相互匹配的项才会显示出来
    • 左表显示所有,右表中的数据必须和左表条件相互匹配的项才会显示出来
    • select * from 表1 left join 表2 on 条件
    • 左外链接 left join
    • 右外链接 right join
    • 全外链接 full join

12.子查询

  • 带in的子查询 select * from 表 where 字段 in (select 字段 from 表 where 条件)
  • 带比较子查询 select * from 表 where 字段 > (select 字段 from 表 where 条件)

查询平均年龄在25岁以上的部门

select dep_id from employee group by dep_id having avg(age)>25;

select name from department where id in (select dep_id from employee group by dep_id having avg(age)>25);

查看技术部员工姓名

select name from employee where dep_id in (select id from department where name='技术');

查询大于全部人平均年龄的员工名与年龄

select name, age from employee where age>(select avg(age) from employee);

查询大于部门内平均年龄的员工名与年龄

select name,age from employee as t1 inner join (select dep_id,avg(age) as avg_age from employee group by dep_id) as t2 on t1.dep_id=t2.dep_id where age>avg_age;

exists关键字表示存在,使用这个关键字以后内层查询语句不返回查询的记录,返回一个真假值,返回True,外层查询语句将进行查询,当返回值为False,外层查询语句不进行查询

select * from employee where exists (select id from department where id=200);

13.索引

工做中必备:

建立

删除

知道用了它会加快查询速度

面试:

  • 数据准备
  • 读取一次硬盘时间开销
    • 寻道时间 0.05ms
    • 3600转/7200转 每分钟 一圈 60/7200 = 0.09ms
    • 找到一圈上的数据平均时间为0.045ms
    • 从硬盘上读取一次数据的时间大概是0.1ms
    • cpu每秒可执行5亿条指令,0.1ms可执行5万条cpu指令
    • 磁盘的预读性原理:每一次读区硬盘的单位不是你要多少就读多少,每一次读数据块的大小都是固定的,linux 4096字节 -block
  • 新的数据结构-树
    • root 根节点
    • branch 分支节点
    • leaf 叶子结点
  • mysql中存储数据的两种方式
    • 在分支节点不会存储数据(让树的高度尽可能矮,让查询一个数据的效率稳定),都是叶子结点存储数据
    • 叶子结点之间是双向链表,查找范围很是快
    • 若是不是平衡树,简单的树最差会退化为线性的
    • 平衡树 balance tree 简称b树:可以让查找某一个值的查找速度尽可能平衡,平衡树不必定是二叉树
    • b树改进以后变成B+树
  • 汇集索引(聚簇索引)和非汇集索引(非聚簇索引、辅助索引)都是用b+树进行存储的
    • 叶子结点不存放具体的整行数据,而是存放的这一行的主键的值
    • innodb主键会默认建立一个汇集索引
    • 全表数据都存储在叶子结点上
    • 汇集索引的好处是一次就能够找到对应的值,很差的点就是存储的数据少,只有Innodb必有汇集索引,且仅有一个主键
    • 非汇集索引存储的是对应的地址,还要查表才能找到数据,优势是能够存更多数据,缺点是须要再查表,innodb myisam
  • 索引的建立与删除
    • create index 索引名 on 表(字段)
    • drop index 索引名 on 表
    • 建立主键 primary key 汇集索引+非空+惟一
    • 建立惟一约束 unique 辅助索引+惟一
    • 添加一个普通索引
  • 正确使用索引
    • create index ind_mix on s1(id, name, email);
    • 必须带着最左边的列作条件,从出现范围开始整条索引失效
    • 条件1and条件2 两个同时成立才会成立,但凡一个条件不成立则最终结果不成立
    • 条件1or条件2 只要一个条件成立就成立
    • 多个条件的组合,若是使用and链接,其中一列使用索引,均可以加快查询速度,使用or链接,必须全部的列含有索引,才能加快查询速度
    • 条件1建立了索引,若是条件1不知足,那确定不成立,不用再找条件2
    • 条件1建立了索引,若是条件1不知足,那不必定不成立,还要找条件2,若是条件2每索引,那么查询的效率仍是低
    • 范围越大越慢
    • 范围越小越快
    • 若是like 'a%' 快
    • 若是like '%a' 慢
    • 1/10如下的重复率比较合适建立索引
    • 对哪一个字段建立了索引,就用哪一个字段来查,查询的字段不是索引字段,查询的速度也不会加快
    • 在建立索引的时候,应该对区分度比较大的列进行建立索引
    • 范围
    • 条件列参与运算,或者使用函数会下降索引查询速度
    • and 和 or
    • 联合索引:最左前缀原则

函数都是处理简单的逻辑

存储过程处理的逻辑比较复杂

复杂的逻辑都是用python代码来处理

简单的数据增删改查用sql解决

覆盖索引:

查询过程当中不须要回表

索引合并:

分别建立的两个索引在某一次查询中临时合并成一条索引 a=1 or b=2

执行计划:

explain select 语句 可以查看sql语句有没有按照预期执行,能够查看索引的使用状况,type等级

慢查询优化:

  • 首先从mysql的角度优化
    • 把每一句话单独执行,找哦到效率低的表,优化这句mysql
    • 了解业务场景,适当建立索引,帮助查询
    • 尽可能用连表代替子查询
    • 确认命中索引的状况
  • 考虑修改表结构
    • 拆表
    • 把固定的字段往前调整
  • 使用执行计划,观察sql的type经过以上调整是否提升

mysql慢日志:

  • 在mysql的配置中开启并设置一下
  • 在超过设定时间后,这条sql老是会被记录下来,这个时候咱们能够对这些被记录的sql进行按期优化

14.pymysql模块

通常都是经过python操做数据

import pymysql

conn = pymysql.connect(host='127.0.0.1', user='root', password='123', database='homework')

cur = conn.cursor() #cursor游标 默认以元组返回
#cur = conn.cursor(cursor=pymysql.cursors.DictCursoor) #取出来的数据是以字典返回 更浪费空间
cur.execute('select * from student;')

ret = cur.fetchone()
print(ret)  # 拿到一条数据

ret2 = cur.fetchmany(10) # 拿到多条数据
print(ret2)

ret3 = cur.fetchall() # 拿到全部剩余的数据
print(ret3)
print(cur.rowcount) # 表示拿到多少条数据

cur.close()
conn.close()
#增 删 改
import pymysql

conn = pymysql.connect(host='127.0.0.1', user='root', password='123', database='homework')

cur = conn.cursor()

try:
	cur.execute('insert into student values(17, "男", 3, "apple")')  #执行了只至关于在内存中插入
	cur.execute('update student set gender ="male" where id=17') # 修改
  cur.execute('delete from student where id=17')
  conn.commit() #提交
except Exception as e:
  print(e)
  conn.rollback() # 回滚

cur.close()
conn.close()

实际在操做中会遇到的问题

结合数据库和python写一个登录

import pymysql

usr = input('username :')
pwd = input('password :')
conn = pymysql.connect(host='127.0.0.1',
                       user='root',
                       password='123',
                       database='test'
												)
conn.cursor()


cur.execute('select * from userinfo where user="%s" and password="%s"'%(usr, pwd))

# select * from userinfo where user = "apple" or 1=1;  --"...    后面的东西注释了
#sql注入

#最好使用execute自动拼接
cur.execute('select * from userinfo where user=%s and password=%s', (usr, pwd)) #不用拼接,也不用加""

cur.close()
conn.close()

15.数据备份和事务

事务

  • begin #开启事务
    select age from userinfo where id=1 for update; # 查询id值,for update 加上行级锁
    update emp set salary=100000 where id=1; # 完成更新
    commit #提交事务

备份

表和数据的备份

mydqldump.exe

在cmd命令直接执行

mysqldump -h 服务器 -u用户名 -p密码 数据库名 > 备份文件名.sql

回复数据 在mysql中执行命令

source D:\python\备份文件名.sql

16.小结

数据的

  • insert into 表 values(值)
  • insert into 表(字段1,字段2) values(值1,值2)
  • insert into 表(字段1,字段2) select 字段1,字段2 from 表 2

  • delete from 表 where 条件
  • truncate table 表名

  • update 表 set 字段=值 where 条件

  • select  字段 from 表

    • where 条件 根据条件筛选符合条件的行
    • group by 分组
    • having 过滤条件 根据分组以后的内容进行组的过滤
    • order by 排序
    • limit m,n 从m+1项开始取n项
  • 顺序:from 表--> where -> group by -> having  -> select -> order by -> limit m,n

    • 注意重命名不是何时均可以使用的
    • where 条件不能使用select字段的重命名
    • select emp_name as name, age as a from employee order by a;    #order by 可使用select以后的age as a
    • 在mysql中作了having的优化,能够先找前面是否有重命名,能够在having后面使用重命名,oracle则没有
  • 拓展

    • 在执行select语句的时候,其实是经过where,group by,having这几个语句锁定对应的行

    • 而后循环每一行执行select语句

    • select name from t where id>2;

      先from t,再where id>2拿到数据,再循环拿到的数据,筛选name字段

    • select name,(select_now()) from t; 一样也是循环拿到数据进行筛选

若是一个问题既可使用连表查询也可使用子查询解决,推荐那个连表查询,效率更高

习题:

查询至少有一门可与学号为1的同窗所学课程相同的同窗的学号和姓名

select sid,sname from student right join (

select distinct student_id from score where cid in (select course_id from score where student_id=1) and student_id != 1;

) as t in student_sid = t.student_id;

查询课程编号为‘2’的成绩比课程编号‘1’低的全部同窗的学号、姓名

  • 思路:
    • select student_id,sname from student right join
    • (select t1.sid1 from (select student_id as sid2,num as n2 from score where course_id=2) as t2
    • inner join
    • (select student_id as sid1,num as n1 from score where course_id=1) as t1
    • on t1.sid1=t2.sid2 and t2.n2 > t1.n1) as tmp
    • on student_id = tmp.sid1;
    • inner join
    • (select student_id as sid1,num as n1 from score where course_id=1) as t1
    • on t1.sid1=t2.sid2 and t2.n2 > t1.n1;
    • 先把课程编号2的全部学生id,学生成绩找出来
    • select student_id as sid2,num as n2 from score where course_id=2;
    • 再把课程编号1的全部学生id,学生成绩找出来
    • select student_id as sid1,num as n1 from score where course_id=1;
    • 连表取到知足条件的学生的学号
    • select t1.sid from (select student_id as sid2,num as n2 from score where course_id=2) as t2
    • 连student表找到姓名

正确的使用mysql数据库

  • 从库的角度
    • 搭建集群
    • 读写分离
    • 分库
  • 从表的角度
    • 合理安排表与表之间的关系:该拆的拆,该合的合
    • 把固定长度的字段放在前面
    • 尽可能使用char而不是varchar
  • 从操做数据的角度
    • 建立索引,选择区分度比较大的列,尽可能选长度比较短的字段建立索引,不要建立没必要要的索引(拖慢写入速度,占空间)
    • 使用索引
    • and 只要有一列索引便可命中
    • or 全部列都有索引才会命中
    • 查询的字段不是索引
    • 在条件中使用范围,结果的范围越大速度越慢
    • like 'a%' 快,like '%a' 慢且不命中索引
    • 条件列不能参与计算、不能使用函数
    • and / or
    • 联合索引,遵循最左前缀原则,且从出现范围开始索引失效
    • 条件中的数据类型和实际字段中的类型必须一致
    • select 字段中应该包含order by中的字段
    • where a between value1 and value2
    • 尽可能在where字段约束数值到一个比较小的范围:分页
    • 尽可能使用连表查询代替子查询
    • 删除数据和修改数据的时候条件尽可能使用主键
    • 合理的建立和使用索引
相关文章
相关标签/搜索