MySql表分区详解,2024年最新jvm性能优化面试题

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

*

from
information_schema
.partitions

where
table_schema

database
(
)

and

table_name

‘t’

G

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

row

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

TABLE_CATALOG
:

def

TABLE_SCHEMA
:

db

TABLE_NAME
:

t

PARTITION_NAME
:

p0

SUBPARTITION_NAME
:

NULL

PARTITION_ORDINAL_POSITION
:

1

SUBPARTITION_ORDINAL_POSITION
:

NULL

PARTITION_METHOD
:

RANGE

SUBPARTITION_METHOD
:

NULL

PARTITION_EXPRESSION
:

id

SUBPARTITION_EXPRESSION
:

NULL

PARTITION_DESCRIPTION
:

10

TABLE_ROWS
:

1

AVG_ROW_LENGTH
:

16384

DATA_LENGTH
:

16384

MAX_DATA_LENGTH
:

NULL

INDEX_LENGTH
:

0

DATA_FREE
:

0

CREATE_TIME
:

2017

02

27

12
:
07
:
29

UPDATE_TIME
:

2017

02

27

13
:
05
:
05

CHECK_TIME
:

NULL

CHECKSUM
:

NULL

PARTITION_COMMENT
:

NODEGROUP
:

default

TABLESPACE_NAME
:

NULL

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

row

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

TABLE_CATALOG
:

def

TABLE_SCHEMA
:

db

TABLE_NAME
:

t

PARTITION_NAME
:

p1

SUBPARTITION_NAME
:

NULL

PARTITION_ORDINAL_POSITION
:

2

SUBPARTITION_ORDINAL_POSITION
:

NULL

PARTITION_METHOD
:

RANGE

SUBPARTITION_METHOD
:

NULL

PARTITION_EXPRESSION
:

id

SUBPARTITION_EXPRESSION
:

NULL

PARTITION_DESCRIPTION
:

20

TABLE_ROWS
:

2

AVG_ROW_LENGTH
:

8192

DATA_LENGTH
:

16384

MAX_DATA_LENGTH
:

NULL

INDEX_LENGTH
:

0

DATA_FREE
:

0

CREATE_TIME
:

2017

02

27

12
:
07
:
29

UPDATE_TIME
:

2017

02

27

13
:
05
:
12

CHECK_TIME
:

NULL

CHECKSUM
:

NULL

PARTITION_COMMENT
:

NODEGROUP
:

default

TABLESPACE_NAME
:

NULL

2

rows
in

set

(
0.00

sec
)

|

TABLE_ROWS列反映了每个分区中记录的数量。由于之前向表中插入了9、10、15三条记录,因此可以看到,当前分区p0中有1条记录,p1分区中有两条记录。PARTITION_METHOD表示分区的类型,这里显示的是RANGE。

对于表t,由于我们定义了分区,因此对于插入的值应该严格遵守分区的定义,当插入一个不在分区中定义的值时,MySQL数据库会抛出一个异常。如下所示:

1

2

|

mysql

insert
into

t

select

30
;

ERROR

1526

(
HY000
)
:

Table
has
no
partition
for

value

30

|

对于上述问题,我们可以对分区添加一个MAXVALUE值的分区,MAXVALUE可以理解为正无穷,因此所有大于等于20且小于MAXVALUE的值被放入p2分区。

1

2

3

4

5

6

7

|

mysql

alter
table

t

add
partition
(
partition
p2
values
less
than
maxvalue
)
;

Query
OK
,

0

rows
affected

(
0.02

sec
)

Records
:

0

Duplicates
:

0

Warnings
:

0

mysql

insert
into

t

select

30
;

Query
OK
,

1

row
affected

(
0.00

sec
)

Records
:

1

Duplicates
:

0

Warnings
:

0

|

RANGE分区主要用于日期列的分区,例如对于销售类的表,可以根据年来分区存放销售记录,如下面的分区表sales。

1

2

3

4

5

6

7

8

|

create
table
sales
(

money
int

unsigned

not

null
,

date

datetime
)

engine

innodb

partition
by
range
(
year
(
date
)
)

