当前位置: 首页 > article >正文

MySQL基础快速复习及高级语法学习

文章目录

  • 一、DDL复习
    • 1.1 创建、查询、删除、修改当前库
    • 1.2 数据类型
    • 1.3 创建表
    • 1.4 查看表
    • 1.5 表维护
  • 二、DML复习
    • 2.1 刨析表数据新增
    • 2.2 刨析表数据的修改以及删除
    • 2.3 中文乱码问题
  • 三、DQL复习及项目实战
    • 3.1 where条件查询
    • 3.2 group by分组查询
    • 3.3 having条件查询(筛选)
    • 3.4 order by排序查询(排序)
    • 3.5 limit限制查询(限制)
    • 3.6 exists型子查询
    • 3.7 左连接查询与右连接查询
    • 3. 8 内连接查询与联合查询
    • 5.9 项目高级查询实战
  • 四、DCL数据控制操纵语句
    • 4.1 mysql限制root用户指定ip登录
    • 4.2 用户密码
    • 4.3 mysql实战系列之创建新用户并限制ip网段登录
    • 4.4 mysql实战系列之库表权限授权与回收
  • 五、mysql的核心知识之事务实战,视图,触发器,以及存储过程
    • 5.1 事务的详细解析
    • 5.2 事务实战
    • 5.4 视图的应用
    • 5.5触发器介绍
    • 5.6 存储过程介绍
  • 六、索引与存储引擎的介绍
    • 6.1 存储引擎介绍
    • 6.2 常用索引
    • 6.3 普通索引与唯一索引
      • 1、什么是普通索引(index)?
      • 2、什么是唯一索引(unique)?
      • 3、创建百万级别的SQL表
      • 4、创建索引
      • 5、主键索引
      • 6. 全文索引
      • 7、外键约束剖析
      • 8、联合索引
  • 七、sql语句优化思路
    • 7.1 mysql的慢查询日志开启与问题定位
    • 7.2 sql语句执行过程解析
    • 7.3 mysql语句优化的几个小建议
  • 八、mysql数据安全核心知识之备份技能
    • 8.1 mysql数据安全之备份的背景意义
    • 8.2 mysql数据安全之备份的介绍
    • 8.3 mysql数据安全之mysqldump备份实例(跨机器)
    • 8.4 mysql数据安全之mysql数据的恢复
    • 8.5 mysql数据安全之物理备份
    • 8.6 mysql数据安全之利用二进制日志mysqlbinlog备份数据
    • 8.7 mysql数据安全之利用二进制日志mysqlbinlog恢复数据


一、DDL复习

1.1 创建、查询、删除、修改当前库

# 创建数据库
create database xiaoming;

# 判断是否存在 如果不存在直接创建
create database xiaoming if not exists xiaoming;

# 创建数据库并指定字符集为gbk
create database xiaoming defult character set gbk;

# 查看某个库是什么字符集
show create database xiaoming;

# 查看当前mysql使用的字符集
show variables like "character%";

# 查看有哪些库
show databases;

# 查看当前库
select database();

# 删除当前库
drop database xiaoming;

# 修改库名称
alter database 数据库名称 character set 字符集名称;

1.2 数据类型

整数型

类型大小
TINYINT-128到127或者0到255
SMALLINT2-32768到32767或者0到65535
MEDIUMINT中等大小的整数类型
INT 或者 INTEGER-2147483648到2147483647或者0到4294967295
BIGINT大的整数类型,存储范围更大

浮点型

类型大小
CHAR定长字符串类型,适合存储长度固定的字符串
VARCHAR变长字符串类型,适合存储长度可变的字符串

浮点型和定点型

类型大小
FLOAT单精度浮点数类型
DOUBLE双精度浮点数类型
DECIMAL 或者 NUMERIC用来存储定点或精确数值的数据类型

日期和时间类型

类型大小
DATA只包含日期
TIME只包含时间
DATETIME包含日期和时间
TIMESTAMP也包含日期和时间,但是会自动管理时间戳

二进制和字节串类型

类型大小
BLOB二进制大对象类型,可以存储图像、视频等二进制数据
TINYBLOB小的二进制大对象类型
MEDIUMBLOB中等大小的二进制大对象类型
LONGBLOB大的二进制大对象类型

1.3 创建表

约束条件

类型说明
comment说明解释
not null不能为空
default默认值
unsigned无符号
auto_increment自增
zerofill自动填充
unique key唯一值

创建表实例

create table database {
	字段名1 字段类型1 约束条件1 说明1,
	字段名2 字段类型2 约束条件2 说明2,
	字段名3 字段类型3 约束条件3 说明3......
}
create table student (
	id TINYINT unsigned not null comment "学号",
	name varchar(20) not null comment "姓名",
	age TINYINT default null comment "年龄",
	class varchar(20) not null comment "班级",
	sex char(5) not null comment "性别"
	);
# 复制表结构 where 1=2就是为了只复制表结构 不复制数据
create table teacher as select * from student where 1=2

create table teacher like student;

1.4 查看表

# 查看当前库所有表
show tables;

# 查看某个表
select * from table;

# 查看表结构
desc table;

# 返回创建指定表的SQL语句  \G:有结束sql语句的作用
show create table student\G

# 删除当前表
drop table student;

1.5 表维护

# 修改表名
rename table student to user;

# 添加列
alter table user add addr varchar(50);
alter table user add family varchar(50) comment '学生父母';

# 在某个位置添加列
alter table user add job varchar(10) first;
alter table user add servnumber int(10) after id;

