MySql拓展

目录

 

1  分区及分表

http://blog.csdn.net/yongchao940/article/details/55266603

1.1 横向分区与纵向分区

1.2 分区的内在涵义

1.3 分区的常见语句及注意事项

1.4  分区和索引

1.5  MySQL分表

2 binlog

2.1 binlog

2.2 binlog开启

2.3 binlog试用

2.4 实践

3 锁

4 基本操作

4.1 修改字段列排序

4.2 replace into与 insert into ... on duplicate key update

5 存储

6. 问题


1  分区及分表

http://blog.csdn.net/yongchao940/article/details/55266603

1.1 横向分区与纵向分区

横向:记录分

纵向:字段分

1.2 分区的内在涵义

1.2.1 分区意义

首先MYISAM、InnoDB都是支持分区的。

1. 表非常大以至于无法全部都放到内存,或者只在表的最后部分有热点数据,其他均为历史数据

2. 分区表数据更容易维护(可独立对分区进行优化、检查、修复及批量删除大数据可以采用drop分区的形式等)

3. 分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备

4. 分区表可以避免某些特殊的瓶颈(ps: InnoDB的单个索引的互斥访问、ext3文件系统的inode锁竞争等) 5、可以备份和恢复独立的分区,非常适用于大数据集的场景、

5. 进行大数据搜索的时候可以进行并行处理

6. 跨多个磁盘分散数据查询,来获得更大的查询吞吐量。

1.2.2 分区物理存储

对应MySQL三个文件的具体情况.

分区在逻辑上是一个表,但是实际上却可以由多个物理分区组成。在执行查询的时候,和优化器会根据分区定义过滤出我们需要数据的分区,无须全表扫描。删除数据的时候同样的道理,效率也是非常的高。

1.3 分区的常见语句及注意事项

1.3.1 注意事项  

http://lobert.iteye.com/blog/1955841

http://www.simlinux.com/2014/08/19/mysql-partitions.html

范围分区添加分区只能在最大值后面追加分区

 比如 现在已经有了如下分区

 

 

p0

5

p1

10

p2

15

1.  分区值必须是严格递增的。如上图,那么插入 alter table orders_range add partition(partition p3 values less than (12));是无法插入成功的。

因此如果我们在程序中有 alter table orders_range add partition(partition p3 values less than MAXVALUE);

2. 此时需要添加分区,需要先删除max对应的分区,然后再添加我们需要的分区

3. 如果我们最后一个分区是[10,15),那么我们插入的值>=15都是插入不进去的,会报错。

4. 所有分区的engine必须一样

5.  分区间隔必须是int,分区名称不能以数字开头  这个导致我们ETL中 preload删除分区无法形成这种语法。只能借用delete删除数据

6. less than 表示分割区间是 [ )形式

7. 如果表上有主键或唯一索引列,range方式分区必须加入 https://www.zhihu.com/question/21738216  

每个分区值上都有独立的索引。 一般原则就是分区列必作为索引。

分区表的索引只是在各个底层表各自加上一个完全相同的索引。之于存储引擎,分区表的底层表与普通表没有区别。

 

8. null对分区主键的影响?

 

9 MySQL中插入换行

直接插入\n 或者通过char(13)的形式,

一般比如 concat_ws('\n',a,b,c)或者 concat_ws(char(13),a,b,c)

 

 

1.3.2 分区操作

1 查看分区

代码块

Plain Text

SELECT PARTITION_NAME,TABLE_ROWS FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 'table_name';

2 添加分区

代码块

Plain Text

alter table orders_range add partition(partition p5 values less than (25));alter table orders_range add partition(partition p5 values less than MAXVALUE);

note:在create语句中没有进行分区的相关定义,也可以可以添加分区的。

代码块

Plain Text

*可以对现有表进行分区,并且会按規则自动的将表中的数据分配相应的分区 
中,这样就比较好了,可以省去很多事情,看下面的操作*/  
mysql> alter table aa partition by RANGE(id)  
 -> (PARTITION p1 VALUES less than (1),  
 -> PARTITION p2 VALUES less than (5),  
 -> PARTITION p3 VALUES less than MAXVALUE);  
Query OK, 15 rows affected (0.21 sec)   //对15数据进行分区  
Records: 15  Duplicates: 0  Warnings: 0  

3 删除分区

note: 批量删除分区

alter table xx drop drop partition  p17177,p17178;

这种带有数字的直接用Excel拖动生成就行了