(

partition
p2014
values
less
than

(
2015
)
,

partition
p2015
values
less
than

(
2016
)
,

partition
p2016
values
less
than

(
2017
)

)
;

|

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

|

mysql

insert
into
sales
select

100
,
‘2013-01-01’
;

Query
OK
,

1

row
affected

(
0.00

sec
)

Records
:

1

Duplicates
:

0

Warnings
:

0

mysql

insert
into
sales
select

100
,
‘2013-02-01’
;

Query
OK
,

1

row
affected

(
0.01

sec
)

Records
:

1

Duplicates
:

0

Warnings
:

0

mysql

insert
into
sales
select

200
,
‘2013-01-02’
;

Query
OK
,

1

row
affected

(
0.00

sec
)

Records
:

1

Duplicates
:

0

Warnings
:

0

mysql

insert
into
sales
select

200
,
‘2014-03-01’
;

Query
OK
,

1

row
affected

(
0.00

sec
)

Records
:

1

Duplicates
:

0

Warnings
:

0

mysql

insert
into
sales
select

100
,
‘2015-03-01’
;

Query
OK
,

1

row
affected

(
0.00

sec
)

Records
:

1

Duplicates
:

0

Warnings
:

0

|

这样创建的好处就是便于对sales这张表的管理。如果我们要删除2015年的数据,不需要执行delete from sales where date>=’2015-01-01′ and dater<= ‘2016-01-01’,只需要删除2015年所在的分区即可。

1

2

3

|

mysql

alter
table
sales
drop
partition
p2015
;

Query
OK
,

0

rows
affected

(
0.01

sec
)

Records
:

0

Duplicates
:

0

Warnings
:

0

|

这样创建的另一个好处就是可以加快某些查询操作,如果我们只需要查询2015年整年的销售额,可以这样:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

|

mysql

explain
partitions
select

*

from
sales
where
date

=
‘2014-01-01’

and

date
<=
‘2014-12-31’

G

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

row

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

id
:

1

select_type
:

SIMPLE

table
:

sales

partitions
:

p2014

type
:

ALL

possible_keys
:

NULL

key
:

NULL

key_len
:

NULL

ref
:

NULL

rows
:

4

filtered
:

25.00

Extra
:

Using
where

1

row
in

set
,

2

warnings

(
0.00

sec
)

|

通过explain partitions命令我们可以发现,在上述语句中,SQL优化只需要去搜索p2014这个分区,而不会去搜索所有的分区,称为分区修剪(partition pruning),故查询的速度得到了大幅度的提升。需要注意的是,如果执行下列语句,结果是一样的,但是优化器的选择可能又会不同了。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

|

mysql

explain
partitions
select

*

from
sales
where
date

=
‘2014-01-01’

and

date
<=
‘2015-01-01’

G

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

row

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

id
:

1

select_type
:

SIMPLE

table
:

sales

partitions
:

p2014
,
p2016

type
:

ALL

possible_keys
:

NULL

key
:

NULL

key_len
:

NULL

ref
:

NULL

rows
:

4

filtered
:

25.00

Extra
:

Using
where

1

row
in

set
,

2

warnings

(
0.00

sec
)

|

这次条件改为date<=’ 2015-01-01’而不是date<=’2014-12-31’时,优化器会选择搜索两个分区,这是我们不希望看到的,因此对于启用分区,应该根据分区的特性来编写最优的SQL。

在进行分区时,如果出现“This partition function is not allowed”的错误提示,则你可能使用了非支持函数。MySQL 5.6支持的partition函数:http://dev.mysql.com/doc/refman/5.6/en/partitioning-limitations-functions.html

另外,需要注意一点的时,对于RANGE分区的查询,优化器只能对YEAR(),TO_YEAR(),TO_SECONDS(),UNIX_TIMESTAMP()这类函数进行优化选择,如果你使用了其他的函数或方法编写了符合分区特性的SQL语句,就不一定能够使用查询优化,所以再编写SQL语句时尽量测试。

2)LIST分区

LIST分区和RANGE分区类似,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择,而非连续的。