# 修改列类型
alter table user modify servnumber varchar(20);

# 修改列名
alter table user change servnumber telephone varchar(20);

# 删除列
alte table user drop family;

# 修改字符集
alter table user character set GBK;

# 表删除
drop table if exists teacher;

二、DML复习

2.1 刨析表数据新增

新建一个表

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(字段对应值);

示例

insert into employee (empno,ename,job,mgr,hiredate,sal,deptnu) values ('1000','小明','经 理','10001','2019-03-03','12345.23','10');

insert into employee values ('1001','小明','经理','10001','2019-03-03','12345.23','10');

蠕虫复制(将一张表的数据复制到另一张表中)

insert into 新表1 select * from 新表2

insert into 表名1(字段名1,字段名2select 字段名1,字段名2 from 表名2;

insert into emp(ename, ejob) select (ename, ejob) from employee;

建表复制

create table 表名1 as select 字段名1,字段名2 from 表名2;

creat table emp as select ename, ejob from employee;

一次性插入多个数据

insert into (字段名) values (对应值1),(对应值2),(对应值3);

2.2 刨析表数据的修改以及删除

创建表并插入两段数据

CREATE TABLE employee( 
empno INT(5) unsigned zerofill auto_increment 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 employee (ename,job) values ('小明','文员');
insert into employee (ename,job) values ('小明','文员'),('小红','行政');

在这里插入图片描述

修改表

update 表名 set 字段名1=1 where 字段名=; 
update 表名 set 字段名1=1,字段名2=2 where 字段名=;

update employee set sal='999.999' ,mgr='1000', hiredate='2020-02-09' where empno='00001';

删除表数据

delete from 表名 where 字段名=; 
truncate table 表名; delete from 表名; 
drop table 表名;

delete from employee where empno='00002';

delete删除数据
在这里插入图片描述
truncate删除数据
在这里插入图片描述

删除速度

drop > truncate > delete

注意事项

  • 面试时:面试官问在删改数据之前,你会怎么做?

答案:会对数据进行备份操作,以防万一,可以进行数据回退

  • 面试时:面试官会问,delete与truncate与drop 这三种删除数据的共同点都是删除数据,他们的不同点是什么?
  1. delele 会把删除的操作记录给记录起来,以便数据回退,不会释放空间,而且不会删除定义
  2. truncate不会记录删除操作,会把表占用的空间恢复到最初,不会删除定义
  3. drop会删除整张表,释放表占用的空间

2.3 中文乱码问题

查看当前mysql使用的字符集

show variables like 'character%';


在这里插入图片描述

character_set_client:客户端请求数据的字符集
character_set_connection:客户端与服务器连接的字符集
character_set_database:数据库服务器中某个库使用的字符集设定,如果建库时没有指明,将默认使用配置
上的字符集
character_set_results:返回给客户端的字符集(从数据库读取到的数据是什么编码的)
character_set_server:为服务器安装时指定的默认字符集设定。
character_set_system:系统字符集(修改不了的,就是utf8)
character_sets_dir:mysql字符集文件的保存路径

临时修改

set names gbk;

在这里插入图片描述
永久:修改配置文件my.cnf里边的

[client] 
default-character-set=gbk 
作用于外部的显示 

[mysqld] 
character_set_server=gbk 
作用于内部,会作用于创建库表时默认字符集

修改库的字符集编码

alter database xiaoxiao default character set gbk;

修改表的字符集编码

alter table employee default character set utf8;

三、DQL复习及项目实战

3.1 where条件查询

首先创建表

/*创建部门表*/
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 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(code)或者count(*)
 select count(*) from employee;
 select count(ename) from employee;
 sum()  计算总和 
select sum(sal) from employee;
 max()    
计算最大值
select * from employee where sal= (select  max(sal) from employee);
 avg()   
计算平均值
select avg(sal) from employee;
 min()   
计算最低值
select * from employee where sal= (select  min(sal) from employee);
 concat函数: 起到连接作用
select concat(ename,' 是 ',job) as aaaa from employee;

在这里插入图片描述

3.2 group by分组查询

  • 作用:把行 按 字段 分组
  • 语法:group by 列1,列2…列N
  • 适用场合:常用于统计场合,一般和聚合函数连用
select deptnu,count(*) from employee group by deptnu; 
select deptnu,job,count(*) from employee group by deptnu,job;
select job,count(*) from employee group by job;

在这里插入图片描述

3.3 having条件查询(筛选)

  • 作用:对查询的结果进行筛选操作
  • 语法:having 条件 或者 having 聚合函数 条件
  • 适用场合:一般跟在group by之后
select job,count(*) from employee group by job having job ='文员'; select deptnu,job,count(*) from employee group by deptnu,job having count(*)>=2; select deptnu,job,count(*) as 总数 from employee group by deptnu,job having 总数>=2;

在这里插入图片描述

3.4 order by排序查询(排序)

  • 作用:对查询的结果进行排序操作
  • 语法:order by 字段1,字段2 …
  • 适用场合:一般用在查询结果的排序

顺序:where ---- group by ----- having ------ order by

select deptnu,job,count(*) from employee group by deptnu,job having count(*) >= 2 order by deptnu desc;
select deptnu,job,count(*) from employee group by deptnu,job having count(*) >= 2 order by deptnu asc;
select sal from employee order by sal desc;
select * from employee order by sal;

在这里插入图片描述
在这里插入图片描述

3.5 limit限制查询(限制)

  • 作用:对查询结果起到限制条数的作用
  • 语法:limit n,m
    1、 n:代表起始条数值,不写默认为0
    2、 m代表:取出的条数
  • 适用场合:数据量过多时,可以起到限制作用
select * from employee limit 4;
select * from employee limit 3,7;

在这里插入图片描述

3.6 exists型子查询

  • exists型子查询后面是一个受限的select查询语句
  • exists子查询,如果exists后的内层查询能查出数据,则返回 TRUE 表示存在;为空则返回 FLASE则不存在
分为俩种:existsnot exists 
select 1 from employee where 1=1; 
select * from 表名 a where exists (select 1 from 表名2 where 条件); 

eg:查询出公司有员工的部门的详细信息 
select * from dept a where exists (select 1 from employee b where a.deptnu=b.deptnu); 
select * from dept a where not exists (select 1 from employee b where a.deptnu=b.deptnu);

在这里插入图片描述

3.7 左连接查询与右连接查询

左右连接的用法以及应用场景

  • 左连接称之为左外连接 右连接称之为右外连接 这俩个连接都是属于外连接
  • 左连接关键字:left join 表名 on 条件 / left outer 表名 join on 条件
  • 右连接关键字:right join 表名 on 条件/right outer 表名 join on 条件
  • 左连接说明: left join 是left outer join的简写,左(外)连接,左表(a_table)的记录将会全部表示出来, 而右表
    (b_table)只会显示符合搜索条件的记录。右表记录不足的地方均为NULL
  • 右连接说明:right join是right outer join的简写,与左(外)连接相反,右(外)连接,左表(a_table)只会显示符合
    搜索条件的记录,而右表(b_table)的记录将会全部表示出来。左表记录不足的地方均为NULL
 select a.dname, b.* from dept a left join employee b on a.deptnu=b.deptnu;

在这里插入图片描述

select emp.*, d.dname from employee emp right join dept d on emp.deptnu=d.deptnu; 

在这里插入图片描述

3. 8 内连接查询与联合查询

  • 内连接:获取两个表中字段匹配关系的记录
  • 主要语法:INNER JOIN 表名 ON 条件;
select empno from employee emp where emp.job = '销售员' union select hiredate from employee emp where job = '文员';

在这里插入图片描述

select * from employee emp where emp.job = '销售员' union select * from employee emp where job = '文员';

在这里插入图片描述

#对销售员的工资从低到高排序,而文员的工资从高到低排序
(select * from employee emp where emp.job = '销售员' order by emp.sal limit 999) union (select * from employee emp where job = '文员'order by emp.sal desc limit 999);

在这里插入图片描述
注意事项

  1. 两个select语句的查询结果的“字段数”必须一致;
  2. 通常,也应该让两个查询语句的字段类型具有一致性;
  3. 也可以联合更多的查询结果
  4. 用到order by排序时,需要加上limit(加上最大条数就行),需要对子句用括号括起来

5.9 项目高级查询实战

1. 查出至少有一个员工的部门。显示部门编号、部门名称、部门位置、部门人数

分析:
涉及 员工 部门表

select deptnu,count(*) from employee group by deptnu; 

在这里插入图片描述

2. 列出薪金比安琪拉高的所有员工

select sal from employee where ename='安琪拉';
select * from  employee where sal > (select sal from employee where ename='安琪拉');

在这里插入图片描述

3. 列出所有员工的姓名及其直接上级的姓名

select a.ename,b.ename from employee a left join employee b on a.mgr=b.empno;

在这里插入图片描述

4. 列出受雇日期早于直接上级的所有员工的编号、姓名、部门名称
在这里插入图片描述

5. 列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门

select a.dname,b.* from dept a left join employee b on a.deptnu=b.deptnu;

在这里插入图片描述

6. 列出所有文员的姓名及其部门名称,所在部门的总人数

涉及表:employee dept 
条件:job='文员' 
语句:select deptnu,count(*) as zongshu from employee group by deptnu; 
语句:select b.ename,a.dname,b.job,c.zongshu from dept a ,employee b ,(select deptnu,count(*) as zongshu from employee group by deptnu) c where a.deptnu=b.deptnu and b.job='文员' and b.deptnu=c.deptnu;

在这里插入图片描述

7. 列出最低薪金大于15000的各种工作及从事此工作的员工人数

select job, count(*) from employee group by job having min(sal) > 15000;

在这里插入图片描述

8. 列出在销售部工作的员工的姓名,假定不知道销售部的部门编号
在这里插入图片描述

9. 列出与诸葛亮从事相同工作的所有员工及部门名称

select a.ename,b.dname from employee a,dept b where a.deptnu=b.deptnu and a.job= (select job from employee where ename = '诸葛亮');

在这里插入图片描述

10. 列出薪金比 在部门30工作的员工的薪金 还高的员工姓名和薪金、部门名称

select max(sal) from employee where deptnu=30;
select a.ename,a.sal,b.dname from employee a ,dept b where a.deptnu=b.deptnu and sal > (select max(sal) from employee where deptnu=30);

在这里插入图片描述

11. 列出每个部门的员工数量、平均工资

select deptnu,count(*),avg(sal) from employee group by deptnu;

在这里插入图片描述

12. 列出薪金高于公司平均薪金的所有员工信息,所在部门名称,上级领导,工资等级

select avg(sal) from employee;
select a.*,c.dname,b.ename,d.grade from employee a,employee b,dept c ,salgrade d where a.mgr=b.empno and a.deptnu =c.deptnu and a.sal > (select avg(sal) from employee) and a.sal between d.lowsal and d.higsal;

在这里插入图片描述

四、DCL数据控制操纵语句

  • 什么是DCL数据控制语言?
    数据控制语言(DCL:Data Control Language)是用来设置或者更改数据库用户或角色权限的语句,这些语句
    包括GRANT、DENY、REVOKE等语句

4.1 mysql限制root用户指定ip登录

  • 查看root用户可以在哪台机器登录
select user,host from mysql.user where user='root';
  • 修改mysql库里边的user表
# 用来更新mysql.user表中的记录,将host字段设置为localhost,条件是user字段的值为root
UPDATE mysql.user SET host='localhost' WHERE user='root';
  • 刷新权限
flush privileges;

4.2 用户密码

  • 修改用户密码分三种方法:
  1. 第一种:使用 SET PASSWORD 语句
set password for 用户@ip = password('密码');

eg:
set password for root@localhost = password('root');
  1. 使用mysqladmin修改密码的方法
mysqladmin -u root -p old_password password new_password;

# 假设你想将root用户的密码改为newpass123,并且当前root用户的密码是currentpass,可以使用如下命令
mysqladmin -u root -p currentpass password newpass123

# 如果你不知道当前密码,但有root权限,可以直接输入:
mysqladmin -u root -p password newpass123
  1. 使用 UPDATE 语句直接修改 mysql.user 表

这种方法是最直接的,但也是最危险的,因为它直接修改了MySQL的内部用户表
一般不推荐这样做,但在某些特殊情况下可能会用到

UPDATE mysql.user SET authentication_string = PASSWORD('new_password') WHERE user = 'username' AND host = 'hostname';
  • 忘记密码
  1. 第一步:修改配置文件my.cnf (默认在/etc/my.cnf),在[mysqld]下面加上 skip-grant-tables (跳过权限的意
    思)
  2. 第二步:重启mysql服务
  3. 第三步:mysql -uroot -p 无需密码登录进入
  4. 第四步:修改密码

4.3 mysql实战系列之创建新用户并限制ip网段登录

创建用户

create user 'username'@'host' identified by 'password';

CREATE USER:这是创建新用户的命令
‘username’:这是新用户的用户名。用户名必须是唯一的,并且不能与现有的用户名冲突
‘host’:这是用户可以从哪个主机连接到MySQL服务器。host可以是具体的主机名(如’example.com’),也可以是通配符’%‘(表示任何主机),或者是’localhost’(表示本地主机)
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='pig'\G
show grants for 'pig'@'%';

在这里插入图片描述
删除用户

语法:
drop user 'username'@'host';

eg:
drop user 'pig'@'%';
delete from mysql.user where user='pig';

4.4 mysql实战系列之库表权限授权与回收

授权语法:grant 权限1,权限2..... on 数据库对象 to '用户'

grant 权限1,权限2..... on 数据库对象 to '用户'@'host' identified by 'password';

all privileges:代表所有权限
. :代表所有库所有表

对现有用户进行授权:对现有用户pig授予所有库所有表所有权限
grant all privileges on *.* to 'pig';
对没有的用户进行授权:
创建一个新用户dog授予WP库的所有权限,登录密码123456,任何一台主机登录 
grant all privileges on WP.* to 'dog'@'%' identified by '123456';
对没有的用户进行授权:
创建一个新用户cat授予WP库的employee表 查与修改权限,登录密码123456,任何一台主机登录
grant select,update on WP.employee to 'cat'@'%' identified by '123456'
对没有的用户进行授权:
对用户cat授予WP库的employee表insert 权限,登录密码123456,任何一台主机登录 
grant insert on WP.employee to 'cat'@'%' identified by '123456';
回收语法:revoke 权限1,权限2..... on 数据库对象 from '用户'@'host';
回收pig用户的所有权限(注意:并没有回收它的登录权限) 
revoke all privileges on *.* from 'pig' @ '%'; flush privileges;
回收pig用户的所有权限(并回收它的登录权限) 
delete from mysql.user where user='pig'; flush privileges;
回收cat用户对WP库的employee的查与修改权限 
revoke select,update on WP.employee from 'cat'@'%'; flush privileges;

五、mysql的核心知识之事务实战,视图,触发器,以及存储过程

5.1 事务的详细解析

什么是事务?

数据库事务通常指对数据库进行读或写的一个操作过程。有两个目的,第一个是为数据库操作提供了一个从失败中恢复 到正常状态的方法,同时提供了数据库即使在异常状态下仍能保持一致性的方法;第二个是当多个应用程序在并发访问数据 库时,可以在这些应用程序之间提供一个隔离方法,以防止彼此的操作互相干扰

事务的特性(ACID):

  • 原子性(Atomicity):事务必须是原子工作单元,一个事务中的所有语句,应该做到:要么全做,要么一个都不做
  • 一致性(Consistency):让数据保持逻辑上的“合理性”,比如:小明给小红打10000块钱,既要让小明的账户减少10000,又要让小红的账户上增加10000块钱
  • 隔离性(Isolation):如果多个事务同时并发执行,但每个事务就像各自独立执行一样
  • 持久性(Durability):一个事务执行成功,则对数据来说应该是一个明确的硬盘数据更改(而不仅仅是内存中的变化)

5.2 事务实战

事务的开启与提交:

  • 事务的开启:begin; start transaction;
  • 事务的提交:commit;
  • 事务的回滚:rollback;

创建表

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;

插入数据

insert into account values ('1',('张三'),'80000');

在这里插入图片描述

开启autocommit(临时生效):
OFF(0):表示关闭 ON (1):表示开启

set autocommit=0;

show variables like 'autocommit';

set autocommit=1;
 
show variables like 'autocommit';

在这里插入图片描述

  • 开启autocommit(永久生效):
    修改配置文件:vi /etc/my.cnf 在[mysqld]下面加上:autocommit=1 记得重启服务才会生效

5.4 视图的应用

  • 什么是视图?视图的作用是什么?

视图(view)是一种虚拟存在的表,是一个逻辑表,它本身是不包含数据的。作为一个select语句保存在数据字典中的。 通过视图,可以展现基表(用来创建视图的表叫做基表base table)的部分数据,说白了视图的数据就是来自于基表

  • 视图的优点是:

1)简单:使用视图的用户完全不需要关心后面对应的表的结构、关联条件和筛选条件,对用户来说已经是过滤好的复合条件 的结果集
2)安全:使用视图的用户只能访问他们被允许查询的结果集,对表的权限管理并不能限制到某个行某个列,但是通过视图就 可以简单的实现
3)数据独立:一旦视图的结构确定了,可以屏蔽表结构变化对用户的影响,源表增加列对视图没有影响;源表修改列名,则 可以通过修改视图来解决,不会造成对访问者的影响
4)不占用空间:视图是逻辑上的表,不占用内存空间 总而言之,使用视图的大部分情况是为了保障数据安全性,提高查询效率

  • 视图的创建以及修改
