教程使用 社区版mysql 5.7
安装MySQL 5.7 j教程
<1>整数型
类型 | 大小 | 范围(有符号) | 范围(无符号unsigned) | 用途 |
---|---|---|---|---|
TINYINT | 1 字节 | (-128,127) | (0,255) | 小整数值 |
SMALLINT | 2 字节 | (-32768,32767) | (0,65535) | 大整数值 |
MEDIUMINT | 3 字节 | (-8388608,8388607) | (0,16777215) | 大整数值 |
INT | 4 字节 | (-2147483648,2147483647) | (0,4294967295 | 大整数值 |
BIGINT | 8 字节 | () | (0,2的64次方减1) | 极大整数值 |
<2>浮点型
类型 | 大小 | 名称 | |
---|---|---|---|
FLOAT(m,d) | 4 字节 | 单精度浮点型 | 备注:m代表总个数,d代表小数位个数 |
DOUBLE(m,d) | 8 字节 | 双精度浮点型 | 备注:m代表总个数,d代表小数位个数 |
<3>定点型
类型 | 大小 | |
---|---|---|
DECIMAL(m,d) | 依赖于M和D的值 | 存的是什么就是什么 |
<4>字符串类型
类型 | 大小 | 用途 |
---|---|---|
CHAR | 0-255字节 | 定长字符串 |
VARCHAR | 0-65535字节 | 变长字符串 |
TINYTEXT | 0-255字节 | 短文本字符串 |
TEXT | 0-65535字节 | 长文本数据 |
MEDIUMTEXT | 0-16777215字节 | 中等长度文本数据 |
LONGTEXT | 0-4294967295字节 | 极大文本数据 |
char的优缺点:存取速度比varchar更快,但是比varchar更占用空间
varchar的优缺点:比char省空间。但是存取速度没有char快
<5>时间型
类型 | 大小 | 格式 | 用途 |
---|---|---|---|
date | 3 | yyyy-MM-dd | 存储日期值 |
time | 3 | HH:mm:ss | 存储时分秒 |
year | 1 | yyyy | 存储年 |
datetime | 8 | yyyy-MM-dd HH:mm:ss | 存储日期+时间 |
timestamp | 4 | yyyy-MM-dd HH:mm:ss | 存储日期+时间,可作时间戳 |
操作语句分为4类:
创建库
# 普通创建
create database xiaoming;
# 判断数据库是否存在,如果不存在则创建
create database if not exists xiaoming;
# 创建数据库并制定字符集
create database xiaoming default character set UTF-8;
查看库
# 进入/切换库
use 库名
# 查看所有库
show databases;
# 查看当前库
select database();
# 查询库的创建信息
show create database xiaoming;
删除库
drop database xiaoming;
创建表
# 语法:
CREATE TABLE 表名 (
字段名1 字段类型1 约束条件1 约束条件5 说明1,
字段名2 字段类型2 约束条件2 说明2,
字段名3 字段类型3 约束条件3 说明3
);
# 约束条件:
not null ----不为空
default ----默认值
unsigned ----无符号(即正数,默认都是有符号的)
auto_increment ----自增
zerofill ----自动填充
unique key ----唯一值
comment -----注释/说明
# eg.
create table student (
id tinyint(5) zerofill auto_increment comment '学生学号', # 00001
name varchar(20) default null comment '姓名',
age tinyint not null comment '年龄',
class varchar(20) not null comment '班级',
sex char(5) not null comment '性别'
);
复制表
# 只复制表结构 但不会复制主键信息
create table teacher as select * from where 1=2;
# 复制表结构+表信息
create table teacher as select * from where 1=1;
# 完全复制表结构
create table teacher like student;
删除表
drop table 表名 ;
drop table if exists 表名;
查看表信息
# 查看当前库所有表
show tables;
# 查看表结构
desc 表名 ;
# 查看创建表的语句 (\G美化,省略分号)
show create table student\G
表结构的维护和删除
# 修改表名
rename table 旧表名 to 新表名;
# 修改字符集
alter table 表名 character set 字符集;
# 添加列
alter table add 列名 类型 comment '说明';
# 最前面添加一列
alter table 表名 add 列名 类型 first;
# 某个字段后添加一列
alter table 表名 add 列名 类型 after 字段名;
# 修改列类型
alter table 表名 modify 列名 新类型;
# 修改列名
alter table 表名 change 旧列名 新列名 类型;
# 删除列
alter table 表名 drop 列名;
# 创建公司的员工表,下面学习笔记会用到
CREATE TABLE employee(
empno INT PRIMARY KEY comment '雇员编号',
ename VARCHAR(20) comment '雇员姓名',
job VARCHAR(20) comment '雇员职位',
mgr INT comment '雇员上级编号',
hiredate DATE comment '雇佣日期',
sal DECIMAL(7,2) comment '薪资',
deptnu INT comment '部门编号'
);
向表中插入数据
# 如果省略字段名,字段对应值,必须全。
insert into 表名 (字段名) values (字段对应值);
# eg.
insert into employee (empno,ename,job,mgr,hiredate,sal,deptnu) values ('1000','小明','经理','10001','2019-03-03','12345.23','10');
# 一次性插入多组数据
insert into 表名 (字段名) values (对应值1),(对应值2),(对应值3);
复制表内所有信息
# 复制表employee结构 名为emp
create table emp like employee;
# 蠕虫复制 将一张表的数据复制到另一张表中
# 复制数据
insert into emp select * from employee;
# 复制数据只复制某些字段
insert into emp (empno,ename) select empno,ename from employee;
# 建表复制
create table 表名1 as select 字段名1,字段名2 from 表名2;
# 修改数据
update 表名 set 字段名1=值1 where 字段名=值;
update 表名 set 字段名1=值1,字段名2=值2 where 字段名=值;
# 删除数据
delete from 表名 where 字段名=值;
# 删除整张表
truncate table 表名;
delete from 表名; # 不加条件 会删除表内所有数据
drop table 表名;
区别:
drop 表会被删除
delete 会把删除的操作记录给记录起来,以便数据回退,不会释放空间,而且不会删除定义
truncate不会记录删除操作,会把表占用的空间恢复到最初,不会删除定义
删除速度:
drop > truncate > delete
创建以下几个表,为我们提供练习操作
/*创建部门表*/
CREATE TABLE dept(
deptnu INT PRIMARY KEY comment '部门编号',
dname VARCHAR(50) comment '部门名称',
addr VARCHAR(50) comment '部门地址'
);
某个公司的员工表
CREATE TABLE employee(
empno INT PRIMARY KEY comment '雇员编号',
ename VARCHAR(50) comment '雇员姓名',
job VARCHAR(50) comment '雇员职位',
mgr INT comment '雇员上级编号',
hiredate DATE comment '雇佣日期',
sal DECIMAL(7,2) comment '薪资',
deptnu INT comment '部门编号'
)ENGINE=MyISAM DEFAULT CHARSET=utf8;
/*创建工资等级表*/
CREATE TABLE salgrade(
grade INT PRIMARY KEY comment '等级',
lowsal INT comment '最低薪资',
higsal INT comment '最高薪资'
);
/*插入dept表数据*/
INSERT INTO dept VALUES (10, '研发部', '北京');
INSERT INTO dept VALUES (20, '工程部', '上海');
INSERT INTO dept VALUES (30, '销售部', '广州');
INSERT INTO dept VALUES (40, '财务部', '深圳');
/*插入emp表数据*/
INSERT INTO employee VALUES (1009, '唐僧', '董事长', NULL, '2010-11-17', 50000, 10);
INSERT INTO employee VALUES (1004, '猪八戒', '经理', 1009, '2001-04-02', 29750, 20);
INSERT INTO employee VALUES (1006, '猴子', '经理', 1009, '2011-05-01', 28500, 30);
INSERT INTO employee VALUES (1007, '张飞', '经理', 1009, '2011-09-01', 24500,10);
INSERT INTO employee VALUES (1008, '诸葛亮', '分析师', 1004, '2017-04-19', 30000, 20);
INSERT INTO employee VALUES (1013, '林俊杰', '分析师', 1004, '2011-12-03', 30000, 20);
INSERT INTO employee VALUES (1002, '牛魔王', '销售员', 1006, '2018-02-20', 16000, 30);
INSERT INTO employee VALUES (1003, '程咬金', '销售员', 1006, '2017-02-22', 12500, 30);
INSERT INTO employee VALUES (1005, '后裔', '销售员', 1006, '2011-09-28', 12500, 30);
INSERT INTO employee VALUES (1010, '韩信', '销售员', 1006, '2018-09-08', 15000,30);
INSERT INTO employee VALUES (1012, '安琪拉', '文员', 1006, '2011-12-03', 9500, 30);
INSERT INTO employee VALUES (1014, '甄姬', '文员', 1007, '2019-01-23', 7500, 10);
INSERT INTO employee VALUES (1011, '妲己', '文员', 1008, '2018-05-23', 11000, 20);
INSERT INTO employee VALUES (1001, '小乔', '文员', 1013, '2018-12-17', 8000, 20);
/*插入salgrade表数据*/
INSERT INTO salgrade VALUES (1, 7000, 12000);
INSERT INTO salgrade VALUES (2, 12010, 14000);
INSERT INTO salgrade VALUES (3, 14010, 20000);
INSERT INTO salgrade VALUES (4, 20010, 30000);
INSERT INTO salgrade VALUES (5, 30010, 99990);
普通查询
# 简单查询
select * from 表;
select 字段1,字段2,字段3 as 字段3别名 from 表;
# 精确查询
select * from employee where ename='后裔';
select * from employee where sal != 50000;
select * from employee where sal <> 50000;
select * from employee where sal > 10000;
# 模糊条件查询
show variables like '%aracter%';
select * from employee where ename like '林%';
# 范围查询
select * from employee where sal between 10000 and 30000;
select * from employee where hiredate between '2011-01-01' and '2017-12-1';
# 离散查询
select * from employee where ename in ('猴子','林俊杰','小红','小胡');
# 清除重复
select distinct(job) from employee;
统计查询(聚合函数)
# count 统计条数
select count(*) from employee;
select count(ename) from employee;
# sum 求和
select sum(sal) from employee;
# max() 计算最大值
select max(sal) from employee;
select * from employee where sal= (select max(sal) from employee);
# min() 计算最低值
select * from employee where sal= (select min(sal) from employee);
# avg() 计算平均值
select avg(sal) from employee;
# concat 起到连接作用, aaa -> "唐僧 是 董事长"
select concat(ename,' 是 ',job) as aaaa from employee;
# 按deptnu部门编号分组,显示部门编号和每个部门编号下有多少员工
select deptnu,count(*) from employee group by deptnu;
# 按职位分组,每个岗位多少员工
select job,count(*) from employee group by job;
# 按照部门+职位分组,并计算这种分组下有多少员工
select deptnu,job,count(*) from employee group by deptnu,job;
一般都是和 聚合函数
和 group by
合用
对查询的结果筛选操作,一般跟在group by
后面
# group by 中练习的 (按职位分组,每个岗位多少员)
select job,count(*) from employee group by job
# 上述基础上,只查询文员,或者叫 筛选出文员
select job,count(*) from employee group by job having job ='文员';
# 部门+职位 下的员工 >= 2人的
select deptnu,job,count(*) from employee group by deptnu,job having count(*)>=2;
# having 后面不使用count(*),使用别名
select deptnu,job,count(*) as 总数 from employee group by deptnu,job having 总数>=2;
select deptnu,job,count(*) as 总数 from employee group by deptnu,job having 总数>=2 order by deptnu;
顺序:where ---- group by ----- having ------ order by
查询结果 限制条数
语法: limit n,m
n代表 起始位置,不写默认0
m代表取出条数
select * from xiaoming.employee limit 4,5;
select * from 表名 a where exists (select 1 from 表名2 where 条件);
# 括号内的查询语句,如果查询为空 exists前的语句不执行,返回空
# 如果括号内查询语句有结果,则正常执行前面的语句。
# 是用select 1 ,查询到结果返回True,空则返回False
not exists 则相反
它们都属于 外连接
# 简写 | 完整写法
left join 表名 on 条件 | left outer 表名 Join on 条件
right join 表名 on 条件 | right outer 表名 Join on 条件
连接查询首先要有 两张表
左连接: 以左表为准,全部显示取来,右表显示符合搜索条件的记录,没有的用null补
右连接:同理,以右表为基准
# 列出部门名称和这些部门的员工信息,同时列出那些没有的员工的部门
select a.dname,b.* from dept a left join employee b on a.deptnu=b.deptnu;
select b.dname,a.* from employee a right join dept b on b.deptnu=a.deptnu;
获取两个表中 字段匹配的记录(条件)
INNER JOIN 表名 ON 条件
# 想查出员工张飞部门的所在地址
select a.addr from dept a inner join employee b on\
a.deptnu=b.deptnu and b.ename='张飞';
就是把多个查询语句的查询结果结合在一起
把多个查询结果 拼接成一张表(上下拼接)。
union 多个表必须字段一致
(select * from employee a where a.job = '销售员' \ order by a.sal limit 999999 )
union
(select * from employee b where b.job = '文员' \
order by b.sal desc limit 999999);
设置更改数据库用户,角色权限的语句。
myqsl 的用户表在 mysql.user表中
use mysql;
select user,host from user where user='root';
# host % 代表任何一台机器都可以登录
mysql -uroot -p # 连接的是localhost
mysql -uroot -h127.0.0.1 -p # 指定IP登录
# 更改允许的登录IP
update user set host='localhost' where user='root';
update mysql.user set host='localhost' where user='root';
# 刷新权限
flush privileges
# 修改用户密码
# 方法1. 数据库内执行
set password for 用户@IP = password('密码');
# 方法2 终端命令行
mysqladmin -u用户 -p旧密码 password 新密码
# 方法3 修改表
select * from user where user='root' \G;
#先查看密码的字段是什么,我的是 authentication_string
update mysql.user set authentication_string=password("123456") where user='root' ;
# 因为可能root有IP localhost多个,密码不同,所以where限制条件,最好再加上host,不然会更改全部root密码
如果忘记密码怎么办?
修改my.cnf (默认在/etc/my.cnf)
在[mysqld]下面加上 skip-grant-tables 跳过权限的意思
重启mysql服务,mysql -uroot -p 这时候无需密码登录进入
然后执行修改用户密码的操作即可。
# 语法
create user 'username'@'host' identified by 'password';
# 创建一个pig用户,并指定登录密码:123456,可以在任何一台远程主机都可以登录
create user 'pig'@'%' identified by '123456';
# 创建一个pig用户,并指定登录密码:为空,指定在120网段的机器登录
create user 'pig'@'120.%.%.%' identified by '';
# 查看创建的用户信息(包括权限)
select * from mysql.user where user='ping'\G
# 或者查看权限
show grants for 'pig'@'%';
USAGE: 无权限的意思
# 删除用户
drop user 'pig'@'host';
# 或者
delete from mysql.user where user='pig';
# 授权
grant 权限1,权限2..... on 数据库对象 to '用户'
grant 权限1,权限2..... on 数据库对象 to '用户'@'host' identified by 'password';
# 回收
revoke 权限1,权限2..... on 数据库对象 from '用户'@'host';
all privileges # 所有权限
select # 查询权限
update # 修改权限
insert # 添加权限
实战
# 授权实战例子
# 对现有用户进行授权:对现有用户pig授予所有库所有表所有权限。
grant all privileges on *.* to 'pig';
# 对没有的用户进行授权:创建一个新用户dog授予XD库的所有权限
# 登录密码123456,任何一台主机登录
grant all privileges on XD.* to 'dog'@'%' identified by '123456';
# 对没有的用户进行授权:创建一个新用户cat授予XD库的employee表 查与修改权限
# 登录密码123456,任何一台主机登录
grant select,update on XD.employee to 'cat'@'%' identified by '123456'
# 回收实战
# 回收pig用户的所有权限(注意:并没有回收它的登录权限)
revoke all privileges on *.* from 'pig' @ '%';
flush privileges;
# 回收pig用户的所有权限(并回收它的登录权限)
delete from mysql.user where user='pig';
flush privileges;
# 回收cat用户对XD库的employee的查与修改权限
revoke select,update on XD.employee from 'cat'@'%';
flush privileges;
# sql结束符号默认为; 修改为//
delimiter //
# 改回来
delimiter ;
事物的特性(ACID)
注意
: MySQL 5.7 innode
支持事物操作
事物开启 begin;
事物提交 commit;
事物回滚 rollback;
事物实战演习
# 创建一个账户表模拟转账,需要指定innodb引擎
create table account (
id tinyint(5) zerofill auto_increment not null comment 'id编号',
name varchar(20) default null comment '客户姓名',
money decimal(10,2) not null comment '账户金额',
primary key (id)
)engine=innodb charset=utf8;
# 开始事务
begin;
# 插入数据
insert into account values ("1","张三"."98000");
# 查询发现有数据
select * from account;
# 另外开一个窗口 ,再次查询,发现没有数据
# 因为执行插入命令的窗口内存中有,但是未提交,所以其他连接查询不到
# 当我们提交后,才能正常查询
# 如果我们回滚,两个都消失
自动提交 autocommit
# autocommit 默认为开启状态
# OFF(0):表示关闭
# ON (1):表示开启
# 临时关闭 autocommit
set autocommit=0;
# 查询设置
show variables like 'autocommit';
# 开启autocommit(永久生效):
# 修改配置文件:vi /etc/my.cnf 在[mysqld]下面加上:
autocommit=1
# 然后重启
# -------------------------------------------
autocommit 开启状态下为开启状态
update table set flag=1 where flag=3
与
update table set flag=1 where flag=3;
commit;
相同,
但是 如果手动begin,则也必须手动commit或roll
# -------------------------------------------
# autocommit设置为OFF后,事物并没有自动提交,则需要自己commit
update table set flag=1 where flag=3;
commit;
视图: 是虚拟存在的表,逻辑存在的表,作为一个select语句 保存在数据字典中。
视图优点:
简单 :使用视图的用户,不需要关心视图后面的表结构,关联关系和筛选条件
对用户来说已经是过滤好的复合条件的结果集
安全: 使用视图的用户只能访问他们被允许查询的结果集。
表的权限管理不能具体到 行和列,但是通过视图就可以简单的实现。
数据独立: 一旦视图的结构确定了,可以屏蔽表结构变化对用户的影响,
源表增加列对视图没有影响;
源表修改列名,则可以通过修改视图来解决,不会造成对访问者的影响。
不占空间: 视图是逻辑上的表,不占用内存空间.
视图的创建以及修改
# 创建的基本语法是:
# 如果视图存在会报错
create view <视图名称> as select 语句;
create view <视图名称> (字段) as select 语句;
# 如果存在就代替,没存在就创建
create or replace view <视图名称>;
# 修改的语法是:
alter view <视图名称> as select 语句;
# 视图删除语法:
drop view <视图名称> ;
# 创建一个视图
create view employ as select empno,ename,job,mgr,deptnufrom employee;
# show tables 视图也会被展示出来,把这个视图当作表用即可。
select * from employ;
视图的缺点:
性能差: 视图查询 --> 基表查询 这中间会有转换,所以会比直接查询基表消耗更多资源。
修改限制: 当用户试图修改试图的某些信息时,数据库必须把它转化为对基本表的某些信息的修改,
对于简单的试图来说,这是很方便的,但是,对于比较复杂的试图,可能是不可修改的。
触发器使用的不多,但还是要了解一下什么是触发器.
触发器简单来说就是监视某种情况,触发某种动作
# 触发器语法
create trigger 触发器名称 after/before insert/update/delete on 表名
for each row
begin
sql语句;
end
after/before
:可以设置为事件发生前或后
insert/update/delet
e:它们可以在执行insert、update或delete的过程中触发
for each row
:每隔一行执行一次动作
# 删除触发器的语法:
drop trigger 触发器名称;
触发器演练
# 创建一个员工迟到表:
create table work_time_delay(
empno int not null comment '雇员编号',
ename varchar(50) comment '雇员姓名',
status int comment '状态'
);
# 创建触发器
#
create trigger trig_work after insert on work_time_delay
-> for each row
-> begin
-> update employee set sal=sal-100 where empno=new.empno;
-> end
-> ;
# new: 指的是事件发生before或者after保存的新数据
存储过程就是一个数据库的脚本
存储过程就是把复杂的一系列操作,封装成一个过程。
使用后,分库分表几乎变成不可能
优点是:
1)复杂操作,调用简单
2)速度快
缺点是:
1)封装复杂
2) 没有灵活性
# 创建存储过程语法
create procedure 名称 (参数....)
begin
过程体;
过程体;# 可以多个
end
参数:in|out|inout 参数名称 类型(长度)
in:表示调用者向过程传入值(传入值可以是字面量或变量)
out:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)
inout:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)
声明变量:declare 变量名 类型(长度) default 默认值;
给变量赋值:set @变量名=值;
调用存储命令:call 名称(@变量名);
删除存储过程命令:drop procedure 名称;
查看创建的存储过程命令:show create procedure 名称\G;
例子
# 创建 存储过程
create procedure name(in n int )
begin
select * from employee limit n;
end;
# 赋值
set @n=5;
# 调用存储过程name
call name(@n)
# 在内部定义变量
create procedure name()
begin
declare n int default 6;
select * from employee limit n;
end
# 调用
call name()
数据库引擎是数据库底层软件组件
不同的存储引擎,可以获得特定的功能。
比如 引技巧,锁定水平等功能
数据库引擎是基于表
的
查看引擎
# 查看支持的引擎
show engines;
# 查看当前数据的引擎
show create table 表名\G
# 查看当前库所有表的引擎
show table status\G
引擎修改命令
# 创建表的时候指定引擎
create table yingqin (id int,name varchar(20)) engine='InnoDB';
# 修改表的引擎
alter table 表名 engine='MyiSAm';
# 修改默认引擎
# vi /etc/my.cnf
# [mysqld]下面 default-storage-engine=MyIsAM 然后重启
MyISAM与InnoDB的区别
MyISAM:
支持全文索引(full text);
不支持事务;
表级锁;
保存表的具体行数;
奔溃恢复不好
Innodb:
支持事务;
以前的版本是不支持全文索引,但在5.6之后的版本就开始支持这个功能了;
行级锁(并非绝对,当执行sql语句时不能确定范围时,也会进行锁全表例如: update table set id=3 where name like 'a%';);
不保存表的具体行数;奔溃恢复好
引擎选择
MyISAM:
• 一般来说MyISAM不需要用到事务的时候
• 做很多count计算
InnoDB:
• 可靠性要求高的,或者要求支持事务
• 想要用到外键约束的时候(讲外键的时候会讲)
推荐:
• 推荐用InnoDB
索引优点
索引缺点
常见索引
创建索引注意点
索引并非越多越好,过多的索引会增加数据的维护速度还有磁盘空间的浪费。
• 当表的数据量很大的时候,可以考虑建立索引。
• 表中经常查数据的字段,可以考虑建立索引。
• 想要保证表中数据的唯一性,可以考虑建立唯一索引。
• 想要保证俩张表中的数据的完整性跟准确性,可以考虑建立外键约束。
• 经常对多列数据进行查询时,可以考虑建立联合索引。
普通索引: index 主要任务就是提高查询速度。其特点是允许出现相同的索引内容,允许空(null)值
唯一索引: unique 顾名思义就是不可以出现相同的索引内容,但是可以为空(null)值
创建索引的方法
# 方法1
# 创建表的时候创建
create table test (
id int(7) zerofill auto_increment not null,
username varchar(20),
servnumber varchar(30),
password varchar(20),
createtime datetime,
unique (id)
)DEFAULT CHARSET=utf8;
# 方法2
# 直接为表添加索引
alter table 表名 add index 索引名称 (字段名称);
# eg. 注意:假如没有指定索引名称时,会以默认的字段名为索引名称
alter table test add unique unique_username (username);
# 方法3
# 直接创建索引
语法:create index 索引 on 表名 (字段名);
# eg.
create index index_createtime on test (createtime);
查看索引
show index from test\G
删除索引
drop index 索引名称 on 表名;
drop index unique_username on test;
alter table 表名 drop index 索引名;
alter table test drop index createtime;
PRIMARY KEY
主键: 每张表只能拥有一个主键,主键加索引就是主键索引。
它是一种特殊的唯一索引,不允许有空值,而唯一索引(unique是允许为空值的)
# 创建主键
# 1.创建表的时候创建
# 略
# 2.直接为表添加主键索引
alter table 表名 add primary key (字段名);
alter table test add primary key (id);
# 删除主键
alter table 表名 drop primary key;
# 如果主键为自增,需要先删除自增
alter table test change id id int(7) unsigned zerofill not null;
fulltex,全文索引
数据库储存文章和句子,查询内容的索引,单位是词
# 创建索引
# 创建表时候创建
create table command (
id int(5) unsigned primary key auto_increment,
name varchar(10),
instruction varchar(60),
fulltex(instruction)
)engine=MyISAM;
# 通过alter添加
alter table command add fulltext(instruction);
# 使用全文索引
select * from 表名 where match (字段名) against ('检索内容');
select * from command where match(instruction) against ('sections');
# 查看匹配度
select * from command where match(instruction) against ('directory');
# 删除全文索引
alter table command drop index instruction;
# 详细使用
https://www.cnblogs.com/tommy-huang/p/4483684.html
# 创建外键约束
foreign key (字段名) references 关联的表名(关联表的字段名)
# 创建表时候
CREATE TABLE `employee` (
`empno` int(11) NOT NULL COMMENT '雇员编号',
`ename` varchar(50) DEFAULT NULL COMMENT '雇员姓名',
`job` varchar(30) DEFAULT NULL,
`mgr` int(11) DEFAULT NULL COMMENT '雇员上级编号',
`hiredate` date DEFAULT NULL COMMENT '雇佣日期',
`sal` decimal(7,2) DEFAULT NULL COMMENT '薪资',
`deptnu` int(11) DEFAULT NULL COMMENT '部门编号',
PRIMARY KEY (`empno`),
foreign key (deptnu) references dept(deptnu)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
# 向表中添加
alter table employee add foreign key (deptnu) references dept(deptnu);
# 删除外键约束
# 需要先删除约束,然后再删除索引
# 查询外键 show create table 表名\G ,查看外键约束
alter table employee drop foreign key employee_ibfk_1;
alter table employee drop index deptnu;
# 注意
# 俩个表,主键跟外键的字段类型一定要相同
# 要使用外键约束表的引擎一定得是InnoDB引擎,MyISAM是不起作用的
# 在干掉外键索引之前必须先把外键约束删除,才能删除索引
复合索引 组合索引,多个索引。
# 添加
alter table 表名 add index(字段1,字段2,字段3);
alter table test add index(username,servnumber,password);
# 删除
alter table test drop index username;
# 联合索引的最左原则
# 1.查看是否已经开启了慢查询日志
show variables like 'slow%'
# 2.开启慢查询日志
set global slow_query_log = on ;
# 自定义日志路径
set global slow_query_log_file = '路径';
# 3.查看慢查询的时间临界值
show variables like '%long%';
# 4.设置慢查询的时间标准
set long_query_time=0.4;
# 重启服务, 设置会恢复到默认
# 永久设置后, 重启服务生效
[mysqld]
slow_query_log = 1
long_query_time = 0.1
slow_query_log_file =/usr/local/mysql/mysql_slow.log
# 执行查询
select * from test where servnumber="13670087879";
# 前面加上expain
expain select * from test where servnumber="13670087879" \G
# 查询性能详情是否开启
show variables like '%profiling%';
# 开启性能记录功能
set profiling = on ;
# 查询性能记录
show profiles;
# 查看语句的执行性能详情
show profile for query 4;
1.尽量避免使用select *from ,尽量精确到想要的结果字段
2.尽量避免条件使用or
3.记得加上limit 限制行数,避免数据量过大消耗性能
4.使用模糊查询时,%放在前面是会使索引失效
5.要小心条件字段类型的转换
数据备份类型
完全备份
部分备份
(1) 增量备份 以上一次为基础
(2) 差异备份 以一次完全备份为基础
数据备份方式
数据备份场景
mysqldump 数据逻辑备份 完全备份
# 数据量不是很大的时候,mysqldump就够了
mysqldump -u 用户 -h host -p 密码 dbname tbale > 路径
常用例子
# 远程备份单库例子
mysqldump -uroot -pabc123456 -h120.25.93.69 zabbix | gzip > /mysql_data_back/zabbix_users.sql.gz
# 远程备份单库例子并保留创建库语句
mysqldump -uroot -pabc123456 -h120.25.93.69 --databases zabbix | gzip > /mysql_data_back/zabbix_bak.sql.gz
# 远程备份单库单表的例子
mysqldump -uroot -pabc123456 -h120.25.93.69 zabbix users | gzip > /mysql_data_back/zabbix_users.sql.gz
# 远程备份多库的例子
mysqldump -uroot -pabc123456 -h120.25.93.69 --databases zabbix XD | gzip > /mysql_data_back/zabbix_XD.sql.gz
# 远程备份全库的例子
mysqldump -uroot -pabc123456 -h120.25.93.69 --all-databases | gzip > /mysql_data_back/all.sql.gz
恢复
# 远程恢复数据(备份的数据文件里有创建库的语句)
mysql -uroot -pabc123456 -h120.25.93.69 < zabbix_bak.sql
# 远程恢复数据(备份的数据文件里没有创建库的语句)
mysql -uroot -pabc123456 -h120.25.93.69 zabbix < zabbix_bak.sql
数据库源文件路径
# 查找数据库源文件路径(一)
show variables like 'datadir%';
# 查找数据库源文件路径(二)
cat /etc/my.cnf
数据库源文件
MyISAM表源文件
db.opt:创建库的时候生成,主要存储着当前库的默认字符集和字符校验规则
.frm :记录着表结构信息的文件
.MYI:记录着索引的文件
.MYD :记录着表的数据
InnoDB表源文件:InnoDB有着共享表空间跟独立表空间的概念。
db.opt:创建库的时候生成,主要存储着当前库的默认字符集和字符校验规则
.frm :记录着表结构信息的文件
.ibd :独立表空间,里边记录这个表的数据和索引
ibdata1:共享表空间,里边记录表的数据和索引
对于MyISAM,直接备份数据库文件夹即可
对于InnoDB,除了数据库文件夹,还需要备份 ib_logfile0
b_logfile1
ibdata1
Mysql上锁
# 请求全局读锁:
flush tables with read lock;
# 解锁
unlock tables;
二进制日志 记录着MySQL数据库的 增删改,不包含查询
可以利用二进制日志进行数据复制和恢复。
开启二进制日志会有1%的性能消耗!
查看二进制日志是否开启
show variables like 'log_bin%';
开启二进制日志 : vi /etc/my.cnf
[mysqld]
log-bin=/data/mydata/log_bin/mysql-bin
server-id=1
查看所有的binlog日志列表
mysql> show master logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 23638 |
+------------------+-----------+
刷新二进制日志:
flush logs;
重置(清空)二进制日志文件
mysql> show master logs;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 1091 |
+------------------+-----------+
使用mysqldump备份数据时,加上-F选项可以重新生成一个新的二进制日志文件
# 会使用mysqldump 备份数据库 XD.user表,并且重新生产一个文件002 记录二进制logbin文件
mysqldump -uroot -p XD user -F > user_bak.sql
mysqlbinlog mysql-bin.000002
# 如果报错
# 第一种:在mysqlbinlog 后边加上 --no-defaults
# 第二种:注释掉配置文件里边的default-character-set=utf8
# 把二进制日志文件导出成普通文件
mysqlbinlog --base64-output=DECODE-ROWS -v mysql-bin.000002 > mysqlbin.sql
# 找出关键字的行数 drop操作的行数
mysqlbinlog --no-defaults mysql-bin.000002 | cat -n | grep -iw 'drop'
4180 DROP TABLE `user` /* generated by server */
# 打印出相关内容
mysqlbinlog --no-defaults mysql-bin.000002 | cat -n | sed -n '4170,4180p'
# ----------------------------------------
4170 # at 59578
4171 #190419 0:41:48 server id 1 end_log_pos 59609 CRC32 0x36cda2b7 Xid = 6380
4172 COMMIT/*!*/;
4173 # at 59609
4174 #190419 0:41:48 server id 1 end_log_pos 59674 CRC32 0x8de2f06a Anonymous_GTID last_committed=145 sequence_number=146
4175 SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
4176 # at 59674
4177 #190419 0:41:48 server id 1 end_log_pos 59787 CRC32 0x6b2edd2b Query thread_id=14 exec_time=0 error_code=0
4178 use `XD`/*!*/;
4179 SET TIMESTAMP=1555605708/*!*/;
4180 DROP TABLE `user` /* generated by server */
# ----------------------------------------
# 把备份的数据表user恢复到数据库中
mysql -uroot -p XD < /mysql_data_back/user_bak.sql
# 利用上面找到的删除的位置进行恢复数据
mysqlbinlog --no-defaults --set-charset=utf8 --stop-position="59674" /data/mydata/log_bin/mysql-bin.000002 | mysql -uroot -p