LIST分区通过使用“PARTITION BY LIST(expr)”来实现,其中“expr” 是某列值或一个基于某个列值、并返回一个整数值的表达式,然后通过“VALUES IN (value_list)”的方式来定义每个分区,其中“value_list”是一个通过逗号分隔的整数列表。

1

2

3

4

5

6

7

8

9

|

CREATE
TABLE
employees

(

id

INT

NOT

NULL
,

fname
VARCHAR
(
30
)
,

lname
VARCHAR
(
30
)
,

hired
DATE

NOT

NULL

DEFAULT

‘1970-01-01’
,

separated
DATE

NOT

NULL

DEFAULT

‘9999-12-31’
,

job_code
INT
,

store_id
INT

)
;

|

假定有20个音像店,分布在4个有经销权的地区,如下表所示:

1

2

3

4

5

6

7

8

|

===

===

===

===

==

地区
商店
ID号

北区

3
,

5
,

6
,

9
,

17

东区

1
,

2
,

10
,

11
,

19
,

20

西区

4
,

12
,

13
,

14
,

18

中区

7
,

8
,

15
,

16

===

===

===

===

==

|

不同于RANGE分区中定义的VALUES LESS THAN语句,LIST分区使用VALUES IN,因为每个分区的值是离散的,因此只能定义值。按照属于同一个地区商店的行保存在同一个分区中的方式来分割表,可以使用下面的“CREATE TABLE”语句:

1

2

3

4

5

6

7

8

9

10

11

12

13

|

CREATE
TABLE
employees

(

id

INT

NOT

NULL
,

name
VARCHAR
(
30
)
,

hired
DATE

NOT

NULL

DEFAULT

‘1970-01-01’
,

separated
DATE

NOT

NULL

DEFAULT

‘9999-12-31’
,

store_id
INT

)

PARTITION
BY
LIST
(
store_id
)

PARTITION
pNorth
VALUES
IN

(
3
,
5
,
6
,
9
,
17
)
,

PARTITION
pEast
VALUES
IN

(
1
,
2
,
10
,
11
,
19
,
20
)
,

PARTITION
pWest
VALUES
IN

(
4
,
12
,
13
,
14
,
18
)
,

PARTITION
pCentral
VALUES
IN

(
7
,
8
,
15
,
16
)

)
;

|

这使得在表中增加或删除指定地区的雇员记录变得容易起来。例如,假定西区的所有音像店都卖给了其他公司。那么与在西区音像店工作雇员相关的所有记录(行)可以使用“ALTER TABLE employees DROP PARTITION pWest;”来进行删除,它与具有同样作用的DELETE (删除)查询“DELETE query DELETE FROM employees WHERE store_id IN (4,12,13,14,18);”比起来,要有效得多。

【要点】如果试图插入列值(或分区表达式的返回值)不在分区值列表中的一行时,那么“INSERT”查询将失败并报错。例如,假定LIST分区的采用上面的方案,下面的查询将失败:

1

|

INSERT
INTO
employees
VALUES
(
224
,

‘Linus’
,

‘2015-05-01’
,

‘2015-10-12’
,

42
,

21
)
;

|

这是因为“store_id”列值21不能在用于定义分区pNorth, pEast, pWest,或pCentral的值列表中找到。要重点注意的是,LIST分区没有类似如“VALUES LESS THAN MAXVALUE”这样的包含其他值在内的定义。将要匹配的任何值都必须在值列表中找到。

LIST分区除了能和RANGE分区结合起来生成一个复合的子分区,与HASH和KEY分区结合起来生成复合的子分区也是可能的。

3)HASH分区

HASH分区的目的是将数据均匀地分布到预先定义的各个分区中,保证各分区的数据量大致都是一样的。在RANGE和LIST分区中,必须明确指定一个给定的列值或列值集合应该保存在哪个分区中;而在HASH分区中,MySQL自动完成这些工作,用户所要做的只是基于将要进行哈希分区的列值指定一个列值或表达式,以及指定被分区的表将要被分隔成的分区数量。