创建的基本语法是: 
create view <视图名称> as select 语句; 
create view <视图名称> (字段) as select 语句; 
create or replace view <视图名称>;
修改的语法是: 
alter view <视图名称> as select 语句;
视图删除语法: 
drop view <视图名称> ;

在这里插入图片描述

  • 视图的缺点

1)性能差:sql server必须把视图查询转化成对基本表的查询,如果这个视图是由一个复杂的多表查询所定义,那么,即 使是视图的一个简单查询,sql server也要把它变成一个复杂的结合体,需要花费一定的时间
2)修改限制:当用户试图修改试图的某些信息时,数据库必须把它转化为对基本表的某些信息的修改,对于简单的试图来说,这是很方便的,但是,对于比较复杂的试图,可能是不可修改的

5.5触发器介绍

  • 什么是触发器?

触发器就是监视某种情况,并触发某种操作

  • 创建触发器的语法:
create trigger 触发器名称 after/before insert/update/delete on 表名 
for each row 
begin 
sql语句; 
end
  • 删除触发器的语法:
drop trigger 触发器名称;

5.6 存储过程介绍

  • 什么是存储过程?

存储过程就是把复杂的一系列操作,封装成一个过程。类似于shell,python脚本等。

  • 存储过程的优缺点

优点是:
1)复杂操作,调用简单
2)速度快


