背景:接之前的博文,表分区的时候选择的是基于自增id的hash分区,分区关键词partition和hash这块谷歌后进行的操作。关于分表记录历史基础数据,因为每年或者每月会新增一张分表,这样相应的在创建新的分表后,也需要创建相应新的合并表,以便于将新的分表数据可以包裹进去。
/**
*
* 准备下一年数据备份表并重新创建合并表
*/
public function createNextYearTable($db){
$next_year = intval(date('Y'))+1;
$has_table = $db->query("SHOW TABLES LIKE 'b_m_d".$next_year."'");
if (empty($has_table)){
$db->execute("create table b_m_d".$next_year." like b_m_d".intval(date('Y')));
sleep(2);
$db->execute("DROP TABLE IF EXISTS b_m_dall");
// 查询出已有的分表
$table_arr = $db->query("SHOW TABLES LIKE 'b_m_d%'");
$table_str = "";
foreach ($table_arr as $val){
foreach ($val as $name){
$table_str .= empty($table_str) ? $name : ",".$name;
}
}
// 拼接创建合并表的sql
$create_sql = $this->getCreateSql();
$create_sql .= " UNION({$table_str})";
$db->execute($create_sql);
}
}
/**
*
* 获取 创建合并表结构sql语句
*/
public function getCreateSql(){
// 创建合并表结构sql语句
$create_sql = "CREATE TABLE `b_m_dall` (
`id` int(11) NOT NULL ,
`goods_id` bigint(15) NULL DEFAULT NULL COMMENT '宝贝id' ,
PRIMARY KEY (`id`)
)
ENGINE=MRG_MyISAM
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci INSERT_method=NO";
return $create_sql;
}
备注:
1.首先判断下一年的数据表是否已经准备好,如果没有,创建下一年数据存放的数据表,创建sql运行完后,休眠2s,释放下连接(视应用情况是否需要休眠)。
2.当创建了新的数据表后,就应该创建对应的新的合并表,所以先删除原有的合并表。
3.获取数据库中已经存在的所有分表表名称,与合并表对应的数据结构sql代码合并成一条sql并执行。
注意点:
1.因为合并表的存储引擎不一样,并且需要包含新的分表,所以不能用create table a like b的形式复制表结构来完成合并表表结构的创建。只能通过复制分表的表结构sql语句来做,以保证合并表和分表的结构一致。
2.使用create table a like b的形式创建新的分表,是为了保证所有的分表之间结构都是一样的,如果通过sql语句来做的话,可能会导致分表之间结构的不一样。