瀏覽代碼

add partition to mysql model

stanley-king 2 年之前
父節點
當前提交
d744e33bc3
共有 5 個文件被更改,包括 177 次插入36 次删除
  1. 44 19
      core/framework/libraries/model.php
  2. 3 16
      data/model/refill_order.model.php
  3. 39 0
      helper/refill/util.php
  4. 1 1
      mobile/control/refill.php
  5. 90 0
      test/refill/TestPartModel.php

+ 44 - 19
core/framework/libraries/model.php

@@ -176,9 +176,10 @@ class Model
 
     public function __call($method,$args) 
     {
-        if(in_array(strtolower($method), ['table','order','where','on','limit','having','group','lock','master','distinct','index','attr','key'],true))
+//        Log::record("method={$method}, args={$args[0]}",Log::DEBUG);
+        if(in_array(strtolower($method), ['table','partition','order','where','on','limit','having','group','lock','master','distinct','index','attr','key'],true))
         {
-            $this->options[strtolower($method)] =   $args[0];
+            $this->options[strtolower($method)] = $args[0];
             if (strtolower($method) == 'table')
             {
             	if (strpos($args[0],',') !== false)
@@ -775,7 +776,7 @@ class ModelDb
         'not in'=>'NOT IN'];
     
     // 查询表达式
-    protected $selectSql = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%INDEX%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%';
+    protected $selectSql = 'SELECT%DISTINCT% %FIELD% FROM %TABLE% %PARTITION% %INDEX%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%';
 
     public function select($options= [])
     {
@@ -821,21 +822,25 @@ class ModelDb
 
     public function parseSql($sql,$options= [])
     {
-        $sql   = str_replace(
-            ['%TABLE%','%DISTINCT%','%FIELD%','%JOIN%','%WHERE%','%GROUP%','%HAVING%','%ORDER%','%LIMIT%','%UNION%','%INDEX%'],
-            [
-                $this->parseTable($options),
-                $this->parseDistinct(isset($options['distinct']) ? $options['distinct'] : false),
-                $this->parseField(isset($options['field']) ? $options['field'] : '*'),
-                $this->parseJoin(isset($options['on']) ? $options : []),
-                $this->parseWhere(isset($options['where']) ? $options['where'] : ''),
-                $this->parseGroup(isset($options['group']) ? $options['group'] : ''),
-                $this->parseHaving(isset($options['having']) ? $options['having'] : ''),
-                $this->parseOrder(isset($options['order']) ? $options['order'] : ''),
-                $this->parseLimit(isset($options['limit']) ? $options['limit'] : ''),
-                $this->parseUnion(isset($options['union']) ? $options['union'] : ''),
-                $this->parseIndex(isset($options['index']) ? $options['index'] : '')
-            ],$sql);
+        //todo $options['on'] 是否正确
+//        Log::record("sql={$sql}", Log::DEBUG);
+        $fields = [
+            $this->parseTable($options),
+            $this->parseDistinct($options['distinct'] ?? false),
+            $this->parseField(isset($options['field']) ? $options['field'] : '*'),
+            $this->parseJoin(isset($options['on']) ? $options : []),
+            $this->parseWhere(isset($options['where']) ? $options['where'] : ''),
+            $this->parseGroup(isset($options['group']) ? $options['group'] : ''),
+            $this->parseHaving(isset($options['having']) ? $options['having'] : ''),
+            $this->parseOrder(isset($options['order']) ? $options['order'] : ''),
+            $this->parseLimit(isset($options['limit']) ? $options['limit'] : ''),
+            $this->parseUnion(isset($options['union']) ? $options['union'] : ''),
+            $this->parseIndex(isset($options['index']) ? $options['index'] : ''),
+            $this->parsePartition(isset($options['partition']) ? $options['partition'] : ''),
+        ];
+
+        $sql = str_replace(['%TABLE%', '%DISTINCT%', '%FIELD%', '%JOIN%', '%WHERE%', '%GROUP%', '%HAVING%', '%ORDER%', '%LIMIT%', '%UNION%', '%INDEX%','%PARTITION%'],
+            $fields, $sql);
         return $sql;
     }
 
@@ -852,6 +857,24 @@ class ModelDb
 		return empty($value) ? '':' USE INDEX ('.$value.') ';
 	}
 
+    protected function parsePartition($value)
+    {
+        if(empty($value)) {
+            return '';
+        }
+        elseif(is_string($value)) {
+            return ' PARTITION (' . $value . ') ';
+        }
+        elseif (is_array($value))
+        {
+            $spart = implode(',', $value);
+            return ' PARTITION (' . $spart . ') ';
+        }
+        else {
+            return '';
+        }
+    }
+
     protected function parseValue($value) 
     {
         //|| is_numeric($value)
@@ -1130,6 +1153,7 @@ class ModelDb
     {
         $sql   = 'DELETE '.$this->parseAttr($options).' FROM '
             .$this->parseTable($options)
+            .$this->parsePartition(isset($options['partition'])?$options['partition']:'')
             .$this->parseWhere(isset($options['where'])?$options['where']:'')
             .$this->parseOrder(isset($options['order'])?$options['order']:'')
             .$this->parseLimit(isset($options['limit'])?$options['limit']:'');
@@ -1146,6 +1170,7 @@ class ModelDb
         $sql   = 'UPDATE '
         	.$this->parseAttr($options)
             .$this->parseTable($options)
+            .$this->parsePartition(isset($options['partition'])?$options['partition']:'')
             .$this->parseSet($data)
             .$this->parseWhere(isset($options['where'])?$options['where']:'')
             .$this->parseOrder(isset($options['order'])?$options['order']:'')
@@ -1289,7 +1314,7 @@ class ModelDb
         return $str;
     }
 
-    protected function parseKey(&$key) {
+    protected function parseKey($key) {
         return $key;
     }
 

+ 3 - 16
data/model/refill_order.model.php

@@ -110,22 +110,9 @@ class refill_orderModel extends Model
         return $this->table('refill_detail')->where(['mchid' => $mchid,'mch_order' => $mch_order])->update($datas);
     }
 
-    public function exist($mchid, $mch_order, $scope = false)
-    {
-        $miner = function ($time) {
-            return strtotime(date('Y-m-d',$time)) - 86400 * 15;
-        };
-        $maxer = function ($time) {
-            return $time + 3600;
-        };
-
-        $cond = ['mchid' => $mchid,'mch_order' => $mch_order];
-        if($scope) {
-            $now = time();
-            $cond['order_time'] = [['egt', $miner($now)], ['elt', $maxer($now)], 'and'];
-        }
-
-        $items = $this->table('refill_detail')->field('detail_id')->where($cond)->select();
+    public function exist($mchid, $mch_order, $part = '')
+    {
+        $items = $this->table('refill_detail')->partition($part)->field('detail_id')->where(['mchid' => $mchid,'mch_order' => $mch_order])->select();
         return !empty($items);
     }
 

+ 39 - 0
helper/refill/util.php

@@ -815,4 +815,43 @@ class util
             return $order_time;
         }
     }
+
+    public static function calc_partition($time = 0)
+    {
+        $miner = function ($time) {
+            return strtotime(date('Y-m-d', $time)) - 86400 * 15;
+        };
+        $maxer = function ($time) {
+            return $time + 3600;
+        };
+        $namer = function ($time) {
+            return 'p'.date('Ym', $time);
+        };
+
+        if (defined('DB_PARTIONED') && DB_PARTIONED)
+        {
+            if(is_string($time)) {
+                $time = intval($time);
+            }
+            
+            if($time == 0)
+            {
+                $now = time();
+                $a = $namer($miner($now));
+                $b = $namer($maxer($now));
+
+                if($a != $b) {
+                    return [$a,$b];
+                } else {
+                    return $a;
+                }
+            }
+            else {
+                return $namer($time);
+            }
+        }
+        else {
+            return '';
+        }
+    }
 }

+ 1 - 1
mobile/control/refill.php

@@ -429,7 +429,7 @@ class refillControl extends merchantControl
             return false;
         } else {
             $refill_order = Model('refill_order');
-            $ret = $refill_order->exist($mchid, $mch_order, true);
+            $ret = $refill_order->exist($mchid, $mch_order, refill\util::calc_partition());
             return ($ret == false);
         }
     }