缺点是:
1)封装复杂
2) 没有灵活性

  • 创建存储过程语法:
create procedure 名称 (参数....) 
begin 
过程体; 
过程体; 
end

参数:
in|out|inout 参数名称 类型(长度)
in:表示调用者向过程传入值(传入值可以是字面量或变量)
out:表示过程向调用者传出值(可以返回多个值)(传出值只能是变量)
inout:既表示调用者向过程传入值,又表示过程向调用者传出值(值只能是变量)

  • 声明变量:declare 变量名 类型(长度) default 默认值;
  • 给变量赋值:set @变量名=值;
  • 调用存储命令:call 名称(@变量名);
  • 删除存储过程命令:drop procedure 名称;
  • 查看创建的存储过程命令:show create procedure 名称\G;

六、索引与存储引擎的介绍

6.1 存储引擎介绍

  • 什么是数据库存储引擎?

数据库引擎是数据库底层软件组件,不同的存储引擎提供不同的存储机制,索引技巧,锁定水平等功能,使用不同的数据库 引擎,可以获得特定的功能

  • 如何查看引擎
# 查看当前数据库支持引擎
show engines;

在这里插入图片描述

# 建表时指定的引擎
create table yinqin (id int, name varchar(20)) engine='InnoDB';

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/5e14adc50b4347689

