Tp6,Tp8 模型分表

文章介绍了ThinkPHP框架中如何在模型层实现全局分表功能,包括分表类型的选择、取模计算以及创建新表的逻辑。作者提供了一个简单的模型类和业务层调用的实例。
摘要由CSDN通过智能技术生成

1:全局分表模型定义

<?php
/**
 * AdvPut.php
 * 全局模型操作
 * Created on 2023/6/13 17:21
 * Create by xyz
 */

namespace app\common\model;

use think\facade\Env;
use think\Model;
use think\facade\Db;

class BackCommonModel extends Model
{
    //分表新表表名
    protected string $tableNew = '';
    //分表参照表表名
    protected string $tableOld = '';
    //分表类型:years:年月,specific_date:年月日,year:年,month:月,day:日,delivery:数字取模分表
    protected string $tableType = '';

    //分表自增id`在这里插入代码片`
    protected int $autoIncrement = 1;
    //表前缀
//    protected $prefix = '';
    protected static function init()
    {

    }

    /**
     * Created by
     * User: xyz
     * Date: 2024/2/23
     * Time: 17:26
     * Brief: 简介
     * docs: 自定义模型分表初始方法
     * @param int $delivery_number 分表取模数
     * @param int $delivery_multiple 分表取模倍数
     */
    public function __comInit(int $delivery_number = 0, int $delivery_multiple = 0)
    {
        //创建分表初始化验证
        $this->prefix = Env::get('database.PREFIX', 'tslu_');

        // if (!empty($this->prefix) && !empty($this->tableType)) {
        if (!empty($this->tableType)) {
            //分表尾缀方式
            $suffixAll = [
                'year' => date("Y"),
                'month' => date("m"),
                'day' => date("d"),
                'years' => date("Y_m"),
                'specific_date' => date("Y_m_d"),
                'delivery' => 0,
            ];
            //数字取模分表计算
            if ($this->tableType == 'delivery' && $delivery_number > 0 && $delivery_multiple > 0) {
                $suffixAll['delivery'] = ceil($delivery_number / $delivery_multiple);
            }
            //验证分表后缀是否存在
            if (isset($suffixAll[$this->tableType]) && !empty($suffixAll[$this->tableType])) {
                //参照表表名
                $this->tableOld = $this->name;
                //分表新表表名
                $this->tableNew = $this->name . '_' . $suffixAll[$this->tableType];
                //验证分表是否存在
                $this->gainTable();
            }
        }
    }

    /**
     * Created by
     * User: xyz
     * Date: 2024/2/19
     * Time: 9:41
     * Brief: 简介
     * docs: 验证分表是否存在,不存在就创建新表
     */
    public function gainTable()
    {
        //获取参照表是否存在
        $tableOld = Db::query("SHOW TABLES LIKE '$this->prefix$this->tableOld'");
        //获取新表是否存在
        $isTable = Db::query("SHOW TABLES LIKE '$this->prefix$this->tableNew'");
        if (!empty($tableOld) && empty($isTable) && !empty($this->tableNew)) {
            //创建表
            $this->createTable();
        }
    }

    /**
     * Created by
     * User: xyz
     * Date: 2024/2/19
     * Time: 9:42
     * Brief: 简介
     * docs: 分表不存在,进行复制主表,创建分表表
     * @return mixed
     */
    protected function createTable(): mixed
    {
        //获取建表语句
        $result = Db::query("SHOW CREATE TABLE $this->prefix$this->tableOld");
        $sql = array_pop($result[0]);
        $sql = preg_replace(
            ['/CREATE TABLE `(\w+)`/', '/AUTO_INCREMENT=(\d+)/'],
            ["CREATE TABLE `$this->prefix$this->tableNew`", "AUTO_INCREMENT=$this->autoIncrement"],
            $sql
        );
        //创建新表
        return Db::execute($sql);
    }
}

2:子类继承父类全局模型

<?php

namespace app\admin\model\xxx;

use app\common\model\BackCommonModel;
use think\db\exception\DbException;
use think\facade\Db;
use think\Model;
use think\Paginator;

class Axx extends BackCommonModel
{

    // 开启自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    protected $connection = 'mysql';