+ 90 - 0
test/refill/TestPartModel.php

@@ -0,0 +1,90 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: stanley-king
+ * Date: 2017/5/25
+ * Time: 上午10:21
+ */
+
+define('APP_ID', 'test');
+define('BASE_ROOT_PATH', str_replace('/test/refill', '', dirname(__FILE__)));
+require_once(BASE_ROOT_PATH . '/global.php');
+require_once(BASE_CORE_PATH . '/lrlz.php');
+require_once(BASE_ROOT_PATH . '/fooder.php');
+require_once(BASE_HELPER_PATH . '/refill/XYZRefillFactory.php');
+
+
+use PHPUnit\Framework\TestCase;
+class TestPartModel extends TestCase
+{
+    public static function setUpBeforeClass() : void
+    {
+        Base::run_util();
+    }
+
+    public function testCalcPartition()
+    {
+        $p1 = refill\util::calc_partition();
+
+        $time = strtotime('2022-10-01');
+        $p2 = refill\util::calc_partition($time);
+
+        $time = strtotime('2022-10-18');
+        $p3 = refill\util::calc_partition($time);
+    }
+
+    //refill_detail
+    public function testDetailExist()
+    {
+        $refill_order = Model('refill_order');
+        $items = $refill_order->table('refill_detail')->field('detail_id')->where(['mchid' => 10202,'mch_order' => '67321661189767693386'])->select();
+    }
+
+    public function testDetailPartion()
+    {
+        $refill_order = Model('refill_order');
+        $items = $refill_order->table('refill_detail')->field('detail_id')->partition('p202210')->where(['mchid' => 10202,'mch_order' => '67321661189767693386'])->select();
+    }
+    public function testDetailPartions()
+    {
+        $refill_order = Model('refill_order');
+        $items = $refill_order->table('refill_detail')->field('detail_id')->partition(['p202209','p202210'])->where(['mchid' => 10202,'mch_order' => '67321661189767693386'])->select();
+    }
+
+    public function testDetailUpdate()
+    {
+        $refill_order = Model('refill_order');
+        $items = $refill_order->table('refill_detail')->where(['mchid' => 10202,'mch_order' => '67321661189767693386'])->update(['order_state' => 50]);
+    }
+    public function testDetailPartsUpdate()
+    {
+        $refill_order = Model('refill_order');
+        $items = $refill_order->table('refill_detail')->partition(['p202209','p202210'])->where(['mchid' => 10202,'mch_order' => '67321661189767693386'])->update(['order_state' => 50]);
+    }
+
+    //refill_order
+    public function testRefillPartion()
+    {
+        $order_sn = '8905710715963417008880';
+        $refill_order = Model('refill_order');
+        $refill_info = $refill_order->getOrderInfo(['order_sn' => $order_sn]);
+        if (!empty($refill_info)) {
+            $order_time = $refill_info['order_time'];
+            $part = refill\util::calc_partition($order_time);
+            $refill_order->partition($part);
+            $info = $refill_order->getOrderInfo(['order_sn' => $order_sn]);
+            $info = $refill_order->getOrderInfo(['order_sn' => $order_sn]);
+            Log::record("info={$info}", Log::DEBUG);
+
+            for ($i =0;$i<2000;$i++)
+            {
+                $refill_order->where(['order_id' => $refill_info['order_id']])->update(['commit_times' => ['exp', 'commit_times+1']]);
+                $refill_order->partition($part);
+                $refill_order->where(['order_id' => $refill_info['order_id']])->update(['commit_times' => ['exp', 'commit_times+1']]);
+            }
+//            $refill_order->partition($part);
+//            $refill_order->where(['order_id' => $refill_info['order_id']])->delete();
+        }
+    }
+}