# 查看当前库所有表的引擎:
show table status;

在这里插入图片描述

#修改表的引擎
alter table 表名 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

6.2 常用索引

  • 什么是索引?

索引是一个单独的,存储在磁盘中上的数据库结构,它们包含着对数据表里的所有记录的引用指针。使用索引可以快速的找 出在某列或多列中有特定值的行

  • 索引的优点:

通过创建唯一索引,来保证数据库表中的每一行数据的唯一性
可以加快数据的检索速度
可以保证表数据的完整性与准确性

  • 索引的缺点:

索引需要占用物理空间
对表中的数据进行改动时,索引也需要跟着动态维护,降低了数据的维护速度

  • 索引的常见类型:

index:普通索引
unique:唯一索引
primary key:主键索引
foreign key:外键索引
fulltext: 全文索引
组合索引

6.3 普通索引与唯一索引

1、什么是普通索引(index)?

普通索引(index)顾名思义就是各类索引中最为普通的索引,主要任务就是提高查询速度。其特点是允许出现相同的索引内容,允许空(null)值

2、什么是唯一索引(unique)?

唯一索引:(unique)顾名思义就是不可以出现相同的索引内容,但是可以为空(null)值

3、创建百万级别的SQL表

  1. 使用虚拟机安装一个数据库 快速为自己安装一个虚拟机
  2. 创建百万级别的SQL 到/home目录下创建一个目录,eg:Demo —》 进入Demo再创建一个目录,mkdir test —》 vi test.sh —》 输入