note:

多表记录级联删除,在一些orm中直接配置级联就可以删除,单纯的数据库而言也是可以的

DELETE FROM tablename [WHERE CONDITION]

delete from emp where ename='dony';

一次删除多个表的数据,语法如下:
delete t1,t2 from table_name as t1 left join table2_name as t2 on t1.id=t2.id where table_name.id=25

4 其他操作

1.4  分区和索引

从本质来说就是两个东西,没有什么本质的关系

但是从效果来说,都能加快查询的速度。但是在修改表(包括但不限于删除)层面上,分区的效率优势就体现出来了。尤其是在表非常大的情况下。

##

1.5  MySQL分表

1.5.1 分表和分区的区别

http://blog.51yip.com/mysql/949.html

1.5.2 索引

1 首先连接字段,在连接的两个表中的字段类型一致比不一致效率高一点,但是不明显,最起码在200w数据量的情况下是不明显的。 note: in(23,225)这种情况就会走range索引

2  count(*)比sum(*)的效率高一点,但是在200w+数据量的情况下只有0.0xs的优势,也是很不明显

3  复合主键在索引层面,就相当于联合索引,也是符合在最左前缀原则

4 索引失效情况

### 从左到右,遇到范围查询即索引失效(in不包括在内)。

范围查询其实可以做进一步的细化区分,in更加细化的描述应该是多值精确匹配, between则是范围查询。

### 隐式类型转换

http://tomhjx.github.io/2016/01/03/MYSQL%E7%B4%A2%E5%BC%95%E5%A4%B1%E6%95%88%E7%9A%84%E5%90%84%E7%A7%8D%E6%83%85%E5%BD%A2%E6%80%BB%E7%BB%93/

 

mysql隐士类型转换坑较多,不要使用隐士类型转换。

note:隐式类型转换还有一个查询匹配的大坑

当字段是string类型的时候,查询条件为 int 0的时候,会匹配上字段中以字符开头的记录

 

关于隐式转换的规则,

  • 当查询字段是INT类型,如果查询条件为CHAR,将查询条件转换为INT,如果是字符串前导都是数字将会进行截取,如果不是转换为0。

  • 当查询字段是CHAR类型,如果查询条件为INT,将查询字段为换为INT再进行比较,可能会造成全表扫描。示例2的name字段为CHAR类型,第一句查询转换为INT时都等于0,所以全部匹配了;第二句查询同为CHAR类型不发生转换,所以仅匹配值为0的记录。

https://blog.eood.cn/mysql_params

 

 

2 binlog

2.1 binlog

2.1.1 日志文件

http://www.cnblogs.com/martinzhang/p/3454358.html

MySQL的二进制日志记录了所有的DDL和DML(除了数据查询语句)语句,以事件形式记录,

还包含语句所执行的消耗的时间,MySQL的二进制日志是事务安全型的。

一般来说开启二进制日志大概会有1%的性能损耗(参见MySQL官方中文手册 5.1.24版)。

二进制有两个最重要的使用场景:

其一:MySQL Replication在Master端开启binlog,Mster把它的二进制日志传递给slaves来达到master-slave数据一致的目的。

其二:自然就是数据恢复了,通过使用mysqlbinlog工具来使恢复数据。 二进制日志包括两类文件:二进制日志索引文件(文件名后缀为.index)用于记录所有的二进制文件,二进制日志文件(文件名后缀为.00000*)记录数据库所有的DDL和DML(除了数据查询语句)语句事件。

2.1.2 日志文件的扩展

当停止或重启时,服务器会把日志文件记入下一个日志文件,Mysql会在重启时生成一个新的日志文件,文件序号递增,此外,如果日志文件超过max_binlog_size系统变量配置的上限时,也会生成新的日志文件。

2.1.3 日志文件的查看

Mysql提供了mysqlbinlog命令来查看日志文件,如mysqlbinlog xxx-bin.001 | more。在记录每条变更日志的时候,日志文件都会把当前时间给记录下来,以便进行数据库恢复。

2.1.4 日志文件格式

statement格式简单来说会记录下执行的SQL语句,为了保证日志能够恢复或者同步数据,在记录下执行SQL的过程中,还必须记录下上下文环境。但并不是所有的语句statement都能记录,比如udf,没有使用order by的limit 还有其他的一些函数和存储过程。

但是只记录执行的sql语句,一般在整表修改或者alter的时候数据量会比row格式小得多

