mysqlデータテーブル分割ポリシー
7413 ワード
mysql表分け方法:
方法一、データベースクラスタを作る!プライマリ・スレーブ・データベースの双方向ホット・バックアップ(または複数のデータベースのリアルタイム・バックアップ・ポリシーのペア)により、データベース・クエリーをいくつかのサーバに割り当てることができます(サーバ・負荷の分散と組み合わせてアーキテクチャを構築できます).
利点:拡張性がよく、複数の表分割後の複雑な操作(phpコード)の欠点がない:単一の表のデータ量はまだ変わっていないが、1回の操作にかかる時間はそんなに多く、ハードウェアのオーバーヘッドが大きい.
方法2、特殊な状況によって、特定の規則によって表を分けます:例えばユーザーチャット表、message_00,message_01,message_02……….message_98,message_99.その後、ユーザーのIDに基づいて、このユーザーのチャット情報をどの表に入れるかを判断し、hashの方法で取得することができ、余剰を求める方法で取得することができ、方法は多く、例えばhashの方法で表名を得ることができます.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
説明すると、上記の方法は、user 18991というユーザーのメッセージがmessage_に記録されていることを示しています.10この表には、user 34523というユーザーのメッセージがmessage_に記録されています.13この表は、読み取るときは、それぞれの表から読み取ればよい
利点:1枚のテーブルに数百万個のデータが現れることを避け、1本のsqlの実行時間の欠点を短縮した:1つのルールが確定すると、このルールを破るのは面倒で、上の例で私が使っているhashアルゴリズムはcrc 32で、もし私が今このアルゴリズムを使いたくないならば、md 5を変更した後、同じユーザーのメッセージを異なるテーブルに格納して、このようなデータは混乱しました.拡張性が悪い.
方法3:mergeストレージエンジンを利用して表分割を実現する
ユーザテーブルuserが1枚、データが50 Wある場合は、2枚のテーブルuser 1とuser 2に分割し、各テーブル25 Wのデータを
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
しかし、このように表を分けるには注意しなければならないことがあります.mergeストレージエンジンを他のストレージエンジン2にすることはできない.insertを実行し、insert_methodオプションの値に応じて、最初のmyisamテーブルまたは最後のmyisamテーブルにデータを入力します.mysqlは、そのmyisamテーブルで一意のキー値が保持されていることを確認しますが、集合内のすべてのテーブルにまたがっているわけではありません.3.mergeテーブルは分割テーブルの構造とそっくりでなければならない・・・
利点:拡張性がよく、phpコードはほとんど欠点を直さない:この方法の効果は2つ目より少し悪い.
提案:具体的な状況を具体的に分析し、方法1、方法2、方法3を総合的に使用する.
固定リンク:http://blog.zhuyin.org/361.html|平凡な技術ブログを拒否
方法一、データベースクラスタを作る!プライマリ・スレーブ・データベースの双方向ホット・バックアップ(または複数のデータベースのリアルタイム・バックアップ・ポリシーのペア)により、データベース・クエリーをいくつかのサーバに割り当てることができます(サーバ・負荷の分散と組み合わせてアーキテクチャを構築できます).
利点:拡張性がよく、複数の表分割後の複雑な操作(phpコード)の欠点がない:単一の表のデータ量はまだ変わっていないが、1回の操作にかかる時間はそんなに多く、ハードウェアのオーバーヘッドが大きい.
方法2、特殊な状況によって、特定の規則によって表を分けます:例えばユーザーチャット表、message_00,message_01,message_02……….message_98,message_99.その後、ユーザーのIDに基づいて、このユーザーのチャット情報をどの表に入れるかを判断し、hashの方法で取得することができ、余剰を求める方法で取得することができ、方法は多く、例えばhashの方法で表名を得ることができます.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
function
get_hash_table(
$table
,
$userid
) {
$str
= crc32(
$userid
);
if
(
$str
<0){
$hash
=
'0'
.
substr
(
abs
(
$str
), 0, 1);
}
else
{
$hash
=
substr
(
$str
, 0, 2);
}
return
$table
.
'_'
.
$hash
;
}
echo
get_hash_table(
'message'
,
'user18991'
);
// message_10
echo
get_hash_table(
'message'
,
'user34523'
);
// message_13
?>
説明すると、上記の方法は、user 18991というユーザーのメッセージがmessage_に記録されていることを示しています.10この表には、user 34523というユーザーのメッセージがmessage_に記録されています.13この表は、読み取るときは、それぞれの表から読み取ればよい
利点:1枚のテーブルに数百万個のデータが現れることを避け、1本のsqlの実行時間の欠点を短縮した:1つのルールが確定すると、このルールを破るのは面倒で、上の例で私が使っているhashアルゴリズムはcrc 32で、もし私が今このアルゴリズムを使いたくないならば、md 5を変更した後、同じユーザーのメッセージを異なるテーブルに格納して、このようなデータは混乱しました.拡張性が悪い.
方法3:mergeストレージエンジンを利用して表分割を実現する
ユーザテーブルuserが1枚、データが50 Wある場合は、2枚のテーブルuser 1とuser 2に分割し、各テーブル25 Wのデータを
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
CREATE TABLE `test`.`user` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 300 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`pwd` VARCHAR( 200 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`email` VARCHAR( 300 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
) ENGINE = MYISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE `test`.`user1` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 300 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`pwd` VARCHAR( 200 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`email` VARCHAR( 300 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
) ENGINE = MYISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
CREATE TABLE `test`.`user2` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 300 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`pwd` VARCHAR( 200 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`email` VARCHAR( 300 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
) ENGINE = MYISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
INSERT INTO `test`.`user` (`id`, `username`, `pwd`, `email`) VALUES (NULL,
'user1'
,
'123'
,
'[email protected]'
);
INSERT INTO `test`.`user` (`id`, `username`, `pwd`, `email`) VALUES (NULL,
'user2'
,
'123'
,
'[email protected]'
);
INSERT INTO `test`.`user` (`id`, `username`, `pwd`, `email`) VALUES (NULL,
'user3'
,
'123'
,
'[email protected]'
);
INSERT INTO `test`.`user` (`id`, `username`, `pwd`, `email`) VALUES (NULL,
'user4'
,
'123'
,
'[email protected]'
);
INSERT INTO user1(user1.id,user1.username,user1.pwd,user1.email) SELECT user.id,user.username,user.pwd,user.email FROM user where user.id >=2;
INSERT INTO user2(user2.id,user2.username,user2.pwd,user2.email) SELECT user.id,user.username,user.pwd,user.email FROM user where user.id >2;
DROP TABLE `user`;
CREATE TABLE `test`.`user` (
`id` INT( 11 ) NOT NULL ,
`username` VARCHAR( 300 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`pwd` VARCHAR( 200 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`email` VARCHAR( 300 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
INDEX ( `id` )
) ENGINE = MRG_MYISAM UNION=(user1,user2) INSERT_METHOD=LAST CHARSET=utf8 AUTO_INCREMENT=1 ;
:
INSERT INTO `user` (`id`,`username`, `pwd`,`email`) VALUES(5,
'user5'
,
'123'
,
'[email protected]'
);
INSERT INTO `user` (`id`,`username`, `pwd`,`email`) VALUES(6,
'user6'
,
'123'
,
'[email protected]'
);
INSERT INTO `user` (`id`,`username`, `pwd`,`email`) VALUES(7,
'user7'
,
'123'
,
'[email protected]'
);
INSERT INTO `user` (`username`, `pwd`,`email`) VALUES(
'user8'
,
'123'
,
'[email protected]'
);
// id 0 , , , last_id。。。。(php )
しかし、このように表を分けるには注意しなければならないことがあります.mergeストレージエンジンを他のストレージエンジン2にすることはできない.insertを実行し、insert_methodオプションの値に応じて、最初のmyisamテーブルまたは最後のmyisamテーブルにデータを入力します.mysqlは、そのmyisamテーブルで一意のキー値が保持されていることを確認しますが、集合内のすべてのテーブルにまたがっているわけではありません.3.mergeテーブルは分割テーブルの構造とそっくりでなければならない・・・
利点:拡張性がよく、phpコードはほとんど欠点を直さない:この方法の効果は2つ目より少し悪い.
提案:具体的な状況を具体的に分析し、方法1、方法2、方法3を総合的に使用する.
固定リンク:http://blog.zhuyin.org/361.html|平凡な技術ブログを拒否