1亿条数据如何分表100张到Mysql数据库中(PHP)

1亿条数据如何分表100张到Mysql数据库中(PHP),第1张

下面通过创建100张表来演示下1亿条数据的分表过程,具体请看下文代码。

当数据量猛增的时候,大家都会选择库表散列等等方式去优化数据读写速度。笔者做了一个简单的尝试,1亿条数据,分100张表。具体实现过程如下:

首先创建100张表:

$i=0;

while($i<=99){

echo

"$newNumber

\r\n";

$sql="CREATE

TABLE

`code_"$i"`

(

`full_code`

char(10)

NOT

NULL,

`create_time`

int(10)

unsigned

NOT

NULL,

PRIMARY

KEY

(`full_code`),

)

ENGINE=MyISAM

DEFAULT

CHARSET=utf8";

mysql_query($sql);

$i++;

下面说一下我的分表规则,full_code作为主键,我们对full_code做hash

函数如下:

$table_name=get_hash_table('code',$full_code);

function

get_hash_table($table,$code,$s=100){

$hash

=

sprintf("%u",

crc32($code));

echo

$hash;

$hash1

=

intval(fmod($hash,

$s));

return

$table"_"$hash1;

}

这样插入数据前通过get_hash_table获取数据存放的表名。

最后我们使用merge存储引擎来实现一张完整的code表

CREATE

TABLE

IF

NOT

EXISTS

`code`

(

`full_code`

char(10)

NOT

NULL,

`create_time`

int(10)

unsigned

NOT

NULL,

INDEX(full_code)

)

TYPE=MERGE

UNION=(code_0,code_1,code_2)

INSERT_METHOD=LAST

;

这样我们通过select

from

code就可以得到所有的full_code数据了。

以上介绍就是本文的全部内容,希望对大家有所帮助。

可以看mysql的data文件夹下面的数据库文件,就可以查看当前分区情况。还有几种获取MySQL分区表信息的常用方法SHOW CREATE TABLE 可以查看创建分区表的CREATE语句 SHOW TABLE STATUS 可以查看表是否为分区表 查看INFORMATION_SCHEMAPARTITIONS表 可以查看表具有哪几个分区、分区的方法、分区中数据的记录数等重要信息

不管你如何分表, 最后的结果 必须要 满足 

数据库的原理,跟着你的项目逻辑走,和你的数据库的逻辑能走通,思路能走通,

且数据库的分表 一定要满足 数据库结构原理,第一范式,第二港式,第三范式。

如果你的数据库自动分的,那么任何客户端驱动都没有必要去管它。如果是手工分的,那么不就是访问不同的库、不同的表嘛。还是要搞清楚前一个问题:你怎样分。这个不清楚,就等于是在给自己“下套”了,在不知道分库分表的具体含义时来问这个时髦概念如何用EF来实现,无的放矢了。

mysql对数据库和表的大小都没有做限制,mysql是一个软件,每一个表都是一个独立的文件,大小要看具体 *** 作系统对单个文件的限制。因此,很大,一般不需要管它 。

mysql自51以后支持分区表,语法同Oracle类似

分区表类型有range、list、hash、key等几种,我给一个range分区的例子吧

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 NOT NULL,

store_id INT NOT NULL

)

PARTITION BY RANGE (store_id) (

PARTITION p0 VALUES LESS THAN (6),

PARTITION p1 VALUES LESS THAN (11),

PARTITION p2 VALUES LESS THAN (16),

PARTITION p3 VALUES LESS THAN (21)

);

分隔符$

DROP PROCEDURE`t_girl``sp_split_table`$

。的CREATE PROCEDURE`t_girl``sp_split_table`()

开始

声明所做的诠释默认0;

申报v_user_name VARCHAR(20)默认“,

申报v_table_name VARCHAR (64)默认“

-获取所有用户的名称。

user_name的选择USER_NAME t_group组申报cur1光标;

-处理错误或警告。

宣布继续完成1329集= 1的处理程序;

-打开游标。

开放cur1;

而<> 1

取到v_user_name cur1;

如果没有这样做,那么

-获取表名。

设置v_table_name = CONCAT('t_group_',v_user_name),;

-创建新的额外的表