要使用HASH分区来分割一个表,要在CREATE TABLE 语句上添加一个“PARTITION BY HASH (expr)”子句,其中“expr”是一个返回一个整数的表达式。它可以仅仅是字段类型为MySQL 整型的一列的名字。此外,你很可能需要在后面再添加一个“PARTITIONS num”子句,其中num是一个非负的整数,它表示表将要被分割成分区的数量,如果没有包括一个PARTITIONS子句,那么分区的数量将默认为1。

1

2

3

4

5

6

7

|

CREATE
TABLE
employees_h

(

id

INT

NOT

NULL
,

lname
VARCHAR
(
30
)
,

store_id
INT

)

PARTITION
BY
HASH
(
store_id
)

PARTITIONS

4
;

|

如果插入一个列store_id为10,20,30的值,那么保存该条记录的分区如下:

1

2

3

4

5

6

7

8

9

10

|

mysql

select
TABLE_ROWS
from
information_schema
.partitions

where
table_schema

database
(
)

and

table_name

‘employees_h’

G

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

row

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

TABLE_ROWS
:

1

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

row

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

TABLE_ROWS
:

0

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

row

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

TABLE_ROWS
:

2

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

row

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

TABLE_ROWS
:

0

4

rows
in

set

(
0.00

sec
)

|

可以看到插入的数据正是按照mod(values,4)这种方式来进行插入的。如果对于连续的值进行HASH分区,如自增主键,则可以较好地将数据进行平均分布。

4)LINER HASH

MySQL还支持线性哈希功能,它与常规哈希的区别在于,线性哈希功能使用的一个线性的2的幂(powers-of-two)运算法则,而常规哈希使用的是求哈希函数值的模数。

线性哈希分区和常规哈希分区在语法上的唯一区别在于,在“PARTITION BY” 子句中添加“LINEAR”关键字。

1

2

3

4

5

6

7

8

9

|

CREATE
TABLE
employees_lh

(

id

INT

NOT

NULL
,

name
VARCHAR
(
30
)
,

hired
DATE

NOT

NULL

DEFAULT

‘1970-01-01’
,

separated
DATE

NOT

NULL

DEFAULT

‘9999-12-31’
,

store_id
INT

)

PARTITION
BY
LINEAR
HASH
(
YEAR
(
hired
)
)

PARTITIONS

4
;

|

按照线性哈希分区的优点在于增加、删除、合并和拆分分区将变得更加快捷,有利于处理含有极其大量(1000吉)数据的表。它的缺点在于,与使用

常规HASH分区得到的数据分布相比,各个分区间数据的分布不大可能均衡。

5)KEY分区

KEY分区和HASH分区相似,不同之处在于HASH分区使用用户定义的函数进行分区,支持字符串HASH分区,KEY分区使用MySQL数据库提供的函数进行分区,这些函数基于与PASSWORD()一样的运算法则。

1

2

3

4

5

6

7

|

CREATE
TABLE
tk

(

col1
INT

NOT

NULL
,

col2
CHAR
(
5
)
,

col3
DATE

)

PARTITION
BY
LINEAR
KEY

(
col1
)

PARTITIONS

3
;

|

在KEY分区中使用关键字LINEAR和在HASH分区中使用具有同样的作用,分区的编号是通过2的幂(powers-of-two)算法得到,而不是通过模数算法。

6)COLUMNS

在前面说了RANGE、LIST、HASH和KEY这四种分区中,分区的条件是:数据必须为整形(interger),如果不是整形,那应该需要通过函数将其转化为整形,如YEAR(),TO_DAYS(),MONTH()等函数。MySQL5.5版本开始支持COLUMNS分区,可视为RANGE分区和LIST分区的一种进化。COLUMNS分区可以直接使用非整形的数据进行分区,分区根据类型直接比较而得,不需要转化为整形。此外,RANGE COLUMNS分区可以对多个列的值进行分区。

COLUMNS分区支持以下的数据类型:

  • 所有的整形类型,如INT、SMALLINT、TINYINT和BIGINT。而FLOAT和DECIMAL则不予支持。
  • 日期类型,如DATE何DATETIME。其余的日期类型不予支持。
  • 字符串类型,如CHAR、VARCHAR、BINARY和VARBINARY。而BLOB和TEXT类型不予支持。

