PHP 按月分表控制台命令(yii2版)

<?php
/**
* @Purpose: 按月分表脚本
* @User: Chrdai
* @Date: 2019/3/19
* @Time: 15:23
*/
namespace app\commands; use yii\console\Controller; class CreateTableController extends Controller
{
/**
* @var string 数据库服务器
*/
const HOST = '127.0.0.1'; /**
* @var string 用户名
*/
const USERNAME = 'root'; /**
* @var string 密码
*/
const PASSWORD = 'testpasswd'; /**
* @var string 数据库
*/
const DBNAME = 'test'; /**
* @var string 默认方法
*/
public $defaultAction = 'create-table-by-month'; public function options($actionID)
{
return parent::options($actionID);
} /**
* @purpose: 准备表前缀和表结构
* @author: Chrdai
* @time: 2019-03-19
* @return array
*/
public function prepare()
{
$userPrefix = 'user_';
$userSql = <<<EOF
(
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(32) NOT NULL DEFAULT '' COMMENT '姓名',
created_at datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at datetime DEFAULT null COMMENT '更新时间',
PRIMARY KEY (id)
) CHARACTER SET utf8 COLLATE utf8_general_ci ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT '用户表';
EOF; return [
[
'table_prefix' => $userPrefix,
'sql' => $userSql,
],
];
} /**
* @purpose: 如果网络可用,则进行一次时间同步
* @author: Chrdai
* @time: 2019-03-19
*/
public function updateToCurrentTime()
{
//ping 3 次
passthru('ping baidu.com -c 3 >/dev/null 2>&1',$res);
if($res === 0){
system('ntpdate asia.pool.ntp.org && hwclock --systohc');
}
} /**
* @purpose: 按月分表
* #表命名方案:table_prefix_年月_序号
* #每月的表1是保存1---15日的数据,表2是保存16--31日的数据
* @author: Chrdai
* @time: 2019-03-19
*/
public function actionCreateTableByMonth()
{
//登录mysql
$mysqlLoginInfo = '-h'.self::HOST.' -u'.self::USERNAME.' -p'.self::PASSWORD . ' -D'.self::DBNAME;
$createHead = "CREATE TABLE IF NOT EXISTS ";
$this->updateToCurrentTime();
$arrTable = $this->prepare();
$year = date('Y',time());
$month = date('m',time());
// 创建本月的表
foreach($arrTable as $val){
//每月2张表
for($i = 1; $i <=2 ; $i ++){
$tableName = $val['table_prefix'] . $year . $month . '_' . $i;
$sql = end($val);
system("/usr/bin/mysql {$mysqlLoginInfo} -e \"{$createHead} {$tableName} {$sql}\"");
}
} //创建下个月的表,如果跨年需要单独处理
if(intval($month) == 12){
$nextYear = $year + 1;
foreach($arrTable as $val){
for($i = 1; $i <=2 ; $i ++){
//下一年1月份的表名
$tableName = $val['table_prefix'] . $nextYear . '01_' . $i;
$sql = end($val);
system("/usr/bin/mysql {$mysqlLoginInfo} -e \"{$createHead} {$tableName} {$sql}\"");
}
}
}else{
$nextMonth = intval($month) + 1;
//下个月的表名
$fullMonth = $nextMonth < 10 ? '0' . $nextMonth : $nextMonth;
foreach($arrTable as $val){
for($i = 1; $i <=2 ; $i ++){
$tableName = $val['table_prefix'] . $year . $fullMonth . '_' . $i;
$sql = end($val);
system("/usr/bin/mysql {$mysqlLoginInfo} -e \"{$createHead} {$tableName} {$sql}\"");
}
}
}
}
}
分表规则为:
每月分两张表.
1-15号为 table_prefix_Ym_1 ,
16-31号为table_prefix_Ym_2 ,
如:table_prefix_201903_1
<?php
/**
* @purpose: 根据时间范围获取表名
* @explain: 表名的分表规则是,每月分两张表,1-15号为 table_prefix_Ym_1 ,16-31号为table_prefix_2 , 如:table_prefix_201903_1
* User: Chrdai
* Date: 2019/3/5
* Time: 18:08
*/ class TablePrefix
{
/**
* @const app调用记录表前缀
*/
const PREFIX= 'table_prefix_'; /**
* @purpose:获取指定时间范围内的app调用记录表
* @param int|string $starttime 开始时间
* @param int|string $endtime 结束时间
* @return array $tables 指定时间范围内的应用程序记录表
*/
public static function getTableByDateRange($starttime,$endtime)
{
$tables = [];
if(!empty($starttime)){
$start = is_numeric($starttime) ? date('Ymd',$starttime) : date('Ymd',strtotime($starttime));
}
if(!empty($endtime)){
$end = is_numeric($endtime) ? date('Ymd',$endtime) : date('Ymd',strtotime($endtime));
}
if(!empty($start) && !empty($end)){
$prev = floor($start / 100);
$next = floor($end / 100);
//开始时间小于等于结束时间范围内的表都房间$tables
while ($prev <= $next){
$tables[] = self::PREFIX . $prev. '_1';
$tables[] = self::PREFIX . $prev. '_2';
$prev = ($prev % 100 === 12) ? ((floor($prev/100) + 1) * 100 +1) : $prev + 1; //对夸年的月份做特殊处理
} //以15天为分界线,分上下月,去除重复的表
if($start % 100 > 15){
array_shift($tables);
}
if($end % 100 <= 15){
array_pop($tables);
}
}
return $tables;
}
}
//获取表名
$tables = TablePrefix::getTableByDateRange('2019-03-05 12:00:00','2019-03-05 14:00:00');
//循环处理各个表中的数据
$table = array_shift($tables); // 首先拿出第一张表中的数据
while(true){
__loop: //...... (每张表的业务逻辑) // 如果$tables中没有表了,则跳出循环,否则循环处理
if(empty($tables)){
break;
}else{
$table = array_shift($tables);
goto __loop;
}
}