集@ stmt的= CONCAT('创建表',v_table_name“像t_group');

S1 @ stmt的准备;

执行S1;

降准备S1;

-数据加载到

stmt的CONCAT(“的插入',v_table_name,'SELECT 从t_group其中user_name =''',v_user_name,'');

准备S1 @ stmt的

执行S1;

降准备S1

结束,如果

结束而;

-关闭游标。

密切cur1;

-从内存中自由变量的

设置@ stmt的= NULL;

完$ $

界定符;

2,试验表。

我们当前用一个有一千万条记录的表来做测试。

MySQL的教程 > SELECT COUNT()从t_group;

+ --------- +

|计数()|

+ --------- +

| 10388608 |

+ ----- ----- +

1集行(000秒)

表结构

的MySQL> DESC t_group

+ ----------- + ------------------ + - + - ---- + ------ + ---------------- +

|场|类型| NULL |重点|中|额外|

+ ----------- + ------------------ + ------ + - - + ------ + ---------------- +

| ID | INT(10)无符号|无|的PRI | NULL | AUTO_INCREMENT |

|钱|十进制(10,2)| NO | | | |

| USER_NAME | VARCHAR(20)号的MUL | |

| | CREATE_TIME |时间戳| NO | | CURRENT_TIMESTAMP的| |

+ - --------- + ------------------ + ------ + ----- + ------- ------------ + ---------------- +

4行集(000秒)

索引情况。

mysql的显示指数从 表| Non_unique | Key_name | Seq_in_index | COLUMN_NAME |校勘基数Sub_part |盒装NULL | Index_type |评论 t_group | 0 |小学| 1 | ID | | 10388608 |空|空| | B树| | | t_group | | idx_user_name | 1 | USER_NAME | | |空|空| | B树| | | t_group | 1 | idx_combination1 | 1 | USER_NAME | | |空|空| | B树| | | t_group | | idx_combination1 | 2 |钱| | 3776 |空|空| | B树| 集行(000秒)

注:

idx_combination1这个索引什么必须的因为要对USER_NAME来集团此时属于松散索引扫描当然完了后你可以干掉她

idx_user_name

MYSQL>选择t_group USER_NAME 1 USER_NAME组;

+ ----------- +

| USER_NAME |

+ ---- +

|大卫

| | 狮子座

| | 利维娅|

|露西|

|撒拉|

|西蒙|

|索尼

| | 晴天|

+ ---- +

8集行(000秒)

所以结果调表应该是这样的。

mysql的像“t_group_%> SHOW TABLES;

+ ------------------------------ +

| Tables_in_t_girl(t_group_%)|

+ ---------- +

| t_group_david

| | t_group_leo

| | t_group_livia

| | t_group_lucy |

| t_group_sarah

| t_group_simon |

| t_group_sony

| | t_group_sunny时加入|

+ ------------------------------ +

8行集( 000秒)

3,对比结果。

MySQL的> SELECT COUNT()从t_group的USER_NAME ='国宝';

+ ---------- +

|计数()|

+ --------- +

| 1298576 |

+ ---------- +

1行集(171秒)

执行了将近2秒。

MySQL的> SELECT COUNT()从t_group_david的;

+ --------- +

|计数()|

+ --------- +

| 1298576 |

+ --- ---- +

1集行(000秒)

几乎什么瞬间的

MySQL的> SELECT COUNT()从t_group其中user_name <>“国宝”;

+ --------- +

|计数()|

+ --------- +

| 9090032 |

+ --------- +

1集行(926秒)

执行了将近10秒,可以想象,这个什么实际的项目大全-宜配网什么不能忍受的。

MySQL的选择(SELECT COUNT()从t_group) - (SELECT COUNT()来自t_group_david)总额;

+ --------- +

|总时加入|

+ --------- +

| 9090032 |

+ --- --- +

1集行(000秒)

几乎什么瞬间的

我们来看看聚集函数。

对于原表的 *** 作。

MYSQL>选择分(钱),MAX(钱)从t_group其中user_name ='国宝';

+ ------------ + ------------ +

| MIN (钱)| MAX(钱)|

+ ------------ + ------------ +

| -641 | 50059 |

+ ------- ----- + ------------ +

1集行(000秒)

最小,最大值都是全索引扫描。所以是瞬间的

MySQL的SELECT SUM(钱),平均(钱)从t_group其中user_name ='国宝';

+ -------------- + ------------ +

|总和(钱)平均(钱)|

+ -------------- + ------------ +

| 31999238384 | 246417910 |

+ ----------------------- - ------------ +

1集行(215秒)

其他聚集函数的结果就不是完整的索引扫描了耗时215秒。

对于小表的 *** 作

MYSQL>选择分(钱),最大从t_group_david(钱);

+ ------------ + ------------ +

|分(钱)| MAX(钱)|

+ ------------ + ------------ +

| -641 | 50059 |

+ ------- ----- + ------------ +

1集行(150秒)

眼霜最小值完全什么全表扫描,耗时150秒,不划算。以此看来,

MySQL的> SELECT SUM(钱),AVG(钱)从t_group_david

+ -------------- + ------------ +

|总和(钱)| AVG (钱)|

+ -------------- + ------------ +

| 31999238384 | 246417910 |

+ ---- -------- + ------------ +

1行集(168秒)

取得这两个结果也是花了快2秒,快了一点。

我们来看看这个小表的结构。

MYSQL> DESC t_group_david

+ ----------- + ------------------ - ----- + ----- + ------ + ---------------- +

|领域| | NULL |键型|中|额外时加入|

+ ------------- + ------------------ + - - + ----- + ------ + ---------------- +

| ID | INT (10)无符号| |优先级| NULL | AUTO_INCREMENT

| | 钱|十进制(10,2)|号| | |

| | USER_NAME | VARCHAR(20)号的MUL | |

| | CREATE_TIME |时间戳| NO | | CURRENT_TIMESTAMP的| |

+ ----------- + ------------------ + ------ + ----- + ------ + ---------------- +

4行集(000秒)

明显的user_name的属性是多余的那么就干掉它。

MySQL的> ALTER TABLE t_group_david下降USER_NAME

查询确定,1298576行的影响(758秒)

记录:1298576重复:0警告:0

现在来重新对小表运行查询

MYSQL>选择分(钱),最大(钱)从t_group_david

+ ------------ + ------------ +

|分(钱)最大(钱)|

+ ------------ + ------------ +

| -641 | 50059 |

+ ------------ + ------------ +

1行集(000秒)

此时是瞬间的。

MYSQL> SELECT SUM(钱),AVG(钱)从t_group_david

+ -------------- + ------------ +

总和(钱)AVG(钱)|

+ -------------- + ------------ +

| 31999238384 | 246417910 |

+ - ---------- + ------------ +

1行集(094秒)

这次算是控制在一秒以内了。

MySQL的>中止

以上就是关于1亿条数据如何分表100张到Mysql数据库中(PHP)全部的内容,包括:1亿条数据如何分表100张到Mysql数据库中(PHP)、mysql分表的3种方法介绍,什么是分区、数据库分表原理等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/10152160.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-05
下一篇2023-05-05

发表评论

登录后才能评论

评论列表(0条)

    保存