1. 数据库简介
1. 定义
数据库就是存储和管理数据的仓库,数据按照一定的格式进行存储,用户可以对数据库中的数据进行增加、修改、删除、查询等操作。
2. 分类
- 关系型数据库:指采用了关系模型来组织数据的数据库,简单来说,关系模型指的就是二维表格模型
- 数据行
- 数据列
- 数据表
- 数据库(数据表的集合)
- 非关系型数据库:非关系型数据库,又被称为NoSQL(Not Only SQL ),对NoSQL 最普遍的定义是“非关联型的”,强调 Key-Value 的方式存储数据。
3. 作用
数据库的作用就是存储和管理数据的
4. 数据库的作用就是存储和管理数据的
- 持久化存储
- 读写速度极高
- 保证数据的有效性
2. 关系型数据库管理系统
1. 介绍
数据库管理系统(英语全拼:Relational Database Management System,简称RDBMS)是为管理关系型数据库而设计的软件系统,如果大家想要使用关系型数据库就需要安装数据库管理系统,其实就是一个应用软件。
2. SQL的介绍
- SQL(Structured Query Language)是结构化查询语言,是一种用来操作RDBMS的数据库的语言。
- SQL语言主要分为:
- DQL:数据查询语言,用于对数据进行查询,如select
- DML:数据操作语言,对数据进行增加、修改、删除,如insert、update、delete
- TPL:事务处理语言,对事务进行处理,包括begin transaction、commit、rollback
- DCL:数据控制语言,进行授权与权限回收,如grant、revoke
- DDL:数据定义语言,进行数据库、表的管理等,如create、drop
3. 数据类型和约束
1. 数据类型
-
整数:int,bit
- bit是二进制位0,1;类似Boolean类型中的True和False
类型 字节大小 有符号范围(Signed) 无符号范围(Unsigned) TINYINT 1 -128 ~ 127 0 ~ 255 SMALLINT 2 -32768 ~ 32767 0 ~ 65535 MEDIUMINT 3 -8388608 ~ 8388607 0 ~ 16777215 INT/INTEGER 4 -2147483648 ~2147483647 0 ~ 4294967295 BIGINT 8 -9223372036854775808 ~ 9223372036854775807 0 ~ 18446744073709551615 小数:decimal;表示浮点数,如 decimal(5, 2) 表示共存5位数,小数占 2 位.
-
字符串:varchar,char;
- char表示固定长度的字符串,如char(3),如果填充'ab'时会补一个空格为'ab ',3表示字符数
- varchar表示可变长度的字符串,如varchar(3),填充'ab'时就会存储'ab',3表示字符数
- text,可变长度,字符个数大于 4000
- longtext,可变长度, 极大型文本数据
-
日期时间: date, time, datetime
类型 字节大小 示例 DATE 4 '2020-01-01' TIME 3 '12:29:59' DATETIME 8 '2020-01-01 12:29:59' YEAR 1 '2017' TIMESTAMP 4 '1970-01-01 00:00:01' UTC ~ '2038-01-01 00:00:01' UTC -
枚举类型:enum(枚举值)
- 使用时,枚举值可以用数字代替,对应数字从1开始
2. 数据约束
- 主键 primary key: 物理上存储的顺序. MySQL 建议所有表的主键字段都叫 id, 类型为 int unsigned.
- 非空 not null: 此字段不允许填写空值.
- 惟一 unique: 此字段的值不允许重复.
- 默认 default: 当不填写字段对应的值会使用默认值,如果填写时以填写为准.
- 外键 foreign key: 对关系字段进行约束, 当为关系字段填写值时, 会到关联的表中查询此值是否存在, 如果存在则填写成功, 如果不存在则填写失败并抛出异常.一个表中可以有多个外键,外键必须关联另一张表的主键
4. 命令行客户端MySQL的基本使用
1. 登录和退出
mysql -uroot -p
quit 或 exit 或 ctrl + d
sudo service mysql start
sudo service mysql stop
sudo service mysql restart
sudo service mysql status
2. 数据库操作
-
查看所有数据库
show databases;
-
创建数据库
create database 数据库名 charset=utf8;
-
使用数据库
use 数据库名;
-
查看当前使用的数据库
select database();
-
删除数据库-慎重
drop database 数据库名;
3. 表结构操作
-
查看当前数据库中所有表
show tables;
-
创建表
create table 表名( 字段名称 数据类型 可选的约束条件, column1 datatype contrai, ... );
-
修改表-添加字段
alter table 表名 add 列名 类型 约束; 例: alter table students add birthday datetime;
-
修改表-修改字段类型
alter table 表名 modify 列名 类型 约束; 例: alter table students modify birthday date not null;
- modify: 只能修改字段类型或者约束,不能修改字段名
-
修改表-修改字段名和字段类型
alter table 表名 change 原名 新名 类型及约束; 例: alter table students change birthday birth datetime not null;
说明:
- change: 既能对字段重命名又能修改字段类型还能修改约束
-
修改表-删除字段
alter table 表名 drop 列名; 例: alter table students drop birthday;
-
查看数据表的创建信息
show create table 表名; 例: show create table students;
-
查看创库SQL语句
show create database 数据库名; 例: show create database mytest;
-
删除表
drop table 表名;
4. 表数据操作
-
查询数据
-- 1. 查询所有列 select * from 表名; 例: select * from students; -- 2. 查询指定列 select 列1,列2,... from 表名;
-
添加数据
-- 1. 全列插入:值的顺序与表结构字段的顺序完全一一对应 insert into 表名 values (...) 例: insert into students values(0, 'xx', default, default, '男'); -- 2. 部分列插入:值的顺序与给出的列顺序对应 insert into 表名 (列1,...) values(值1,...) 例: insert into students(name, age) values('王二小', 15); -- 3. 全列多行插入 insert into 表名 values(...),(...)...; 例: insert into students values(0, '张飞', 55, 1.75, '男'),(0, '关羽', 58, 1.85, '男'); -- 4. 部分列多行插入 insert into 表名(列1,...) values(值1,...),(值1,...)...; 例: insert into students(name, height) values('刘备', 1.75),('曹操', 1.6);
说明:
- 主键列是自动增长,但是在全列插入时需要占位,通常使用空值(0或者null或者default)
- 在全列插入时,如果字段列有默认值可以使用 default 来占位,插入后的数据就是之前设置的默认值
-
修改数据
update 表名 set 列1=值1,列2=值2... where 条件 例: update students set age = 18, gender = '女' where id = 6;
-
删除数据
delete from 表名 where 条件 例: delete from students where id=5;
问题:
上面的操作称之为物理删除,一旦删除就不容易恢复,我们可以使用逻辑删除的方式来解决这个问题。
-- 添加删除表示字段,0表示未删除 1表示删除 alter table students add isdelete bit default 0; -- 逻辑删除数据 update students set isdelete = 1 where id = 8;
说明:
- 逻辑删除,本质就是修改操作
5. as起别名
-
使用 as 给字段起别名
select id as 序号, name as 名字, gender as 性别 from students;
-
可以通过 as 给表起别名
-- 表名.字段名 -- 可以通过 as 给表起别名 select s.id,s.name,s.gender from students as s;
6. distinct去除重复数据
select distinct 列1,... from 表名;
注意: 如果去多字段去重,那么结果会比较多个字段,只有多个字段中的值完全相同,才认为是重复数据
例: 查询班级中学生的性别
select name, gender from students;
7. where条件查询
- 格式如下:
select * from 表名 where 条件;
例:
select * from students where id = 1;
- 比较运算符查询
- 等于: =
- 大于: >
- 大于等于: >=
- 小于: <
- 小于等于: <=
- 不等于: != 或 <>
- 逻辑运算
- and
- or
- not
- 模糊查询
- like是模糊查询关键字
- %表示任意多个任意字符
- _表示一个任意字符
- 范围查询
- between .. and .. 表示在一个连续的范围内查询
- in 表示在一个非连续的范围内查询
- 空判断
- between .. and .. 表示在一个连续的范围内查询
- in 表示在一个非连续的范围内查询
- 不能使用 where height = null 判断为空
- 不能使用 where height != null 判断非空
- null 不等于 '' 空字符串
8. 排序order by
select * from 表名 order by 排序字段 排序方式,排序字段 排序方式,排序字段 排序方式;
排序方式:默认使用升序asc;降序desc;
9. 分页查询limit
- select * from 表名 limit start,count;
- start表示开始索引,默认从0开始索引
- 获取第n页数据的SQL语句:select * from 表名 limit (n-1) * count, count
5. MySQL条件查询
1. 聚合函数
- count(col): 表示求指定列的总行数
- max(col): 表示求指定列的最大值
- min(col): 表示求指定列的最小值
- sum(col): 表示求指定列的和
- avg(col): 表示求指定列的平均值
- 聚合函数默认忽略字段为null的记录;如果指定字段的值为null 时,使用ifnull(字段,参数值)进行替换计算
- count(*) 来统计所有记录
- 聚合函数一般会的配合分组一起使用
2. 分组查询group by
- select 分组字段, 聚合函数 from 表名 group by 分组字段;
- 例:select gender,avg(age) from students group by gender;
- group_concat(字段名) 在分组中使用,作用是来拼接显示分组中的数据
- 例:select gender,group_concat(name) from students group by gender;
- group by + having 是对分组数据进行条件过滤
- select gender,count(*) from students group by gender having count(*)>2;
- group by + with rollup在最后记录后面新增一行,显示select查询时聚合函数的统计和计算结果
3. 连接查询
连接查询可以实现多个表的查询,当查询的字段数据来自不同的表就可以使用连接查询来完成。
-
内连接
select * from 表1 as 表别名1 inner join 表2 as 表别名2 on 连接条件;
- inner join, 连接时,得到的结果是两表的交集
- on 条件可以省略,得到结果是笛卡尔积形式,这个结果无意义.
-
左连接
select 字段 from 表1 left join 表2 on 表1.字段1 = 表2.字段2
- 左连接以左表为主根据条件查询右表数据,右表数据不存在使用null值填充。
- on不能省略
-
右连接
select 字段 from 表1 right join 表2 on 表1.字段1 = 表2.字段2
- 右连接以右表为主根据条件查询左表数据,左表数据不存在使用null值填充。
- on不能省略
-
自连接
- 自连接查询 也没有自己的连接关键字,也可以使用上述的任意一种.
- 自连接查询 是一种特殊的表数据表示形式,连接的两张表实际是同一张表
- 因为在多表连接查询 时一般会为表起别名.
4. 子查询
- 在一个 select 语句中,嵌入了另外一个 select 语句, 那么被嵌入的 select 语句称之为子查询语句,外部那个select语句则称为主查询.
- 按照子查询的结果.子查询 可分为三类:
标量子查询 :子查询 返回结果为一行一列
列级子查询 : 子查询 的返回结果为多行一列 ,一般会使用范围查询 in 来操作
行级子查询: 子查询返回的结果为一行多列,一般会使用()将要比较的多个字段进行包含 - 子查询是一个完整的SQL语句,子查询被嵌入到一对小括号里面
5. 外键约束
外键的作用是用来实现数据 的引用完整性,保证数据的有效性
一个表中可以创建多个外键;外键必须关联的是另一张表的主键;在关联时,外键字段和类型要和关联的主键相同
-
建立方式:
创建表时加入外建,前提是被关联的表存在 create table 表名(字段 类型, ...., foreign key(外键字段) references 参考表名(参考字段)); 在表已建立成功后,添加外键 alter table 表名 add foreign key(外键字段) references 参考表名(参考字段); 被参考的表或表中的数据不能随意删除,如果想删除,要么先删掉外键所在的表或表中的数据再删除,要么删除外键关系 删除外键: alter talbe 表名 drop foreign key 外键名;
6. MySQL高级指令
-
将查询结果插入到其他表中
insert into .. select ..
insert into good_cates(name) select cate_name from goods group by cate_name;
-
使用连接更新表中某个字段数据
update .. join ..
update goods g inner join good_cates gc on g.cate_name=gc.name set g.cate_name=gc.id;
-
创建表并给字段插入数据使用
create table .. select...
create table good_brands ( id int unsigned primary key auto_increment, name varchar(40) not null) select brand_name as name from goods group by brand_name;
-
修改表结构
- alter table语句修改表结构
7.事务
1. 介绍
事务就是用户定义的一系列执行SQL语句的操作, 这些操作要么完全地执行,要么完全地都不执行, 它是一个不可分割的工作执行单元。
2. 四大特性
- 原子性(Atomicity):原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚
- 一致性(Consistency):一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
- 隔离性(Isolation):一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态,也就是说一个事务执行之前和执行之后都必须处于一致性状态。
- 持久性(Durability):指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
3. 事务的使用
-
查看MySQL数据库支持的表的存储引擎
show engines;
- 常用的表的存储引擎是 InnoDB 和 MyISAM
- InnoDB 是支持事务的
- MyISAM 不支持事务,优势是访问速度快,对事务没有要求或者以select、insert为主的都可以使用该存储引擎来创建表
-
开启事务
begin; 或者 start transaction;
- 开启事务后执行修改命令,变更数据会保存到MySQL服务端的缓存文件中,而不维护到物理表中
- MySQL数据库默认采用自动提交(autocommit)模式,如果没有显示的开启一个事务,那么每条sql语句都会被当作一个事务执行提交的操作
- set autocommit = 0 表示取消自动提交事务模式,直到显示的执行commit和rollback表示该事务结束。
-
提交事务
将本地缓存文件中的数据提交到物理表中,完成数据的更新。
commit;
-
回滚事务
放弃本地缓存文件中的缓存数据, 表示回到开始事务前的状态
rollback;
8. PyMySQL的使用
1. 安装pymysql第三方包
sudo pip3 install pymysql
2. pymysql的使用:
-
导包
import pymysql
-
创建连接对象
conn = pymysql.connect(host='localhost', port=3306, user='root', password='mysql',database='python', charset='utf8') * 参数host:连接的mysql主机,如果本机是'localhost' * 参数port:连接的mysql主机的端口,默认是3306 * 参数user:连接的用户名 * 参数password:连接的密码 * 参数database:数据库的名称 * 参数charset:通信采用的编码方式,推荐使用utf8
-
获取游标对象
cur = conn.cursor()
游标操作说明:
- 获取查询结果集中的一条数据:cur.fetchone()返回一个元组, 如 (1,'张三')
- 获取查询结果集中的n条数据:cur.fetchmany(n)返回一个元组
- 获取查询结果集中的所有数据: cur.fetchall()返回一个元组,如((1,'张三'),(2,'李四'))
- 关闭游标: cur.close(),表示和数据库操作完成
-
执行SQL语句,返回值就是 SQL 语句在执行过程中影响的行数
sql_str = '''select * from goods''' row_count = cur.execute(sql_str)
-
获取指定条数记录
result = cur.fetchmany(4) for t in result: print(t)
-
关闭游标
cur.close()
-
关闭连接
conn.close()
9. 索引
1. 介绍
索引在MySQL中也叫做“键”,它是一个特殊的文件,它保存着数据表里所有记录的位置信息
应用场景:
当数据库中数据量很大时,查找数据会变得很慢,我们就可以通过索引来提高数据库的查询效率。
2. 索引的优缺点
优点:
加快数据的查询速度
#### 缺点:
创建索引会耗费时间和占用磁盘空间,并且随着数据量的增加所耗费的时间也会增加
使用原则:
- 对经常更新的表就避免对其进行过多索引的创建,对经常用于查询的字段应该创建索引,
- 数据量小的表最好不要使用索引,因为由于数据较少,可能查询全部数据花费的时间比遍历索引的时间还要短,索引就可能不会产生优化效果。
- 在一字段上相同值比较多不要建立索引,比如在学生表的"性别"字段上只有男,女两个不同值。相反的,在一个字段上不同值较多可是建立索引。
3. 索引的使用
-
查看表中已有索引
show index from 表名;
- 主键列会自动创建索引
-
索引的创建
-- 创建索引的语法格式 -- alter table 表名 add index 索引名[可选](列名, ..) -- 给name字段添加索引 alter table classes add index my_name (name);
- 索引名不指定,默认使用字段名
-
索引的删除
-- 删除索引的语法格式 -- alter table 表名 drop index 索引名 -- 如果不知道索引名,可以查看创表sql语句 show create table classes; alter table classes drop index my_name;
-
联合索引
联合索引又叫复合索引,即一个索引覆盖表中两个或者多个字段,一般用在多个字段一起查询的时候。
-- 创建联合索引 alter table teacher add index (name,age);
- 减少磁盘空间开销,因为每创建一个索引,其实就是创建了一个索引文件,那么会增加磁盘空间的开销。
- 在使用联合索引的时候,我们要遵守一个最左原则,即index(name,age)支持 name 、name 和 age 组合查询,而不支持单独 age 查询,因为没有用到创建的联合索引。