对于日期类型的分区,我们不再需要YEAR()和TO_DATS()函数了,而直接可以使用COLUMNS,如:

1

2

3

4

5

6

7

8

9

|

CREATE
TABLE

t\_c

(

key

varchar
(
50
)
,

value

varchar
(
50
)
,

create\_time

datetime

)

ENGINE

InnoDB
DEFAULT

CHARSET

utf8mb4

PARTITION
BY
RANGE
COLUMNS

(
create_time
)

(

PARTITION
p0
VALUES
LESS
THAN

(
‘2017-01-01 00:00:00’
)
,

PARTITION
p1
VALUES
LESS
THAN

(
‘2017-03-01 00:00:00’
)

)
;

|

同样可以使用字符串分区。

1

2

3

4

5

6

7

8

9

10

|

CREATE
TABLE

monitor\_2

(

key

varchar
(
15
)
,

value

varchar
(
50
)
,

create\_time

datetime
,

city

VARCHAR
(
15
)

)

ENGINE

InnoDB
DEFAULT

CHARSET

utf8mb4

PARTITION
BY
LIST
COLUMNS
(
city
)

(

PARTITION
p0
VALUES
IN
(
‘shanghai’
,
‘beijing’
,
‘shenzhen’
)
,

PARTITION
p1
VALUES
IN
(
‘hubei’
,
‘henan’
,
‘hunan’
)

)
;

|

对比RANGE分区和LIST分区,Columns分区的亮点除了支持数据类型增加之外,另外一大亮点是Columns分区还支持多列分区。如:

1

2

3

4

5

6

7

8

9

10

11

|

CREATE
TABLE

monitor\_3

(

key

varchar
(
15
)
,

value

varchar
(
50
)
,

create\_time

datetime
,

test

VARCHAR
(
1
)

)

ENGINE

InnoDB
DEFAULT

CHARSET

utf8mb4

PARTITION
BY
RANGE
COLUMNS
(
create_time
,
test
)

(

PARTITION
p0
VALUES
LESS
THAN

(
‘2017-01-01 00:00:00’
,
‘yes’
)
,

PARTITION
p1
VALUES
LESS
THAN

(
‘2017-03-01 00:00:00’
,
‘no’
)
,

PARTITION
p2
VALUES
LESS
THAN

(
MAXVALUE
,
MAXVALUE
)

)
;

|

MySQL 5.5开始支持COLUMNS分区,对于之前的RANGE和LIST分区,用户可以用RANGE COLUMNS和LIST COLUMNS分区进行很好的代替了。

三、MySQL子分区

子分区(subparttitioning)是在分区的基础上再进行分区,有时也称这种分区为复合分区。MySQL数据库允许在RANGE和LIST的分区上再进行HASH或KEY的子分区,如:

1

2

3

4

5

6

7

8

|

create
table
ts
(
a

int
,
b

date
)

engine

innodb

partition
by
range
(
year
(
b
)
)

subpartition
by
hash
(
to_days
(
b
)
)

subpartitions

2

(

partition
p0
values
less
than
(
1990
)
,

partition
p1
values
less
than
(
2000
)
,

partition
p2
values
less
than
maxvalue

)
;

|

1

2

3

4

5

6

7

8

9

10

|

mysql

system
ls

ln

/
data
/
mysql
/
3306
/
data
/
db

total

592

rw

r

1

27

27

67

Feb

27

12
:
03

db
.opt

rw

r

1

27

27

8578

Feb

27

15
:
54

ts
.frm

rw

r

1

27

27

98304

Feb

27

15
:
54

ts
#P#p0#SP#p0sp0.ibd

rw

r

1

27

27

98304

Feb

27

15
:
54

ts
#P#p0#SP#p0sp1.ibd

rw

r

1

27

27

98304

Feb

27

15
:
54

ts
#P#p1#SP#p1sp0.ibd

rw

r

1

27

27

98304

Feb