    protected $name = 'xxxx';

    // 定义时间戳字段名
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';

    protected int $autoIncrement = 1;//自增id

    //分表类型:years:年月,specific_date:年月日,year:年,month:月,day:日,delivery:数字取模分表
    protected string $tableType = 'delivery';
    //分表取模数
    public static int $deliveryNumber = 0;
    //分表取模倍数
    public static int $deliveryMultiple = 0;

    /**
     * Created by
     * User: xyz
     * Date: 2024/2/23
     * Time: 17:44
     * Brief: 简介
     * docs: 模型初始化
     */
    protected static function init()
    {
        (new Axx())->comInit();
        parent::init();
    }

    /**
     * Created by
     * User: xyz
     * Date: 2024/2/23
     * Time: 17:43
     * Brief: 简介
     * docs: 模型初始化,调用父级自定义魔术方法
     */
    public function comInit()
    {
        parent::__comInit(self::$deliveryNumber, self::$deliveryMultiple);
    }
}

3:业务层引用模型

<?php
/**
 * UserService.php
 * 文件描述
 * Created on 2023/6/5 11:41
 * Create by xyz
 */
namespace app\admin\service\xxxService;

use app\admin\model\powers\Axx;
use app\common\service\CommonService;
use fast\Random;
use think\facade\Config;
use think\Exception;
use think\facade\Log;

class xxxService extends CommonService
{

    /**
     * Created by
     * User: xyz
     * Date: 2023/10/11
     * Time: 15:18
     * Brief: 简介
     * docs: 用户登录
     * @param array $param
     * @return array
     * @throws Exception
     * @throws \RedisException
     */
    public function userLogin(array $param): array
    {
        try {
		  //定义分表取模数
            PowersAdmin::$deliveryNumber = 1;
            //定义分表取模倍数
            PowersAdmin::$deliveryMultiple = 50;
            //获取用户信息
            $userInfo = PowersAdmin::where('xxxx',$param['xxx'])->find();
        } catch (Exception $e) {
            Log::error('用户登录错误' . $e->getMessage());
            throw new Exception($e->getMessage());
        }
    }
}

以上就是tp6,tp8的模型分表全部方法啦,只是一个简单的demo,大家可以自己完善更好的。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
ThinkPHP8分表是一种数据库设计策略,主要用于解决大型应用中数据量过大、查询效率下降的问题。通过将数据分散存储到不同的表(即物理分库、分表),可以有效减轻单个数据库的压力,提高系统的整体性能。 ### ThinkPHP8分表的基本原理 1. **水平分表**:按照一定规则对数据进行切割,比如根据时间戳、用户ID或其他属性将数据分布到不同的表中。这通常涉及到修改数据模型和业务逻辑以适应分布式环境。 2. **负载均衡**:不同分表的数据访问压力得以均衡分配给各个数据库实例,避免了某一分表成为瓶颈。 3. **查询优化**:合理的分表策略可以帮助减少跨服务器的查询延迟,提升查询速度。 ### ThinkPHP8如何支持分表操作 - **配置文件调整**:通过在`config.php`中设置分表相关的配置项,如选择分表策略、指定分表字段等。 - **自定义模型**:利用ThinkPHP提供的ORM特性,在模型层对分表操作进行封装,实现复杂的查询逻辑,如基于条件选择特定分表内的数据。 - **中间件管理**:部署一些中间件处理分表相关请求,自动路由到正确的分表上执行操作,同时负责数据的一致性和完整性检查。 ### 实现步骤及注意事项 1. **需求分析**:明确数据结构、业务逻辑以及预期的性能目标,评估是否需要采用分表策略。 2. **设计阶段**:规划数据分表策略,包括确定分片键、分片算法、主从复制方案等,保证数据一致性。 3. **编码实施**:在ThinkPHP项目中集成分表功能,注意更新数据库连接、模型类等相关部分。 4. **测试验证**:进行全面的性能测试和兼容性测试,确保分表后的系统能够稳定运行,并达到预期的效果。 5. **监控与优化**:上线后持续监控系统性能,根据实际效果调整分表策略,优化查询效率和资源利用率。 ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值