Mysql常見水平分表方案

2021-07-26 14:31:15 字數 4591 閱讀 9356

根據經驗,mysql表資料一般達到百萬級別,查詢效率會很低,容易造成表鎖,甚至堆積很多連線,直接掛掉;水平分表能夠很大程度較少這些壓力。

一般在有嚴格的自增id需求上,如按照user_id水平分表:

table_1  user_id從1~100w 

table_2  user_id從101~200w 

table_3  user_id從201~300w 

... 

通過乙個原始目標的id或者名稱通過一定的hash演算法計算出資料儲存表的表名,然後訪問相應的表。

按如下分10張表:

function

get_hash_table

($table

,$userid

)else

return

$table

."_"

.$hash;}

echo get_hash_table

('message'

,'user18991'

);//結果為message_10

echo get_hash_table

('message'

,'user34523'

);//結果為message_13

另外,介紹我現在就是採用簡單的取模分表:

/**

* @param string $table_name 表名

* @param int $user_id 使用者id

* @param int $total 分表總數

* @link

*/function

hash_table

($table_name

,$user_id

,$total

)echo hash_table

("artice"

,1234,5

);//artice_5

echo hash_table

("artice"

,3243,5

);//artice_4

感覺merge儲存引擎類似sql中union的感覺,但是查詢效率不高。

如下舉例,擁有1000w記錄的old_user表分表:

(1)建立new_user表使用merge儲存引擎

mysql

>

create table if not exists

`user1`

(->

`id`

int(11)

not null auto_increment

,->

`name`

varchar(50

)default null

,->

`***`

int(1)

not null default

'0',

->

primary key

(`id`

)->

)engine

=myisam

default charset

=utf8 auto_increment=1

;queryok,

0rows affected

(0.05

sec)

mysql

>

create table if not exists

`user2`

(->

`id`

int(11)

not null auto_increment

,->

`name`

varchar(50

)default null

,->

`***`

int(1)

not null default

'0',

->

primary key

(`id`

)->

)engine

=myisam

default charset

=utf8 auto_increment=1

;queryok,

0rows affected

(0.01

sec)

mysql

>

insert into

`user1`

(`name`

,`***`

)values

('張映',0

);queryok,

1row affected

(0.00

sec)

mysql

>

insert into

`user2`

(`name`

,`***`

)values

('tank',1

);queryok,

1row affected

(0.00

sec)

mysql

>

create table if not exists

`new_user`

(->

`id`

int(11)

not null auto_increment

,->

`name`

varchar(50

)default null

,->

`***`

int(1)

not null default

'0',

->

index(id

)->

)type

=merge union

=(user1

,user2

)insert_method

=last auto_increment=1

;queryok,

0rows affected,1

warning

(0.00

sec)

mysql

>

selectid,

name

,***

from

new_user

;+----+--------+-----+

|id

|name  

|***

|+----+--------+-----+|1

|張映|0

||1|

tank   |1

|+----+--------+-----+

2rows

inset

(0.00

sec)

mysql

>

insert into

`new_user`

(`name`

,`***`

)values

('tank2',0

);queryok,

1row affected

(0.00

sec)

mysql

>

selectid,

name

,***

from

user2

->

;+----+-------+-----+

|id

|name 

|***

|+----+-------+-----+|1

|tank  |1

||2|

tank2 |0

|+----+-------+-----+

2rows

inset

(0.00

sec)

(2)我old_user資料進行分表:

insert into user1

(user1.id

,user1

.name

,user1

.***

)select

(user.id

,user

.name

,user

.***

)from old_user

where

user

.id

<=

5000000

insert into user2

(user2.id

,user2

.name

,user2

.***

)select

(user.id

,user

.name

,user

.***

)from old_user

where

user

.id

>

10000000

這種方案最大的好處是,幾乎不用動業務**。

/php/mysql-tables.html 尊重他人勞動成果就是尊重自己!

Mysql常見的水平分表

根據經驗,mysql表資料一般達到百萬級別,查詢效率會很低,容易造成表鎖,甚至堆積很多連線,直接掛掉 水平分表能夠很大程度較少這些壓力。一般在有嚴格的自增id需求上,如按照user id水平分表 table 1 user id從1 100w table 2 user id從101 200w tabl...

Mysql水平分表

mysql水平分表 mysql在資料量大的情況下,會遇到水平分表的情況。1 條件中含有分表的資訊 比如說要劃分10個表,那對10進行取模。其實也可以是任意雜湊函式,但是要注意注意衝突處理。2 根據時間拆表 當表的關係比較複雜時,無法根據某個維度進行分表。但是有明顯的時效性。想必大家都用微薄,某人發的...

mysql 水平分表 垂直分表

mysql的分表技術 水平分割技術 以qq使用者登入為例 建立uuid表 create table uuid id int unsigned primary key auto increment 建立3張使用者表 create table qqlogin0 id int unsigned prima...