根據經驗,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...