27

15
:
54

ts
#P#p1#SP#p1sp1.ibd

rw

r

1

27

27

98304

Feb

27

15
:
54

ts
#P#p2#SP#p2sp0.ibd

rw

r

1

27

27

98304

Feb

27

15
:
54

ts
#P#p2#SP#p2sp1.ibd

|

表ts先根据b列进行了RANGE分区,然后又进行了一次HASH分区,所以分区的数量应该为(3×2=)6个,这通过查看物理磁盘上的文件也可以得到证实。我们也可以通过使用subpartition语法来显示地指出各个子分区的名字,例如对上述的ts表同样可以这样:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

|

create
table
ts
(
a

int
,
b

date
)

engine

innodb

partition
by
range
(
year
(
b
)
)

subpartition
by
hash
(
to_days
(
b
)
)

(

partition
p0
values
less
than
(
1990
)

(

subpartition
s0
,

subpartition
s1

)
,

partition
p1
values
less
than
(
2000
)

(

subpartition
s2
,

subpartition
s3

)
,

partition
p2
values
less
than
maxvalue

(

subpartition
s4
,

subpartition
s5

)

)
;

|

子分区的建立需要注意以下几个问题:

1、每个子分区的数量必须相同。

2、要在一个分区表的任何分区上使用subpartition来明确定义任何子分区,就必须定义所有的子分区。

3、每个subpartition子句必须包括子分区的一个名字。

4、子分区的名字必须是唯一的。

子分区可以用于特别大的表,在多个磁盘分别分配数据和索引,用到不错,语句这里就不介绍了,可以MySQL技术内幕-Innodb存储引擎书籍。

四、分区中的NULL值

MySQL数据库允许对NULL值做分区,但是处理的方法与其他数据库可能完全不同。MySQL数据库的分区总是视NULL值小于任何的一个非NULL值,这和MySQL数据库中处理NULL值的ORDER BY操作是一样的。因此对于不同的分区类型,MySQL数据库对于NULL值的处理也是各不相同。

1)对于RANGE分区,如果向分区列插入了NULL值,则MySQL数据库会将该值放入最左边的分区。

1

2

3

4

5

6

7

8

9

|

create
table
t_range
(

a

int
,

b

int

)

engine

innodb

partition
by
range
(
b
)
(

partition
p0
values
less
than

(
10
)
,

partition
p1
values
less
than

(
20
)
,

partition
p2
values
less
than
maxvalue

)
;

|

我的面试宝典:一线互联网大厂Java核心面试题库

以下是我个人的一些做法,希望可以给各位提供一些帮助:

整理了很长一段时间,拿来复习面试刷题非常合适,其中包括了Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等,且还会持续的更新…可star一下!

image

283页的Java进阶核心pdf文档

Java部分:Java基础,集合,并发,多线程,JVM,设计模式

数据结构算法:Java算法,数据结构

开源框架部分:Spring,MyBatis,MVC,netty,tomcat

分布式部分:架构设计,Redis缓存,Zookeeper,kafka,RabbitMQ,负载均衡等

微服务部分:SpringBoot,SpringCloud,Dubbo,Docker

image

还有源码相关的阅读学习

image

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

区进行很好的代替了。

三、MySQL子分区

子分区(subparttitioning)是在分区的基础上再进行分区,有时也称这种分区为复合分区。MySQL数据库允许在RANGE和LIST的分区上再进行HASH或KEY的子分区,如:

1

2

3

4

5

6

7

8

|

create
table
ts
(
a

int
,
b

date
)

engine

innodb

partition
by
range
(
year
(
b
)
)

subpartition
by
hash
(
to_days
(
b
)
)

subpartitions

2

(

partition
p0
values
less
than
(
1990
)
,

partition
p1
values
less
than
(
2000
)
,

partition
p2
values
less
than
maxvalue

)
;

|

1

2

3

4

5

6

7

8

9

10

|

mysql

system
ls

ln

/
data
/
mysql
/
3306
/
data
/
db

total

592

rw

r

1

27

27

67

Feb

27

12
:
03

db
.opt

rw

r