此文为袋鼠(Chrdai)工作中所几记,如有转载请注明出处:https://www.cnblogs.com/chrdai/p/10551175.html

按月分表(create table)的更多相关文章

  1. Mycat(5):聊天消息表数据库按月分表实践,平滑扩展

    本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/47003577 未经博主同意不得转载. 1,业务需求 比方一个社交软件,比方像腾讯 ...

  2. 用复制方式创建表 Create Table tbname as select * from user.tab where ...

    用复制方式创建表 Create Table tbname as select * from user.tab where ...

  3. mysql如何查询多样同样的表/sql分表查询、java项目日志表分表的开发思路/按月分表

    之前开发的一个监控系统,数据库的日志表是单表,虽然现在数据还不大并且做了查询sql优化,不过以后数据库的日志表数据肯定会越来越庞大,将会导致查询缓慢,所以把日志表改成分表,日志表可以按时间做水平分表, ...

  4. mysql 创建表 create table详解

      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 ...

  5. Oracle 创建表 Create Table...

    一.创建表 主键约束primary key 约束条件,唯一且非空,一个表中只能有一个主键:有多个字段联合作为主键时,合在一起唯一标识记录,叫做联合主键. 外键约束 foreign key 受另外一张表 ...

  6. mysql 事件 按月分表

    /****** 对象: Table Order_201512 脚本日期: 2015/12/18 11:44:23 ******/ /****** 字段数据长度 = 2599 字节 ******/ CR ...

  7. 根据查询结果创建新表create table .. as (select....)

    一张表 student 查询数学和英语都是90分以上的同学,并创建一张新表 test1

  8. mysql按月分表, 组合查询

    每个月月底最后一天建好下个月的空表 或每年底建1到12月的空表 , table_201901,table_201902,table_201903 增加记录不需要修改,insert到当月对应表就好了. ...

  9. Mysql数据库进阶之(分表分库,主从分离)

    前言:数据库的优化是一个程序员的分水岭,作为小白我也得去提前学习这方面的数据的 (一)  三范式和逆范式 听起范式这个迟非常专业我来举个简单的栗子: 第一范式就是:  把能够关联的每条数据都拆分成一个 ...

随机推荐

  1. 使用antd Table + mobx 处理数组 出现的一系列问题

    在store中定义了一个数组: @observable list = [...] 若是在table组件中直接使用list: <Table className={styles.table} col ...

  2. Luogu P2158 仪仗队 题解报告

    题目传送门 [题目大意] 给定一个n×n的点方阵,求站在左下角的点能看到的点数 注意同一条直线上只能看到一个点 [思路分析] 因为是一个方阵,所以可以对称地算,那么对于半个方阵,这里假设是左上的半个方 ...

  3. L1-Day12

    1.凡是杀不死你的都会让你变得更强.(什么关系?主语是什么?)[我的翻译]There is no killing you makes you stronger.[标准答案]What doesn’t k ...

  4. 如何做一个项目.ppt

    链接:https://pan.baidu.com/s/1q8Ogj0xYQV_vk-HGcszxqw 提取码:0a82 复制这段内容后打开百度网盘手机App,操作更方便哦

  5. 吴恩达《机器学习》课程笔记——第七章:Logistic回归

    上一篇  ※※※※※※※※  [回到目录]  ※※※※※※※※  下一篇 7.1 分类问题 本节内容:什么是分类 之前的章节介绍的都是回归问题,接下来是分类问题.所谓的分类问题是指输出变量为有限个离散 ...

  6. [MySQL]如何支持utf8格式的UCS4unicode字符

    filed中必须是CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci: 连接时必须set names "utf8mb4": 这是一段P ...

  7. JavaScript 变量声明:var、let、const

    1. 概述 1.1 说明 在ES5 声明变量的方法:var命令和function命令. 在ES6 声明变量的方法:var命令.function命令.let命令.const命令.import命令.cla ...

  8. LeetCode 7. Reverse Integer(c语言版)

    题目: Given a 32-bit signed integer, reverse digits of an integer. Example 1: Input: 123Output: 321 Ex ...

  9. VUE项目快速构建

    IDE  :VScode 1.新建项目文件夹 ctrl+~   调出命令板,/IDE找到当前文件夹右键 点击‘在命令提示符中打开’ 安装 node:官网(https://nodejs.org/en/d ...

  10. spring+myBatis 配置多数据源,切换数据源

    注:本文来源于  tianzhiwuqis <spring+myBatis 配置多数据源,切换数据源> 一个项目里一般情况下只会使用到一个数据库,但有的需求是要显示其他数据库的内容,像这样 ...