#!/bin/bash 

echo "请输入字段servnumber的值:" 
read serber 
echo "请输入创建sql语句的数量:" 
read number 

# char=`head /dev/urandom | tr -dc 0-9 | head -c 11` 

for (( i=0;i<$number;i++ )) 
	do
	pass=`head /dev/urandom | tr -dc a-z | head -c 8` 
	let serber=serber+1 
	echo "insert into test(id,username,servnumber,password,createtime) values('$i','user${i}','${serber}','$pass',now());" >>sql.txt 

done

—》执行shell脚本:sh test.sh —》创建一个test库,并创建一个表

create table test ( 
	id int(7) zerofill auto_increment not null, 
	username varchar(20), 
	servnumber varchar(30), 
	password varchar(20), 
	createtime datetime, 
	primary key (id) 
)DEFAULT CHARSET=utf8;

—》进行插数操作:source /home/Demo/sql.txt

在这里插入图片描述

4、创建索引

  • 创建表的时候创建
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;
  • 直接为表添加索引
语法:
alter table 表名 add index 索引名称 (字段名称); 

eg: 
alter table test add unique unique_username (username);

在这里插入图片描述

  • 直接创建索引
语法:
create index 索引 on 表名 (字段名);
 
eg:
create index index_createtime on test (createtime);

在这里插入图片描述

  • 查看索引
语法:
show index from 表名\G 

eg:
show index from test\G

在这里插入图片描述

  • 如何删除索引
语法:
drop index 索引名称 on 表名;

eg:
drop index unique_username on test;

在这里插入图片描述

5、主键索引

  • 什么是主键索引?

把主键添加索引就是主键索引,它是一种特殊的唯一索引,不允许有空值,而唯一索引(unique是允许为空值的)。指定 为“PRIMARY KEY”

主键:主键是表的某一列,这一列的值是用来标志表中的每一行数据的
注意:每一张表只能拥有一个主键

  • 创建主键:
1)创建表的时候创建 

2)直接为表添加主键索引 
语法:
alter table 表名 add primary key (字段名);
 
eg:alter table test add primary key (id);

在这里插入图片描述

  • 删除主键:
语法: 
alter table 表名 drop primary key; 
eg: alter table test drop primary key; 

注意:在有自增的情况下,必须先删除自增,才可以删除主键 

删除自增:alter table test change id id int(7) unsigned zerofill not null;

在这里插入图片描述

6. 全文索引

  • 什么是全文索引?

全文索引是将存储在数据库中的文章或者句子等任意内容信息查找出来的索引,单位是词。全文索引也是目前搜索引擎 使用的一种关键技术。指定为 fulltex

  • 创建练习表的sql:
create table command ( 
id int(5) unsigned primary key auto_increment, 
name varchar(10), 
instruction varchar(60) 
)engine=MyISAM;
  • 插入数据
insert into command values('1','ls','list directory contents'); 
insert into command values('2','wc','print newline, word, and byte counts for each file'); 
insert into command values('3','cut','remove sections from each line of files'); 
insert into command values('4','sort','sort lines of text files'); 
insert into command values('5','find','search for files in a directory hierarchy'); 
insert into command values('6','cp','复制文件或者文件夹'); 
insert into command values('7','top','display Linux processes'); 
insert into command values('8','mv','修改文件名,移动'); 
insert into command values('9','停止词','is,not,me,yes,no ...');

在这里插入图片描述

  • 添加全文索引
    1.创建表的时候创建全文索引
    2.通过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');
  • 停止词(is not ):
出现频率很高的词,将会使全文索引失效
  • in boolean mode 模式:
in boolean mode:意思是指定全文检索模式为布尔全文检索(简单可以理解为是检索方式) 

select * from 表名 where match (字段名) against ('检索内容' in boolean mode);
  • 注意点:
使用通配符*时,只能放在词的后边,不能放前边
  • 删除全文索引:
alter table command drop index instruction;
  • 注意点总结:

1、一般情况下创建全文索引的字段数据类型为 char、varchar、text 。其它字段类型不可以
2、全文索引不针对非常频繁的词做索引。比如is,no,not,you,me,yes这些,我们称之为停止词
3、对英文检索时忽略大小写

7、外键约束剖析

  • 什么是外键?

外键就是作用于两个表数据之间的链接的一列或多列,用来保证表与表之间的数据的完整性和准确性

  • 添加外键约束:
语法:foreign key (字段名) references 关联的表名(关联表的字段名) 

注意:主键跟外键的字段类型一定要相同

create table的方法: 

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的方法: 
alter table employee add foreign key (deptnu) references dept(deptnu);

在这里插入图片描述
在有外键约束的情况下,deptnu输入不准确,是无法插入的
在这里插入图片描述

  • 删除外键约束:

注意:在干掉外键索引之前必须先把外键约束删除,才能删除索引

mysql> alter table employee drop index deptnu; 
ERROR 1553 (HY000): Cannot drop index 'deptnu': needed in a foreign key constraint 
mysql> 
mysql> alter table employee drop foreign key employee_ibfk_1; 
Query OK, 0 rows affected (0.01 sec) 
Records: 0 Duplicates: 0 Warnings: 0 