row格式会记录下变更后的数据,但是不用记录上下文。详细记录了数据修改细节。因为如果碰到alter Table之类的语句会导致所有修改后的记录都会被记录(包括没有修改的列),导致日志数据量非常大。但是不用记录

http://www.cnblogs.com/kevingrace/p/6065088.html

note:公司的许多库使用的都是statement。

MySQL 5.7.7 之后默认格式是row之前使用的是statement。

 

2.2 binlog开启

https://xcoder.in/2015/08/10/mysql-binlog-try/

http://www.cnblogs.com/EasonJim/p/7158466.html

http://blog.5ibc.net/p/122608.html

http://www.jianshu.com/p/2c8325f0d393

2.3 binlog试用

使用mysql bin目录下的mysqlbinlog命令查看bin ./mysqlbinlog /usr/local/var/mysql/mysql-bin.000001文件,如下图所示

 

2.4 实践

2.4.1  max_binlog_cache_size溢出

http://liuqunying.blog.51cto.com/3984207/1751687

https://my.oschina.net/u/2485991/blog/533123

note:

max_binlog_size  一般设置为512M或1GB,但不能超过1GB。该设置不能严格控制Binlog的大小,尤其是Binlog遇到比较大的事务时,为了保证事务的完整性,不可能做切换日志的动作,只能将该事务的所有SQL都记录进当前日志,直到事务结束。这种情况下回出现日志文件大小超过设定值的情况。

binlog_cache_size 这个默认32k,公司里有1m的也有64M的

max_binlog_cache_size  一个线程来了会按照binlog_cache_size分配cache,不够的会用临时文件,对于一个多事务的任务,max_binlog_cache_size会控制所有的事务总的binlog_cache_size的大小。这个值不会超过4G

show variables like '%binlog_size%'; 该命令查出来的大小的值的单位是bytes

http://blog.csdn.net/m48o8gewuc/article/details/72888092

2.4.2  在row模式下查看原生sql

公司的show variables like 'binlog_rows_query_log_events';也是打开的

http://blog.csdn.net/mchdba/article/details/52268615

2.4.3 业务库大表在线修改表结构:

基本原理是生成中间表,复制数据,最后删除中间表。中间的过程并不总是会复制数据,如果复制数据会导致非常耗时,极有可能会导致锁表。

具体过程??

3 锁

可以从引擎和读/写/行/表 这两个维度来对MySQL的锁进行分析。

redo&undo https://my.oschina.net/guol/blog/156682

4 基本操作

4.1 修改字段列排序

字段增加和修改语法(ADD/CNAHGE/MODIFY)中,都有一个可选项 first|after
column_name,这个选项可以用来修改字段在表中的位置,默认 ADD 增加的新字段是加在表的最后位置,而 CHANGE/MODIFY 默认都不会改变字段的位置。

alter table emp add birth date after ename; (alter table emp add birth date after ename,add hah after birth,add hab after hah;)可以一次增加多个列指定顺序。

alter table emp modify age int(3) first; 修改字段 age,将它放在最前面

查询顺序? 不带任何限制的查询,

https://www.zhihu.com/question/19726583

这种有很多影响因素,一般结果会是查询顺序,但是不能依赖于这个(并不一定总是查询顺序)。

 

字段增加和修改语法(ADD/CNAHGE/MODIFY)中,都有一个可选项 first|after
column_name,这个选项可以用来修改字段在表中的位置,默认 ADD 增加的新字段是加在表的最后位置,而 CHANGE/MODIFY 默认都不会改变字段的位置。

alter table emp add birth date after ename;

alter table emp modify age int(3) first; 修改字段 age,将它放在最前面

4.2 replace into与 insert into ... on duplicate key update

replace into 相当于有重复key的情况下,会先删除旧的记录,然后添加一条新的记录。没有replace的字段则会以默认值填充。

insert into on....则是只会修改涉及的字段,没有涉及修改的字段还是保留原记录的内容。

http://blog.csdn.net/mchdba/article/details/8647560

5 存储

5.1之后就是compact格式,

  1. 减少了大约20%的空间

  2. 在某些操作下会增加CPU的占用

  3. 在典型的应用场景下,比Redundant快
    compress用在varchar特别长,或者blob资源比较多的场景。

6. 问题

mysql不支持正则替换功能,

不支持删除分区的非等

不支持窗口函数,但是MySQL有自己的语法来实现窗口功能。

建表语句:auto_increament=xx 表示自增数字的起点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值