MySQL的3个子表方案
首先,说说你为什么要把表分开。当一块数据达到数百万,您所花费的时间将花费更多的时间,如果有联合查询,它可能会死在那里。子表的目的是减少数据库的负担和缩短查询时间。
根据个人经验,MySQL执行SQL的过程如下:
1,接收sql;
2,将SQL放入队列队列中;
3,执行sql;
4,返回执行结果。
执行这一过程的时间最多在哪里首先,排队时间,第二,SQL执行时间。事实上,这两个是一回事,等待的时候,在执行中必须有一个SQL,所以我们必须缩短SQL的执行时间。
mysql有一个表和行锁定机制,为什么会有这样一个机制,为了保证数据的完整性,我举例来说,如果两个SQL修改一个表,有一个数据,这个时候怎么做呢,不是一个两个SQL,你可以同时修改数据吗很显然,MySQL的处理这种情况,一个是表锁(MyISAM存储引擎),一个是行锁(InnoDB存储引擎)。表锁定,表明没有您可以在此表上操作。它必须等待我完成表,线锁是一样的,其他SQL必须等待我完成这个数据操作来操作这个数据。如果数据太多,执行的时间太长,等待时间越长,这就是我们要把表分开的原因。
两。
1,例如做MySQL集群:使用MySQL集群、MySQL Proxy,MySQL复制,磁盘数据库等
有人会问MySQL集群,根表与它有什么关系虽然它不是实际意义上的子表,但它打开了子表的作用。作为一个集群的意义是什么一个数据库来减轻负担,这是许多在SQL,减少SQL队列,例如:有10个SQL请求,如果放在一个数据库服务器的队列,他不得不等待很长的时间,如果10个SQL请求,分配给队列5数据库服务器,在队列数据库服务器只有2个,所以等待的时间大大缩短这已经很明显了,所以我把它放在子表的范围内,我做了一些MySQL集群:
mysql代理安装、配置和读写分离
MySQL复制是主从式的安装和配置,以及数据同步。
优点:良好的可伸缩性,在多个子表(PHP代码)之后没有复杂的操作。
缺点:单个表中的数据量没有变化,占用的时间仍然很大,硬件开销很大。
2,估计大量数据和经常访问的表预先估计,并将它们划分为若干表。
这一预测是不坏,论坛发布了一系列的文章,时间一长,表必须非常大,几十万、几百万的所有可能。在聊天室的信息表,几十人在一起聊天的一个晚上,时间长了,这种形式的数据必须非常大。有很多这样的东西。所以这个数据规模大,这是可以预测的,将被分配一个表提前,这是什么是,根据实际情况,采取聊天信息表为例:
我建了100个这样的表提前,message_00,message_01,message_02的…message_98,message_99。,然后根据用户的ID来确定用户的聊天信息放在桌上,你可以得到它在哈希的方式,你可以得到它在剩余的方式。有很多方法。下面的哈希方法用于获取表的名称:
复制代码代码如下所示:
< PHP
功能get_hash_table(合表用户美元){
$str = CRC32($);
如果($<0){
哈希=0美元。Substr(ABS(str),0, 1);
其他{ }
哈希substr($str =美元,0, 2);
}
返回$表。_。$哈希;
}
回声get_hash_table(消息,'user18991 '); / /结果message_10
回声get_hash_table(消息,'user34523 '); / /结果message_13
>
要说明的是,以上的方法告诉我们,user18991的用户信息记录在message_10的表面,和user34523的用户信息记录在message_13表面。阅读时,只能从自己的表中阅读。
优点:避免列出数以百万计的数据并缩短SQL的执行时间。
缺点:当某个规则,打破这个规则会很麻烦,我使用哈希算法在上面的例子是CRC32,如果我不想使用此算法,使用MD5,将相同的用户信息存储在不同的表中,这样数据的命令。可扩展性是非常可怜的。
3,使用合并存储引擎实现子表
我认为这个方法更合适,那些以前没有考虑过的,而且数据查询很慢。这时,如果我们想把现有的大数据量与痛苦分开,最痛苦的事情就是改变代码,因为程序中的SQL语句已经写了。现在,一个表应该被分成几十个表,甚至数百个表,这样SQL语句需要重写吗例如,我非常喜欢一个例子。
MySQL >显示发动机;你会发现mrg_myisam实际上是合并。
复制代码代码如下所示:
>创建MySQL表不存在` user1 `(
` ID `,int(11)不为空auto_increment,
`名字`,varchar(50)默认为空,
`性`,int(1)不为空的默认'0',
-主键(id)
默认的字符集utf8 auto_increment = 1 > = MyISAM引擎);
查询OK,0行受影响(0.05秒)
>创建MySQL表不存在` user2 `(
` ID `,int(11)不为空auto_increment,
`名字`,varchar(50)默认为空,
`性`,int(1)不为空的默认'0',
-主键(id)
默认的字符集utf8 auto_increment = 1 > = MyISAM引擎);
查询OK,0行受影响(0.01秒)
MySQL >插入` user1 `(`名字`,`性`)值('zhang营',0);
查询OK,1行受影响(0秒)
MySQL >插入` user2 `(`名字`,`性`)值('tank ',1);
查询OK,1行受影响(0秒)
>创建MySQL表不存在` `(所有用户
` ID `,int(11)不为空auto_increment,
`名字`,varchar(50)默认为空,
`性`,int(1)不为空的默认'0',
>索引(id)
->类型=合并)联盟=(user1,user2)insert_method =最后auto_increment = 1;
查询OK,受影响的0行,1警告(0秒)
MySQL >选择ID、名称、性别从所有用户;
+ -- + + + -------- -----
身份证姓名性别| | | |
+ -- + + + -------- -----
| 1 | | 0 |张颖
| 1 |罐| 1 |
+ -- + + + -------- -----
2行(0秒)
MySQL >插入`所有用户`(`名字`,`性`)值('tank2 ',0);
查询OK,1行受影响(0秒)
MySQL >选择ID、名称、性别从user2
->;
+ -- + + + ------- -----
身份证姓名性别| | | |
+ -- + + + ------- -----
| 1 |罐| 1 |
| 2 | TANK2 | 0 |
+ -- + + + ------- -----
2行(0秒)
Mysql> CREATE TABLE IF NOT EXISTS `user1` (`id`, int (11) NOT NULL AUTO_INCREMENT, `name` varchar (50) DEFAULT - > NULL - > `sex`, int (1) NOT NULL DEFAULT'0'KEY (`id`) - > PRIMARY - > ENGINE=MyISAM) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1; Query OK, 0 rows affected (0.05 sec) mysql> CREATE TABLE IF NOT EXISTS `user2` (`id`, int (11) NOT NULL AUTO_INCREMENT, `name` varchar (50) DEFAULT - > NULL - > `sex`, int (1) NOT NULL DEFAULT'0' KEY (`id`) - > PRIMARY - > ENGINE=MyISAM) DEFAULT CHARSET=utf8 AUTO_INCREMENT=1; Query OK, 0 rows affected (0.01 sec mysql> INSERT INTO `user1` (`name`) `sex` (VALUES), 'Zhang Ying', 0); Query OK, 1 row affected (0 sec) mysql> INSERT INTO `user2` (`name`, `sex`) VALUES ('tank', 1); QuEry OK, 1 row affected (0 sec)>创建MySQL表不存在`所有用户`(` ID `,int(11)不为空auto_increment,`名字` varchar(50)默认->空-> `性`,int(1)不为空的默认0->索引->类型=合并(ID))联盟=(user1,user2)insert_method =最后auto_increment = 1查询;好的,0行的影响,1报警(0秒)MySQL >选择ID、姓名、性别、来自所有用户;
+ -- + + + -------- -----
身份证姓名性别| | | |
+ -- + + + -------- -----
| 1 | | 0 |张颖
| 1 |罐| 1 |
+ -- + + + -------- -----
2行(0秒)
MySQL >插入`所有用户`(`名字`,`性`)值('tank2 ',0);查询行,1行的影响(0秒)MySQL >选择ID、姓名、性别、从user2 ->;
+ -- + + + ------- -----
身份证姓名性别| | | |
+ -- + + + ------- -----
| 1 |罐| 1 |
| 2 | TANK2 | 0 |
+ -- + + + ------- -----
2行(0秒)
我不知道你从上面的操作中发现任何东西。如果我有一个用户表用户,50w的数据,现在我想拆除两表user1和user2,每桌25w数据,
复制代码代码如下所示:
插入user1(user1.id,user1.name,user1。性)选择(User.ID,user.name,用户从用户那里User.ID。性)250000
插入user2(user2.id,user2.name,2.性别)选择(User.ID,user.name,用户性别)从用户> 250000
所以我成功地把一个用户表分成了两个表,这个时候有一个问题,怎么做sql语句中的代码,以前是一个表,现在是两个表,代码变化很大,所以给程序员很大的工作量,有没有好的解决办法呢方法是备份以前的用户表单并删除它。在上面的操作中,我建立了一个所有用户表,仅改变了的所有用户表的名称的用户。但并不是所有的MySQL操作可用于
一,如果你使用ALTER TABLE更改表合并到其他表的类型,对基础表的映射了。相反,从底层的MyISAM表的行复制到替换表,然后分配一个新的类型。
B,在网上,有人说替换不起作用,我试了一阵子,Halo第一次。
复制代码代码如下所示:
MySQL >更新所有用户设置性别=取代(性别、0, 1)id是2;
查询OK,1行受影响(0秒)
匹配行:1更改:1个警告:0
MySQL >选择*从所有用户;
+ -- + + + -------- -----
身份证姓名性别| | | |
+ -- + + + -------- -----
| 1 | | 0 |张颖
| 1 |罐| 1 |
| 2 | TANK2 | 1 |
+ -- + + + -------- -----
3行(0秒)
MySQL >更新所有用户设置性别=取代(性别,0, 1),id = 2;查询行,1行的影响(0),1 1, 1, 0 0。
+ -- + + + -------- -----
身份证姓名性别| | | |
+ -- + + + -------- -----
| 1 | | 0 |张颖
| 1 |罐| 1 |
| 2 | TANK2 | 1 |
+ -- + + + -------- -----
3行(0秒)
C、合并表不能保持对整个表的唯一约束。当你执行一个插入的数据进入第一个或最后一个MyISAM表(根据不同的insert_method期权价值)。MySQL保证,MyISAM形成唯一的核心价值是独特的,但不是所有的表在收集。
D,当你创建一个合并表格,没有检查确保表格底部的存在和相同的组织。当合并使用表,MySQL检查是否每个映射表的记录长度是相等的,但不是很可靠。如果你创建一个合并表格从类似的MyISAM表,你碰到奇怪的问题,很有可能。
C和D在网上看到,没有测试。让我们试试看。
优点:可伸缩性好,程序代码变化不太大。
缺点:这个方法的效果比第二次差一点。
三。总结
以上三种方法,我实际上做了两个,第一和第二。第三是不做的,所以有点瘦。哈哈 u3002what有一个度,超过一定程度就会变得很糟糕,不盲目做数据库服务器集群,硬件是要花钱的,做不要一味的表,表1000指出,MySQL存储也给所有硬盘上面的表三的文件后,文件的情况下,1000分表对应3000个文件检索,这会很慢。我的建议是
方法1和方法2组合成一个子表。
方法1和方法3组合成一个子表。
根据不同的情况,我的两个建议适合不同的情况,我想会有很多人选择一种方法1和方法3相结合的方法。