【原创】PHP + MySQL 分表减低数据库压力
2008-06-27 14:09
295 查看
以下是我对使用 PHP + MySQL 处理负载过重的数据库问题思考和总结,经验方面一定有着不少欠缺的地方,欢迎高手前来指教:
在设计时考虑合理的表结构和相应大概要承受多少访问压力,需不需要分表,如果需要分表每个表放多少条记录合适;
对于分表的实现可以采用 PHP 处理或是 MySQL 自带的 MERGE 表类型(即 MRG_MyISAM)来处理:
⑴如果是使用 PHP 处理有两种情况:
①没有数据的新库新表要为抗压做准备,比如一个聊天室一开始就要考虑可能有多个子聊天室,可以根据一些条件来进行,例如按照主键或是 ID 的范围得出一种算法在存储时就按照相应算法分配存储到同结构但不同名的表中;
②如果是对已经有大量数据需要减压的数据库可以按照一定规则,比如按照该表的访问频率多少,把常用的数据放到一个表中,很少访问的数据放到另一张表中,访问数据时先访问常用表,找不到时再访问非常用表。
⑵如果采用 MySQL 自带的分表方式处理,就是使用 MySQL 的 MERGE 表类型(即 MRG_MyISAM)。这种时候一般是针对已有教多数据,单个数据表无法承受负载时才会使用这种方式,可以针对这个教大的表使用一些工具比如 phpMyadmin 来对相关表的类型进行修改,同时确定分表中每个表里的记录数,不过这个操作需要慎重,除了首次分表外,以后的数据将加到最后一个子表中,想要再分时就需要手动处理,编辑相关的“表明 .MRG”文件了,同时还要处理新的子表的“ALTER TABLE tablename AUTO_INCREMENT = xxx”。
采用 MERGE 表时需要注意手册中提到的一些问题:
①如果你使用 ALTER TABLE 来把 MERGE 表变为其它表类型,到底层表的映射就被丢失了。取而代之的,来自底层 MyISAM 表的行被复制到已更换的表中,该表随后被指定新类型。
②REPLACE 不起作用。
③没有 WHERE 子句,或者在任何被映射到一个打开的 MERGE 表上的任何一个表上的 REPAIR TABLE,TRUNCATE TABLE,OPTIMIZE TABLE 或 ANALYZE TABLE,你不能使用 DROP TABLE,ALTER TABLE,DELETE FROM。如果你这么做了,MERGE 表将仍旧指向原始表,这样产生意外结果。解决这个不足最简单的办法是在执行任何一个这些操作之前发出一个 FLUSH TABLES 语句来确保没有 MERGE 表仍旧保持打开。
④一个 MERGE 表不能在整个表上维持 UNIQUE 约束。当你执行一个 INSERT,数据进入第一个或者最后一个 MyISAM 表(取决于 INSERT_METHOD 选项的值)。MySQL 确保唯一键值在那个 MyISAM 表里保持唯一,但不是跨集合里所有的表。
⑤当你创建一个 MERGE 表之时,没有检查去确保底层表的存在以及有相同的机构。当 MERGE 表被使用之时,MySQL 检查每个被映射的表的记录长度是否相等,但这并不十分可靠。如果你从不相似的 MyISAM 表创建一个 MERGE 表,你非常有可能撞见奇怪的问题。
⑥在 MERGE 表中的索引的顺序和它的底层表中的索引应该一样。如果你使用 ALTER TABLE 给一个被用在 MERGE 表中的表添加一个 UNIQUE 索引,然后使用 ALTER TABLE 在 MERGE 表上添加一个非唯一索引,如果在底层表上已经有一个非唯一索引,对表的索引排序是不同的。(这是因为 ALTER TABLE 把 UNIQUE 索引放在非唯一索引之前以利于重复键的快速检测 )。因此对使用这样索引的表的查询可能返回不期望的结果。
⑦在 Windows中,在一个被 MERGE 表使用的表上 DROP TABLE 不起作用,因为 MERGE 引擎的表映射对 MySQL 的更上层隐藏。因为 Windows 不允许已打开文件的删除,你首先必须刷新所有 MERGE 表(使用 FLUSH TABLES)或在移除该表之前移除 MERGE 表。
在设计时考虑合理的表结构和相应大概要承受多少访问压力,需不需要分表,如果需要分表每个表放多少条记录合适;
对于分表的实现可以采用 PHP 处理或是 MySQL 自带的 MERGE 表类型(即 MRG_MyISAM)来处理:
⑴如果是使用 PHP 处理有两种情况:
①没有数据的新库新表要为抗压做准备,比如一个聊天室一开始就要考虑可能有多个子聊天室,可以根据一些条件来进行,例如按照主键或是 ID 的范围得出一种算法在存储时就按照相应算法分配存储到同结构但不同名的表中;
②如果是对已经有大量数据需要减压的数据库可以按照一定规则,比如按照该表的访问频率多少,把常用的数据放到一个表中,很少访问的数据放到另一张表中,访问数据时先访问常用表,找不到时再访问非常用表。
⑵如果采用 MySQL 自带的分表方式处理,就是使用 MySQL 的 MERGE 表类型(即 MRG_MyISAM)。这种时候一般是针对已有教多数据,单个数据表无法承受负载时才会使用这种方式,可以针对这个教大的表使用一些工具比如 phpMyadmin 来对相关表的类型进行修改,同时确定分表中每个表里的记录数,不过这个操作需要慎重,除了首次分表外,以后的数据将加到最后一个子表中,想要再分时就需要手动处理,编辑相关的“表明 .MRG”文件了,同时还要处理新的子表的“ALTER TABLE tablename AUTO_INCREMENT = xxx”。
采用 MERGE 表时需要注意手册中提到的一些问题:
①如果你使用 ALTER TABLE 来把 MERGE 表变为其它表类型,到底层表的映射就被丢失了。取而代之的,来自底层 MyISAM 表的行被复制到已更换的表中,该表随后被指定新类型。
②REPLACE 不起作用。
③没有 WHERE 子句,或者在任何被映射到一个打开的 MERGE 表上的任何一个表上的 REPAIR TABLE,TRUNCATE TABLE,OPTIMIZE TABLE 或 ANALYZE TABLE,你不能使用 DROP TABLE,ALTER TABLE,DELETE FROM。如果你这么做了,MERGE 表将仍旧指向原始表,这样产生意外结果。解决这个不足最简单的办法是在执行任何一个这些操作之前发出一个 FLUSH TABLES 语句来确保没有 MERGE 表仍旧保持打开。
④一个 MERGE 表不能在整个表上维持 UNIQUE 约束。当你执行一个 INSERT,数据进入第一个或者最后一个 MyISAM 表(取决于 INSERT_METHOD 选项的值)。MySQL 确保唯一键值在那个 MyISAM 表里保持唯一,但不是跨集合里所有的表。
⑤当你创建一个 MERGE 表之时,没有检查去确保底层表的存在以及有相同的机构。当 MERGE 表被使用之时,MySQL 检查每个被映射的表的记录长度是否相等,但这并不十分可靠。如果你从不相似的 MyISAM 表创建一个 MERGE 表,你非常有可能撞见奇怪的问题。
⑥在 MERGE 表中的索引的顺序和它的底层表中的索引应该一样。如果你使用 ALTER TABLE 给一个被用在 MERGE 表中的表添加一个 UNIQUE 索引,然后使用 ALTER TABLE 在 MERGE 表上添加一个非唯一索引,如果在底层表上已经有一个非唯一索引,对表的索引排序是不同的。(这是因为 ALTER TABLE 把 UNIQUE 索引放在非唯一索引之前以利于重复键的快速检测 )。因此对使用这样索引的表的查询可能返回不期望的结果。
⑦在 Windows中,在一个被 MERGE 表使用的表上 DROP TABLE 不起作用,因为 MERGE 引擎的表映射对 MySQL 的更上层隐藏。因为 Windows 不允许已打开文件的删除,你首先必须刷新所有 MERGE 表(使用 FLUSH TABLES)或在移除该表之前移除 MERGE 表。
相关文章推荐
- PHP + MySQL 分表减低数据库压力
- PHP + MySQL 分表减低数据库压力
- php+mysql 数据库分表分段备份程序--宋正河
- php mysql连接数据库实例
- php 链接 mysql 数据库
- php中对MYSQL操作之预处理技术(2)数据库dql查询语句
- php mysql 数据库写入与读取取文件
- MYSQL - php 使用 localhost 无法连接数据库
- 用 PHP 导出 MySQL 数据库内容为 .sql 文件
- 【PHP基础知识】——数据库MySQL操作(上)
- 全新的PDO数据库操作类php版(仅适用Mysql)
- 我的Php学习笔记(六)Mysql简介和创建新的数据库 常用的SQL语句
- PHP_Mysql(创建数据库和表)
- unity连接数据库--可在安卓设备连接(PHP服务器+MySql)
- 【2012年最新原创AJAX案例,重磅推出】1、使用ajax+js+json+dom+php+mysql实现超强 Web聊天室V2.0
- PHP使用数据库永久连接方式操作MySQL的是与非
- PHP+Mysql————表单数据插入数据库及数据提取
- PHP_mySQL_通过php代码+sql查询语句读取数据库信息
- PHP与MySQL学习笔记8:重要概念与设计Web数据库
- php操作mysql--连接数据库 创建表 填充表