diff --git a/library/think/db/Query.php b/library/think/db/Query.php index 6a064c6a..1c124ac0 100644 --- a/library/think/db/Query.php +++ b/library/think/db/Query.php @@ -39,6 +39,8 @@ class Query protected $options = []; // 参数绑定 protected $bind = []; + // 分表规则 + protected $partition = []; /** * 架构函数 @@ -256,6 +258,62 @@ class Query return $this->connection->getConfig($name); } + /** + * 得到分表的的数据表名 + * @access public + * @param array $data 操作的数据 + * @return string + */ + public function getPartitionTableName($data = []) + { + // 对数据表进行分区 + if (isset($data[$this->partition['field']])) { + $field = $data[$this->partition['field']]; + switch ($this->partition['type']) { + case 'id': + // 按照id范围分表 + $step = $this->partition['expr']; + $seq = floor($field / $step) + 1; + break; + case 'year': + // 按照年份分表 + if (!is_numeric($field)) { + $field = strtotime($field); + } + $seq = date('Y', $field) - $this->partition['expr'] + 1; + break; + case 'mod': + // 按照id的模数分表 + $seq = ($field % $this->partition['num']) + 1; + break; + case 'md5': + // 按照md5的序列分表 + $seq = (ord(substr(md5($field), 0, 1)) % $this->partition['num']) + 1; + break; + default: + if (function_exists($this->partition['type'])) { + // 支持指定函数哈希 + $fun = $this->partition['type']; + $seq = (ord(substr($fun($field), 0, 1)) % $this->partition['num']) + 1; + } else { + // 按照字段的首字母的值分表 + $seq = (ord($field{0}) % $this->partition['num']) + 1; + } + } + return $this->getTable() . '_' . $seq; + } else { + // 当设置的分表字段不在查询条件或者数据中 + // 进行联合查询,必须设定 partition['num'] + $tableName = []; + for ($i = 0; $i < $this->partition['num']; $i++) { + $tableName[] = 'SELECT * FROM ' . $this->getTable() . '_' . ($i + 1); + } + + $tableName = '( ' . implode(" UNION ", $tableName) . ') AS ' . $this->name; + return $tableName; + } + } + /** * 获取当前的builder实例对象 * @access protected