基本的介绍,使用。
数据库的诞生:
人类在过程中,创造了 数字,文字,符号等进行数据较多记录,但是随着认知能力和创造能力的提升,数据量越来越大,对于数据的记录和准确查找成为一个重大难题,计算机诞生后,数据开始在计算机中存储并计算,并设计出了数据库系统
数据库解决的问题:
- 持久化存储
- 优化读写
- 保证数据的有效性
为什么要使用数据库:
因为数据量越来越大,有效的存储相应的数据.
分类:
文档型:例如SQLit,就是一个文件,通过对其操作完成对数据库的操作
服务型:例如mysql,数据库存储在一个物理文件中,但是要使用终端以tcp/ip协议链接,再进行数据库的读写操作.
三范式:
概念:经过研究对使用中问题的总结,提出了一些规范,这些规范成为范式。
范式:
第一范式:列不可拆分
第二范式:唯一标识
第三范式:引用主键
- R模型:
当前物理的数据库都是按照E-R模型设计的
E:标识entry,实体
R:标识relationship,关系
一个实体对应转换为数据库中的一个表
关系标书两个实体之间的对应规则:
1、一对一
2、一对多
3、多对多
数据库的简单使用:
显示数据库: show databases;
mysql:用户的权限
,创建数据库:
格式:
utf-8: create database 数据库名 defalut charset utf8 collate utf8_general_ci;
gbk:create database 数据库名 defalut charset utf8 collate utf8_chinese_ci;
使用数据库
格式 use 数据库名;
查看当前正在使用的数据库
select database();
显示当前数据库中的所有表,
show tables;
用户管理:
注意: 需要使用root用户创建用户.
创建用户 格式:
create user “用户名”@”IP地址”identified by “密码”;
所有ip都能访问就是%
删除用户:
drop user ”用户名”@”host
修改用户:
rename user “用户名”@”IP地址” to “新用户名”@”IP地址”;
修改用户密码:
set password for “用户名”@”IP地址” = password(“西密码”);
创建了之后需要授权才能访问
授权管理:需要root用户
查看权限
show grants for “用户名”@”ip地址”;
授权:
格式: grant 权限 on 数据库.表 to “用户名”@”IP地址”;
取消授权:
revoke 权限 on 数据库.表 from “用户名”@”IP地址”;
将数据读取到数据,立即生效
flush privileges
后期开大基本不会使用root用户,进入公司后,公司的DB人员会提供一个用户名和密码并说明权限,
数据库操作:
utf-8 : create database 数据库名 default charset utf8 collate utf8_general_ci;
gbk: create database 数据库名 default charset gbk collate gbk_chinese_ci;
删除数据库:
drop databases 数据库名
切换数据库:
use 数据库名;
查看当前使用数据库:
select 数据库名;
对数据库内表的操作:
查看所有表的名称:
show tables;
建表:
数据完整性:
- 一个数据库就是一个完整的业务单元,数据库里可以包含多张表,数据被存储在表中
- 在表中为了跟家精准的存储数据,保证数据的正确有效性,可以在创建表的时候,为表添加一些强制性的验证,包括数据字段的类型、约束。
格式:
create table 表名(列名 类型[约束1[,约束2……])engine = 引擎 default charset=编码;
表名:给数据集合起的名字
列名:字段的名字
编码:与数据库编码相同,解决存储编码错误的问题
引擎:
myisam:默认引擎,不支持事物
innodb:支持事物,原子性操作
类型:
bit :字节
tinyint:小整数 有符号(最高位表示符号正负)和无符号(最高位也表示数据)
int:整数(默认11位) 有符号和无符号
bigint:大整数 有符号和无符号
decimal:准确的小数值
float:单精度浮点数 数据越大,精度越不准。有效位:6-8
double:双精度浮点数,有效位:13-15
char:固定长度的字节 最多255个 优点速度快
varchar:用于变长的字符串,最多255个字符,一般都写在最后面,优化数据
text:保存变长的大字符串,最多65535个字符
mediumtext:16777215字节
longtext:4294967295-4gb
时间:
DATE :yyy-mm-dd
TIME:HH:MM:SS
YEAR:YYYY
DATETIME:YYY-MM-DD HH:MM:SS
TIMESTAMP:YYYYMMDD HHMMSS
其他:
enum: 枚举类型,从中选取一个
set:集合变量,从中选取多个写入。
作用:明确字段的数据类型
约束:
primary key: 主键 作用:唯一约束标识数据库表中的每条记录
主键必须包含唯一的值
主键列不能包含null值。
每个表都应该有一个主键,并且每个表只能拥有一个主键
not null: 非空约束 作用:约束强制列不能接受null值
约束强制字段始终保安值,所以如果不向字段添加值,就无法插入和更新数据。
null: 空 作用:允许为空,默认是这个
auto_increment:作用:自增长
自增长列,必须是索引(含主键)
default:作用:用于向列中插入默认值
unique:唯一值 作用:约束标识数据库中表的每条数据
使用: unique 唯一索引名称(列名1)
与primary key 的区别:
两者都是列或列集合提供了唯一性的保证
pk拥有自动定义的unique约束
每个表可以有多个unique约束,但是每个表只能有一个pk约束
foreign key:外键
一个表中的fk指向另一个表中的pk
用于预防破坏表之间的连接动作
也能繁殖非法数据插入外键列,因为它必须是
他所指向的那个表中的值之一。
查看数据:
select * from 表名;
说明:
- from 后面关键字写的表名,表示数据来源这个表
- select 后面写表中的列名,如果是*则表示所有列。
- 如果要查询多个列,列之间用逗号分隔。
插入数据:
- 全列插入。
- 格式: insert into 表名 values(数据1,2,3……);
- 注意:主键是自增长,但是,在插入的时候需要站位,在插入成功后一实际值为准。
- 缺少插入。
- 格式: insert into 表名(列1,列2 ……) values(数据1,2,3……);
- 同时插入多条数据。
- 格式:insert into 表名 values(数据1,2,3……),(数据1,2,3……),(数据1,2,3……);
- 格式: insert into 表名(列1,2……)values数据1,2,3……),(数据1,2,3……),(数据1,2,3……);
删除表:
drop table表名;
查看表结构
desc 表名
查看建表语句:
show create table 表名;
show create table 表名 /G;
重命名表名:
rename table 原表名 to 新表名;
清空表数据
delete from 表名;
truncate table 表名;
修改表:
添加列:
alter table 表名 add 列名 类型;
删除列:
alter table 表名 drop column 列名;
修改列:
alter table 表名 modify column 列名 类型;#修改的是类型
alter table 表名 change 原列名 新列名 类型;#修改列名和类型。
添加主键:
alter table 表名 add primary key(列名);#列名需要存在的
删除主键:
alter table 表名 drop primary key;#不能删除自动增长的
alter table 表名 modify 列名 (类型),drop primary key;#类型是站位的。
添加外键:
删除外键:
修改默认值:
alter table 表名 alter 列名 set default 默认值;
删除默认值
alter table 表名 alter 列名 drop default;
auto_increment:作用:自增长
自增长列,必须是索引(含主键)
原理:
使用 show create table 表名\G 语句第一次查看建表格式,没有出现,等到插入数据之后再去查看的时候就出现了auto_increment = 值
其增长是步长为1递增的
mysql
基于会话级别的,想要修改的话有两种
- 修改自身会话的
-
-
- show session variables like ‘auto_inc%’;
- set session auto_increment_increment =2;#只能修改自身的不能修改全部的。修改的是步长。
- set session auto_increment_offset = 2 ; 这个是修改的是起始值,一般无需修改。
-
-
- 修改全全局会话的
-
-
- show global variables like ‘auto_inc%’;
- set global auto_increment_increment =2;修改的是全局的步长
- set global auto_increment_offset = 2 ;修改的是全局的起始值。
-
-
primary key: 主键
它是一种特殊的唯一索引,不允许为空,如果主键使用单个列,则它的值必须唯一。如果是多个列,则其组合必须唯一。
使用单个列
create able student(
id int not null auto_increment primary key,
name char(20)
) engine = innodb default charset = utf8
使用多个列
create able student(
id int not null auto_increment,
id1 int not null,
primary key (id,id1)
name char(20)
) engine = innodb default charset = utf8
unique:唯一值
优点:
- 加速查询。
- 唯一约束(可以为null)。
是够可以有多个唯一值的数。
主要多条数据只要有一个不同就可以插入进去 因为其是联合唯一。
外键:
如果我们在一个表中想要获取一个值 ,但是这个的值时变化的,我们要方便添加进去而且还需要其能够在输入不是另外一张表中的东西时会出现报错。
pymysql模块:
2018.8.26里
安装:pip istall pymysql
建表:
增:
改:
删:
查:
sql注入:
增加多条数据。
索引
一、作用:
- 约束
- 加速查找
二、分类:
- 主键索引
-
-
- 特点:最多有一个,不能为空,不能重复,加速查询
-
-
- 普通索引
- 唯一索引
-
-
- 特点:可以有多个,不能重复,加速查询
-
-
- 联合索引
-
-
- 分类:联合主键索引,联合唯一索引,联合普通索引
-
-
- 全文索引(忽略)
为什么使用索引?
快
无索引:从前到后依次查找
原理:
额外的文件保存特殊的数据结构
注意:查询快,插入,更新,删除操作会变慢。
索引算法种类
- btree索引
名称:二叉树
mysql使用的格式,效率高
- hash索引
-
-
- 单值查询速度快,但是在文件中不是按照顺讯存储,所以范围查询时效率不会太高
-
-
创建索引
- 主键索引
不建议额外添加,在建表时已经创建
- 全文索引
作用:用于在一篇文章中,奸恶文本信息
说明:mysql 从3.23.23版本开始开始支持全文索引,全文索引的类型为fulltext,
可以创建在varchar或者text类型的字段身上。
注意:一般不用mysql 的,一般会基于其他框架实现
- 普通索引
格式: create index 索引名称 on 表名(列名)
删除: drop index 索引名称 on 表名 ;
索引合并:
把多个单列索引合并使用
- 唯一索引
格式: create unique index 索引表名 on 表名(列名)
删除:drop unique index 索引名称 on 表名 ;
- 联合索引
- 联合唯一索引
格式: create unique index 索引表名 on 表名(列名)
删除:drop unique index 索引名称 on 表名 ;
- 联合普通索引
格式: create index 索引表名 on 表名(列名)
删除:drop index 索引名称 on 表名 ;
最左侧前缀匹配特性:
不用索引的情况:
- where email = “[email protected]”
- where age*5;
- where email= “[email protected]” and age = 5;
- 索引合并vs联合索引
联合索引效率高于索引合并
- 覆盖索引
直接在索引文件中获取信息,无需去表中获取
索引的注意事项:
- 频繁查找的列创建索引
- 避免使用select * #覆盖索引
- 尽量使用count(1)或者 count(列)替代 count(*),在某些数据库中 count(*)的效率低,但是在现版本的mysql中不存在这个问题
- 创建表是尽量使用char替换varchar
- 表的字段顺序固定长度字段优先
- 联合索引替代多个单列索引合并(经常使用多个条件查询)
- 尽量使用段索引,字段类型为text类型添加索引必须要使用短索引
- 使用连接(join)替代子查询。
- 类型需要一致
- 索引散列值重复少不适合建立索引
命中索引
给字段创建索引,并不是所有的情况都能使用到索引,索引要想生效需要命中索引。
无法命中索引的情况
- like ‘xx%’
- 使用函数
select * from student where reverse(name)=”xxxx”;
- or
当or条件中含有未建立索引的列才失效,当有and后有索引时就不失效了。
走索引:
select * from student where id = 444;
不走索引:
select * from student where id = 444 or name = “xxxxx”
- 类型不一致
如果列是字符串类型,传入条件必须使用’’引起来
注意:主键列不适用
- !=
普通索引不走索引。
注意:主键列不适用
- >
普通索引不走索引。
注意:如果主键或者索引类型是整数类型,还是会走索引。
- order by
当根据索引排序时,选择的映射如果不是索引,则不走索引。
不走: select email from student order by name desc;
走: select name from student order by name desc;
注意:如果对主键排序,还是会走索引
- 联合索引没有使用最左侧
计划执行
作用:让mysql预估执行操作的时间(一般正确)
使用: explain SQL语句
字段:
- select_type
查询类型
simple 简单查询
primary 最外层查询
subquery 映射子查询
derived 子查询
union 联合查询
union result 使用联合的结果
- table
正在访问的表名
- type
查询时的访问方式
all
index
range
index_range
ref_or_null
ref
eq_ref
const
system
越往下效率越高。
- possible_keys
可能使用的索引
- key
真实使用的索引
- key_len
mysql 中使用索引字段的长度
- rows
mysql 估计为了找到所需要的行而读取的数据行数
- Extra
包含mysql解决查询的详细信息
Using index
Using where
Using temporary
Using filesort
Range checked for each recode
分页优化
select * from student limit xxxx,xx;
解决方案:
- 不让访问
- 索引表中扫描,这样效率会快一点点。
select * from student where id in (select id from student limit xxxx,xx);
- 记住当前页数据的最大id和最小id
- 只有上一页和下一页
max_id min_id
上一页:
select * from student where id < min_id limit 10;
下一页:
select * from student where id > max_id order by desc limit 10;
- 上一页,1,2,3,4,5,6,7,8,9,下一页
select * from student where id in (select id from (select id from student where id >max_id limit 30)as T order by T.id desc limit 10);
视图
概念:
给SQL起别名,方便以后使用,类似临时表。
创建视图:
格式:
create view 视图名称 as SQL语句
注意:视图是虚拟存在的。视图不常用,可读性不高。
删除视图: drop view 视图名称
修改视图: alter view 视图名称 as SQL语句;
触发器:
作用:当对某张表做增删改操作时,可以使用触发器自定义关联行为。
注意:查询不会触发触发器
举例: 在用户注册时,会在用户表中增加一条数据,同时也要再日志表中增加一条数据,
解决例子中的问题
- 程序级别解决,两条sql语句顺序执行
- 触发器解决,只需要在用户表中插入,而无需手动往日志表中添加数据.。
创建触发器:
- 插入前
格式:create trigger 触发器名 before insert on 表名for each row
begin
……
end
- 插入后
格式:create trigger 触发器名 after insert on 表名for each row
begin
……
end
- 删除前
格式:create trigger 触发器名 before delete on 表名for each row
begin
……
end
- 删除后
格式:create trigger 触发器名 after delete on 表名for each row
begin
……
end
- 更新前
格式:create trigger 触发器名 before update on 表名for each row
begin
……
end
- 更新后
格式:create trigger 触发器名 after update on 表名for each row
begin
……
end
delimiter:修改结束字符
delimiter // 结尾变成 //
delimiter //
create trigger aaa after insert on grade for each row
begin
insert into teacher(name ) values(new.name)
end //
delimiter ;
注意:new表示新数据。
删除一个班级后,再插入一个老师,老师的名字为删除的班级的名字
delete from grade where id=1;
delimiter //
create trigger aaa after insert on grade for each row
begin
insert into teacher(name ) values(old.name)
end //
delimiter ;
注意:old表示老数据
函数
- 内置函数
- 自定义函数
delimiter //
create function func(
a int,
b int)
returns int
begin
declare num int default 0;
end //
delimiter ;
NULL字段
建议:以后在建表时,额外添加几个无用(备用)的字段
添加新的字段 就修改备用的字段。