1

27

27

8578

Feb

27

15
:
54

ts
.frm

rw

r

1

27

27

98304

Feb

27

15
:
54

ts
#P#p0#SP#p0sp0.ibd

rw

r

1

27

27

98304

Feb

27

15
:
54

ts
#P#p0#SP#p0sp1.ibd

rw

r

1

27

27

98304

Feb

27

15
:
54

ts
#P#p1#SP#p1sp0.ibd

rw

r

1

27

27

98304

Feb

27

15
:
54

ts
#P#p1#SP#p1sp1.ibd

rw

r

1

27

27

98304

Feb

27

15
:
54

ts
#P#p2#SP#p2sp0.ibd

rw

r

1

27

27

98304

Feb

27

15
:
54

ts
#P#p2#SP#p2sp1.ibd

|

表ts先根据b列进行了RANGE分区,然后又进行了一次HASH分区,所以分区的数量应该为(3×2=)6个,这通过查看物理磁盘上的文件也可以得到证实。我们也可以通过使用subpartition语法来显示地指出各个子分区的名字,例如对上述的ts表同样可以这样:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

|

create
table
ts
(
a

int
,
b

date
)

engine

innodb

partition
by
range
(
year
(
b
)
)

subpartition
by
hash
(
to_days
(
b
)
)

(

partition
p0
values
less
than
(
1990
)

(

subpartition
s0
,

subpartition
s1

)
,

partition
p1
values
less
than
(
2000
)

(

subpartition
s2
,

subpartition
s3

)
,

partition
p2
values
less
than
maxvalue

(

subpartition
s4
,

subpartition
s5

)

)
;

|

子分区的建立需要注意以下几个问题:

1、每个子分区的数量必须相同。

2、要在一个分区表的任何分区上使用subpartition来明确定义任何子分区,就必须定义所有的子分区。

3、每个subpartition子句必须包括子分区的一个名字。

4、子分区的名字必须是唯一的。

子分区可以用于特别大的表,在多个磁盘分别分配数据和索引,用到不错,语句这里就不介绍了,可以MySQL技术内幕-Innodb存储引擎书籍。

四、分区中的NULL值

MySQL数据库允许对NULL值做分区,但是处理的方法与其他数据库可能完全不同。MySQL数据库的分区总是视NULL值小于任何的一个非NULL值,这和MySQL数据库中处理NULL值的ORDER BY操作是一样的。因此对于不同的分区类型,MySQL数据库对于NULL值的处理也是各不相同。

1)对于RANGE分区,如果向分区列插入了NULL值,则MySQL数据库会将该值放入最左边的分区。

1

2

3

4

5

6

7

8

9

|

create
table
t_range
(

a

int
,

b

int

)

engine

innodb

partition
by
range
(
b
)
(

partition
p0
values
less
than

(
10
)
,

partition
p1
values
less
than

(
20
)
,

partition
p2
values
less
than
maxvalue

)
;

|

我的面试宝典:一线互联网大厂Java核心面试题库

以下是我个人的一些做法,希望可以给各位提供一些帮助:

整理了很长一段时间,拿来复习面试刷题非常合适,其中包括了Java基础、异常、集合、并发编程、JVM、Spring全家桶、MyBatis、Redis、数据库、中间件MQ、Dubbo、Linux、Tomcat、ZooKeeper、Netty等等,且还会持续的更新…可star一下!

[外链图片转存中…(img-Czlb0wnF-1713642136371)]

283页的Java进阶核心pdf文档

Java部分:Java基础,集合,并发,多线程,JVM,设计模式

数据结构算法:Java算法,数据结构

开源框架部分:Spring,MyBatis,MVC,netty,tomcat

分布式部分:架构设计,Redis缓存,Zookeeper,kafka,RabbitMQ,负载均衡等

微服务部分:SpringBoot,SpringCloud,Dubbo,Docker

[外链图片转存中…(img-MCaMl1Au-1713642136372)]

还有源码相关的阅读学习

[外链图片转存中…(img-F7rxo7mw-1713642136373)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-DWzyOonF-1713642136373)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值