MySql数据库详解
一、数据库分类
了解三范式:
一范式(1NF):字段不可分,每个字段都是原子性。
二范式(2NF):有主键,非主键字段依赖主键。
三范式(3NF):非主键字段不能相互依赖。
- 关系型数据库(行、列)
- 概念:指用 关系模型来组织数据信息 的数据库。关系模型指的是二维表格模型,而一个关系型数据库便是由二维表以及表之间(表和表、行和列之间)的关系所构成的一个数据集合。
- eg:mysql、orcale、sql Server、DB2、sqllite
- 非关系型数据库()
- 概念:指非关系型的,分布式系统的,且一般不确保遵照ACID标准的数据储存系统。
非关系型数据库算是一 种数据结构化储存的集合 ,可以是 文档或键值对 等。
非关系型数据库的本质是传统关系型数据库的功能阉割版本,通过去掉不需要的功能来提高性能。 - eg:Redis、MongDB
- DBMS(数据库管理系统)、RDBMS(关系型数据库管理系统)
- 数据库的管理软件,科学有效的管理数据,维护和获取数据。
二、Mysql的基础语法
MySql关键字不区分大小写
自定义结束符号,系统默认为;
delimiter $ //执行之后结束符就会改变
- 修改数据库密码
- 知道密码的情况
//修改数据库密码
alter user 'root'@'localhost' identified by 'pass_123'
//刷新权限
flush privileges;
2.管理数据库,一些基础操作
//命令行执行sql文件:
mysql -u root -p -D数据库名称<物理地址
//创建数据库 if not exists 避免error报错,转为警告
create database if not exists 数据库名称
//查看创建数据库语句
show create table;
//删除数据库
drop database if exists 数据库名称
//切换数据库
use 数据库名称
//查看所有数据库
show databases
//查看所有表
show tables
//显示某个表的所有结构信息
desc/describe 表名称 《==》 show columns from 表名称
//查看表的索引、主键信息
show index from 表名称
//explain 分析sql执行情况
eg: explain select * from user;
//该命令将输出Mysql数据库管理系统的性能及统计信息。
show table status from 数据库名 // 显示数据库中所有表的信息
show table status from 数据库名 like'runoob%'; # 表名以runoob开头的表的信息
show table status from 数据库名 like'runoob%'\G; # 加上 \G,查询结果按列打印
//退出mysql
exit
- 数据库语言
- DDL 数据库定义语言
- DML 数据库操作语言
- DQL 数据库查询语言
- DCL 数据库控制语言
- 数据库类型
- 数值类型
整数值
浮点数值
小数值 - 日期和时间类型
日期值
时间值
年份值
时间戳
混合日期 - 字符串类型
定长字符串
变长字符串
短文本字符串
长文本数据
中等长度文本数据据
极大文本数据
二进制255个字符的二进制字符串
二进制文本数据
- 数据库表操作
- 创建数据表
//创建数据库表 if not exists 如果不存在就不执行,避免报错
//eg:创建一个用户表
create table if not exists user(
user_id int auto_increment, --设置属性自增
user_name varchar(25) not null, --设置属性非空
user_date timestamp not null default current_timestamp --设置自动获取时间
primary key(user_id) --设置表主键
)ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8;
- 删除数据表
drop table 表名称;
- 修改数据表
//修改表名
alter table 表名 rename to 新表名
//修改表结构,添加索引
alter table 表名 add index 索引名(字段名);
//修改字段类型及字段名
法一:alter table 表名 modify 字段名 需要修改的字段类型
法二:alter table 表名 change 原字段名 原字段名/新字段名 字段类型
//添加表字段
alter table 表名 add 字段名
//删除表字段
alter table 表名 drop 字段名
- 从命令提示符中读取数据 where binary
//使用binary关键字区分大小写
select * from user where binary user_name='ABC';
select * from user where binary user_name='abc';
- 插入数据
insert into 表名(表的列名) values(表的列对应的值)
- 查询数据,返回行数(查询指定数据),查询空值
select * from 表名 --查询表所有的数据
select 列名(一个或多个) from 表名 --设定返回的记录数。
select * from 表名 limit 返回的行数 --查询表所有的数据
//敲黑板
//指定返回第三行到第八行,
select * from user limit 2,6; //第一个参数为3-1,即开始处,第二个是指定返回的行数
select * from user limit 6 offset 2; //第一个参数为返回的行数,第二个为开始的地方3-1处
//查询空值问题,
select * from user where user_name=null --错误操作
select * from user where user_name is null;--正确操作
//查询非空值问题,
select * from user where user_name!=null --错误操作
select * from user where user_name is not null;--正确操作
//过滤重复的数据
select DISTINCT name,age,sex from user;
- 更新数据
update 表名 set 列名=需要改变 的值 where 列名=条件值
- 删除数据
delete from 表名 where 列名=条件值
- like字句(模糊查询)
//用于查询某个字段
select * from 表名 where like '%字段'
//注意,如果没有”%“的话,like就与=效果一样了。%匹配多个字符,_匹配单个字符
select * from user where user_name like '王_' and user_age=22;
select * from user where user_name like '王%' or user_age=22;
- order by–排序
//desc;降序排序、asc:升序排序(默认)
select * from 表名 order by 排序条件;
select * from user order by user_age desc;
- group by–分组
//GROUP BY 语句根据一个或多个列对结果集进行分组。
//在分组的列上可以使用 COUNT, SUM, AVG,等函数。
select user_name,count(*) from user where group by user_name; --按名字分组,统计每个每个名字有多少
//使用with rollup,WITH ROLLUP可以实现在分组统计数据基础上再进行相同的统计(SUM,AVG,COUNT…),
//1.使用count()统计时
select coalesce(user_name,"总数"),count("总数") from user group by user_name with rollup;
- 表连接
1.数据库在通过连接两张或多张表来返回记录时,都会生成一张 中间的临时表,然后再将这张临时表返回给用户
注意:这张临时表是数据库(MySQL自动生成)
//查询两个表相同的东西
select * from 表1,表2 where 表1.同属性=表2.同属性;
//inner join--内连接,获取两个表中字段匹配关系的记录(两个表的交集)。
select * from user u join sorts s on u.user_id=s.sort_id;
//left join--(左连接)获取左表所有记录,即使右表没有对应匹配的记录.(只显示左表的所有信息,以及交集)
select * from user u join sorts s on u.user_id=s.sort_id;
//right join--(右连接) 获取右表所有记录,即使左表没有对应匹配的记录。(只显示右表的所有信息,以及交集)
select * from user u join sorts s on u.user_id=s.sort_id;
//union操作符--(全连接),两个或两个以上的select的结果集组合成一个结果集
//distinct--删除结果集中重复的数据,all--返回结果集中所有数据(包括重复)
select * from 表名 union distinct select * from 表名;
- 导出表数据
select * from 表名 into outfile ’导出的物理地址‘;
三、 事务—用于处理操作量大,复杂度高的数据(MySql默认开启事务
SET AUTOCOMMIT=0 禁止自动提交
SET AUTOCOMMIT=1 开启自动提交
- 使用事务的条件
在 MySQL 中只有使用了 Innodb 数据库引擎 的数据库或表才支持事务
事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行
事务用来管理 insert,update,delete 语句 - 事务原则----ACID原则
原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。
一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。
隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。
持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。 - 事务控制语句
begin、start transaction 显示的开启一个事务
commit 提交事务(永久性修改)
rollback 事务回滚,撤销所有正在进行的所有未提交的修改
savepoint 保存点名 在事务中创建一个保存点
release savepoint 保存点名 删除一个事务保存点
rollback to 标记点名 把事务回滚到标记点
set transaction 设置事务的隔离级别。
读未提交:read uncommitted
读已提交:read committed
可重复读:repeatable read
串行化:serializable -
a.脏读,当前线程事务可以读取另一个线程事务未提交修改的数据。 b.不可重复读,事务提交前看到的数据不一致(别的线程修改提交); 线程1开启事务查询数据一个样,当线程2开启事务修改提交后,线程1再次查询发现数据修改(未提交),这就是不可重复读。 c.幻读, 可重复读级别通过MVCC机制保证事务提交前看到的数据都是一致的,但是又有一个新问题,当线程2修改完数据提交后,线程1看到的还是未修改前的原始数据,但实际底层数据已被更改,当线程1提交后发现数据改变,像幻觉一样,这就是幻读。 d.加锁读,SERIABLIZEBLE 为了解决幻读问题,当线程事务1查询数据,线程事务2修改数据会被锁住,因为数据具有不确定性。
//开始事务
begin;
insert into user(name,sex,age) values("西施","女",24);
//提交事务
commit
//开始事务
begin;
insert into user(name,sex,age) values("林黛玉","女",28);
//回滚
rollback;
四、索引–帮助mysql高效获取数据的数据结构(索引=>数据结构)
- 索引的分类
- 主键索引–primary key
唯一标识,主键不可重复 - 唯一索引–unique key
避免重复的列出现,唯一索引可以重复,多个列都可以标识为唯一索引 - 常规索引–key/index
默认的,index/key关键字来设置 - 全文索引–FullText
在特定的数据库引擎下才有,快速定位数据
- 索引的使用
- 在创建表的时候给字段添加索引
create table 表名(
列名 列类型 not null,
索引类型 属性名(列名);
) - 创建完表之后给字段添加索引
ALTER table 表名 ADD 索引类型 索引名(列名) - 创建索引
CREATE 索引类型 索引名 ON 表名(列名)
- 删除索引
alter table 表名 drop 索引类型 索引名
五、临时表–保存一些临时数据
- 临时表的创建—temporary
create temporary table 表名(
列名 列类型 ,
) - 临时表的删除
同删除普通表
六、复制表
CREATE TABLE 新表 LIKE 要复制的表;
INSERT INTO 新表 SELECT * FROM 要复制的表;
七、SQL注入问题
如果您通过网页获取用户输入的数据并将其插入一个MySQL数据库,那么就有可能发生SQL注入安全的问题。
防止SQL注入,我们需要注意以下几个要点:
1.永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和 双"-"进行转换等。
2.永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。
3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
4.不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。
5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
6.sql注入的检测方法一般采取辅助软件或网站平台来检测,软件一般采用sql注入检测工具jsky,网站平台就有亿思网站安全平台检测工具。MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防御SQL注入,XSS攻击等。
八、存储过程(写好一些sql直接调用)
概念:
-
存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。
-
存储过程是为了完成特定功能的SQL语句集,经编译创建并保存在数据库中,用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。
-
存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用。
- 创建存储过程
delimiter //
create procedure ccgc()
begin
select * from user;
end
//
delimiter ;
- 调用存储过程
call ccgc(); - 存储过程的变量
create procedure test()
begin
– 使用 declare语句声明一个变量
declare username varchar(32) default ‘’;
– 使用set语句给变量赋值
set username=‘lucy’;
– 将users表中id=1的名称赋值给username
select name into username from users where id=1;
– 返回变量
select username;
end; - 存储过程的条件、循环、函数等语句。。。。。。。。
九、触发器
- 概念
-
触发器是一种特殊类型的存储过程,它不同于存储过程,主要是通过事件触发而被执行的,即不是主动调用而执行的;而存储过程则需要主动调用其名字执行
-
触发器:trigger,是指事先为某张表绑定一段代码,当表中的某些内容发生改变(增、删、改)的时候,系统会自动触发代码并执行。
- 作用
- 可在写入数据前,强制检验或者转换数据(保证护数据安全)
- 触发器发生错误时,前面用户已经执行成功的操作会被撤销,类似事务的回滚
- 创建触发器
create trigger 触发器名字 触发时间 触发事件 on 表 for each row
begin
-- 触发器内容主体,每行用分号结尾
end
eg:
delimiter // --这里更改结束符号是为了避免 下面的语句报错
create trigger user_trigger after insert on user_age for each row
begin
update user set age=age-1 where id=1;
end
//
delimiter ;
- on 表 for each:触发对象,触发器绑定的实质是表中的所有行,因此当每一行发生指定改变时,触发器就会发生
-
触发时间
当 SQL 指令发生时,会令行中数据发生变化,而每张表中对应的行有两种状态:数据操作前和操作后before:表中数据发生改变前的状态
after:表中数据发生改变后的状态
PS:如果 before 触发器失败或者语句本身失败,将不执行 after 触发器(如果有的话)
5. 触发事件
- 触发器是针对数据发送改变才会被触发,对应的操作只有
INSERT
DELETE
UPDATE - 注意事项
在 MySQL 5 中,触发器名必须在每个表中唯一,但不是在每个数据库中唯一,即同一数据库中的两个表可能具有相同名字的触发器
每个表的每个事件每次只允许一个触发器,因此,每个表最多支持 6 个触发器,before/after insert、before/after delete、before/after update
- 查看触发器
show triggers; - 触发触发器
执行创建触发器时定义的事件 - 删除触发器
drop trigger 触发器名称; - 触发器应用
- 触发器针对的是数据库中的每一行记录,每行数据在操作前后都会有一个对应的状态,触发器将没有操作之前的状态保存到 old 关键字中,将操作后的状态保存到 new 中