mysql> 
mysql> alter table employee drop index deptnu; 
Query OK, 0 rows affected (0.01 sec) 
Records: 0 Duplicates: 0 Warnings: 0
  • 注意点总结:

(1)俩个表,主键跟外键的字段类型一定要相同
(2)要使用外键约束表的引擎一定得是InnoDB引擎,MyISAM是不起作用的
(3)在干掉外键索引之前必须先把外键约束删除,才能删除索引

8、联合索引

  • 什么是联合索引?

联合索引又称组合索引或者复合索引,是建立在俩列或者多列以上的索引

  • 怎么来创建联合索引?
alter table 表名 add index(字段1,字段2,字段3); 

alter table test add index(username,servnumber,password);
  • 怎么删除联合索引?
alter table test drop index username;
  • 为什么要使用联合索引,而不使用多个单列索引?

联合索引的效率远远高于单列索引

  • 注意点总结:

索引并非越多越好,过多的索引会增加数据的维护速度还有磁盘空间的浪费
当表的数据量很大的时候,可以考虑建立索引
表中经常查数据的字段,可以考虑建立索引
想要保证表中数据的唯一性,可以考虑建立唯一索引
想要保证俩张表中的数据的完整性跟准确性,可以考虑建立外键约束
经常对多列数据进行查询时,可以考虑建立联合索引

七、sql语句优化思路

7.1 mysql的慢查询日志开启与问题定位

  • 第一步:查询是否已经开启了慢查询
show variables like 'slow%';

在这里插入图片描述

  • 第二步:开启慢查询日志
set global slow_query_log = on;

日志路径也可以自定义:
set global slow_query_log_file = '路径';

在这里插入图片描述

  • 第三步::查看慢查询的时间临界值—》设置慢查询的时间标准
set ong_query_time = 0.2;

在这里插入图片描述

7.2 sql语句执行过程解析

介绍如何开启性能详情

  • 第一步:查看性能是否开启
show variables like '%profiling%';
  • 第二步:开启性能记录功能
set  profiling = on ;
  • 第三步:查看性能记录
show profiles;
  • 第四步:查看语句的执行性能详情
 show profile for query 4;

在这里插入图片描述

在这里插入图片描述

7.3 mysql语句优化的几个小建议

介绍日常工作应该尽量避免的sql语句

  • 第一个注意点:

尽量避免使用select *from ,尽量精确到想要的结果字段

  • 第二个注意点:

尽量避免条件使用or

  • 第三个注意点:

记得加上limit 限制行数,避免数据量过大消耗性能

  • 第四个注意点:

使用模糊查询时,%放在前面是会使索引失效
在这里插入图片描述

  • 第五个注意点:

要小心条件字段类型的转换

八、mysql数据安全核心知识之备份技能

8.1 mysql数据安全之备份的背景意义

  • 数据备份的意义:

(1)保护数据的安全;
(2)在出现意外的时候(硬盘的损坏,断电,黑客的攻击),以便数据的恢复;
(3)导出生产的数据以便研发人员或者测试人员测试学习;
(4)高权限的人员操作失误导致数据丢失,以便恢复;

8.2 mysql数据安全之备份的介绍

  • 数据库的备份类型:

(1)完全备份:对整个数据库的数据进行备份
(2)部分备份:对部分数据进行备份(可以是一张表也可以是多张表)
增量备份:是以上一次备份为基础来备份变更数据的,节约空间
差异备份:是以第一次完全备份的基础来备份变更备份的,浪费空间

  • 数据库备份的方式:

(1)逻辑备份:直接生成sql语句保存起来,在恢复数据的时候执行备份的sql语句来实现数据的恢复
(2)物理备份:直接拷贝相关的物理数据


区别:
逻辑备份效率低,恢复数据效率低,但是逻辑备份节约空间;
物理备份浪费空间,但是相对逻辑备份而言效率比较高

  • 数据库备份的场景:

(1)热备份:备份时,数据库的读写操作不会受到影响
(2)温备份:备份时,数据库的读操作可以进行,但是写操作不能执行
(3)冷备份:备份时,不能进行任何操作

8.3 mysql数据安全之mysqldump备份实例(跨机器)

  • mysqldump使用语法:
mysqldump -u 用户 -h host -p 密码 dbname table > 路径
  • 远程备份单库例子:
mysqldump -uroot -pabc123456 -h192.168.111.100 zabbix | gzip > /mysql_data_back/zabbix_users.sql.gz
  • 远程备份多库的例子:
mysqldump -uroot -pabc123456 -h192.168.111.100 --databases zabbix xiaoli | gzip > /mysql_data_back/zabbix_xiaoli.sql.gz
  • 远程备份全库的例子:
mysqldump -uroot -pabc123456 -h192.168.111.100 --all-databases | gzip > /mysql_data_back/all.sql.gz

8.4 mysql数据安全之mysql数据的恢复

  • 远程恢复数据(备份的数据文件里有创建库的语句):
mysql -uroot -pabc123456 -h192.168.111.100 < zabbix_bak.sql
  • 远程恢复数据(备份的数据文件里没有创建库的语句):
mysql -uroot -pabc123456 -h192.168.111.100 zabbix < zabbix_bak.sql

8.5 mysql数据安全之物理备份

  • 看找数据库源文件路径(一):
show variables like 'datadir%';

-在这里插入图片描述

  • 看找数据库源文件路径(二):
cat /etc/my.cnf
  • MyISAM表源文件:

db.opt:创建库的时候生成,主要存储着当前库的默认字符集和字符校验规则
frm :记录着表结构信息的文件
MYI:记录着索引的文件
MYD :记录着表的数据

  • InnoDB表源文件:InnoDB有着共享表空间跟独立表空间的概念

db.opt:创建库的时候生成,主要存储着当前库的默认字符集和字符校验规则
frm :记录着表结构信息的文件
ibd :独立表空间,里边记录这个表的数据和索引
ibdata1:共享表空间,里边记录表的数据和索引

  • 请求全局读锁:
flush tables with read lock;
  • 解锁:
unlock tables;

8.6 mysql数据安全之利用二进制日志mysqlbinlog备份数据

  • 什么是二进制日志:

二进制日志就是记录着mysql数据库中的一些写入性操作,比如一些增删改,但是,不包括查询!

  • 二进制日志有哪些功能:

一般情况下,二进制日志有着数据复制和数据恢复的功能

  • 注意:

开启二进制日志会有1%的性能消耗!

  • 查看二进制日志是否开启:
show variables like 'log_bin%';
  • 开启二进制日志 : vi /etc/my.cnf

在这里插入图片描述

  • 查看所有的binlog日志列表:
show master logs;

在这里插入图片描述

  • 刷新二进制日志:
flush logs;
  • 重置(清空)二进制日志文件:
PURGE BINARY LOGS BEFORE 'date';

PURGE BINARY LOGS BEFORE NOW();

8.7 mysql数据安全之利用二进制日志mysqlbinlog恢复数据

  • 把二进制日志文件导出成普通文件:
mysqlbinlog --base64-output=DECODE-ROWS -v mysql-bin.000002 > mysqlbin.sql

mysqlbinlog:这是MySQL提供的命令行工具,用于解析二进制日志文件
–base64-output=DECODE-ROWS:此选项指示mysqlbinlog在解析二进制日志时对Base64编码的数据进行解码。这对于处理包含Base64编码数据的二进制日志非常有用,因为直接解析Base64编码的数据通常难以阅读
-v:此选项增加输出的详细程度,使得输出的信息更加详细
mysql-bin.000002:这是您要解析的二进制日志文件的名称
mysqlbin.sql:将命令的输出重定向到mysqlbin.sql文件中

  • 找出要恢复的位置
找出关键字的行数:
mysqlbinlog --no-defaults mysql-bin.000002 | cat -n | grep -iw 'drop'
  • mysqlbinlog --no-defaults mysql-bin.000002:
    1.mysqlbinlog:MySQL提供的命令行工具,用于解析二进制日志文件
    2.–no-defaults:此选项表示不使用默认的选项文件。这可以防止mysqlbinlog从配置文件中读取额外的选项,从而避免潜在的配置冲突
    3.mysql-bin.000002:指定要解析的二进制日志文件

  • |:管道符|将前一个命令的标准输出作为下一个命令的标准输入

  • cat -n:
    cat:用于连接和打印文件内容。这里使用-n选项来为输出的每一行加上行号

  • |:
    再次使用管道符|将cat -n的输出传递给下一个命令

  • grep -iw ‘drop’:
    1.grep:用于从文本中搜索匹配指定模式的行
    2.-i:表示忽略大小写
    3.-w:表示全词匹配,即确保匹配的是完整的单词,而不是单词的一部分
    4.‘drop’:指定要搜索的模式(关键字)

打印出相关内容:
mysqlbinlog --no-defaults mysql-bin.000002 | cat -n | sed -n '4170,4180p'
  • 恢复数据:
    第一步:把备份的数据表user恢复到数据库中:mysql -uroot -p xiaoli < /mysql_data_back/user_bak.sql
    第二步:利用上面找到的删除的位置进行恢复数据
mysqlbinlog --no-defaults --set-charset=utf8 --stop-position="59674" /usr/local/mysql/data/log_bin/mysql-bin.000002 | mysql -uroot -p

http://www.kler.cn/a/368908.html

相关文章:

  • 设计模式(二)
  • Autosar 启动过程-基于ETAS工具
  • (7) cuda异常处理
  • Python中的递归函数是如何工作的,它有哪些应用场景?
  • Linux 进程间通信_匿名管道
  • opencv-platform实现人脸识别
  • Maven入门到进阶:构建、依赖与插件管理详解
  • 在项目中如何实现 Redis 分布式锁?
  • Golang | Leetcode Golang题解之第506题相对名次
  • 【React系列五】—React学习历程的分享
  • C# OOP面试题精选 面向新手/SOLID原则/设计模式++ 长期更新
  • 为什么在网络中不能直接传输数据
  • Linux 文件权限管理:chown、chgrp 和 chmod 的使用及权限掩码规则
  • 高效集成钉钉报销到金蝶付款单的技术实现
  • CSRF 点击劫持
  • 摊牌了,创业失败了
  • python实战(二)——房屋价格回归建模
  • WebSocket学习笔记
  • Kafka之消费者客户端
  • 多模态大模型(MLLM)中的Connector
  • 机器学习与金融风控项目篇-day04-卡方分箱案例与模型的可解释性
  • 使用SQL在PostGIS中创建各种空间数据
  • 极狐GitLab 17.5 发布 20+ 与 DevSecOps 相关的功能【二】
  • ArcGIS计算多个面要素范围内栅格数据各数值的面积
  • NLP自然语言处理中的Attention机制原理揭秘
  • 创新业态下金融头部机构在 FICC 平台建设上的思考与实践