thinkphp5水平分割表partition,以及查询操作
前言
先交代下背景,在一个项目中,有一个数据表有水平分表的需求。当时想找到一种方法,把对数据库的操作,写到一个模型里,通过去换模型属性中的table来达到代码不变操作的数据表变化的效果。
我们都知道,模型要想关联数据表的话,有两中方式,第一种就是将模型名和数据表一致。这样模型就会默认关联到名字对应的数据表。第二种就是定义模型的 protected $table 来指定表明。
添加链接描述
模型初始化
ThinkPHP5内置了partition方法,可用于实现简单的分表。新增,修改,删除,查询单条数据时,用parition方法都可以轻松搞定,因为这些操作有一个共同的特点,就是能事先明确的知道,我要操作的是哪一条记录。但有一个需求,ThinkPHP5似乎没有解决,比如当一个大表,被拆分成若干个子表时,如何根据相关条件及排序获取分页数据。这种需求场景下,由于事先并不知道哪些数据会出现在第一页,哪些数据会出现在第二页,这些根据检索条件动态匹配的列表数据,该如何查询呢?
模型层
<?php
namespace app\common\model;
use think\Model;
class WalletLog extends Model
{protected $table = 'tb_walletlog';protected $pk = 'walletid';private function getRule(){return ['type' => 'mod', // 分表方式'num' => 3 // 分表数量];}public function saveData($data, $user_id){return $this->partition(['user_id' => $user_id], "user_id", $this->getRule())->insert($data);}public function getAll($where, $field = "*", $user_id){return $this->partition(['user_id' => $user_id], "user_id", $this->getRule())->where($where)->field($field)->select();}//查询所有分割表public function getAll2(){return $this->partition('', '', $this->getRule())->select();}
}
分库分表查询分表与其他表关联查询 join 不好使用(各种sql 报错)估计不支持
解决方案:
插入使用分表操作,进行分割数据,查询使用普通联合/聚合查询
1、模型层调整 查询
namespace application\workflow\model;
use think\Model;
class Init_Model extends Model
{protected $pk = 'id';//初始化表名public function __construct($name = ''){if (!empty($name)) {$this->name = $name;}}
}
使用时:$model = new init_model(‘test’); //成功改变了数据表
$model->get(); //操作时二次走__construct成空白,还原成没有表名;
请问有内置方法动态改变表名吗,对于动态管理的东东很须要这个功能呀
前人栽树,后人挖坑,哎
2、 执行sql 查询(拼接表名称来实现查询)
select count(1) as total from .$tables['countSql']
3、Db模型函数查询
注意:不要使用任何 SQL 语句中会出现的关键字当表名、字段名,例如 order 等。会导致数据模型拼装 SQL 语句语法错误。
thinkphp5 看云文档 partition 方法用于是数据库水平分表
partition 方法用法如下:
// 用于写入
$data = ['user_id' => 110,'user_name' => 'think'
];$rule = ['type' => 'mod', // 分表方式'num' => 10 // 分表数量
];
Db::name('log')->partition(['user_id' => 110], "user_id", $rule)->insert($data);// 用于查询
Db::name('log')->partition(['user_id' => 110], "user_id", $rule)->where(['user_id' => 110])->select();
4、闭包用法:
每个union方法相当于一个独立的SELECT语句。MySQL通过创建并填充临时表的方式来执行union查询。除非确实要消除重复的行,否则建议使用union all。原因在于如果没有all这个关键词,MySQL会给临时表加上distinct选项,这会导致对整个临时表的数据做唯一性校验,这样做的消耗相当高。
Db::field('name')->table('think_user_0')->union('SELECT name FROM think_user_1')->union('SELECT name FROM think_user_2')->select();
//或者下面这种用法
Db::field('name')->table('think_user_0')->union(['SELECT name FROM think_user_1','SELECT name FROM think_user_2'])->select();
//支持UNION ALL 操作,例如:
Db::field('name')->table('think_user_0')->union(['SELECT name FROM think_user_1','SELECT name FROM think_user_2'],true)->select();
其他案例
应用ThinkPHP内置的分表算法处理百万级用户数据.(适合流水类记录表)
数据表:house_member_0house_member_1house_member_2house_member_3模型中//class MemberModel extends AdvModel {protected $partition = array('field'=>'username','type'=>'id','num'=>'4');public function getDao($data=array()) {$data = empty($data) ? $_POST : $data;$table = $this->getPartitionTableName($data);return $this->table($table);}}方法中class MemberAction extends BaseAction {public function login() {if($this->isPost()) {$this->validToken();$dao = D('Member')->getDao();$res = $dao->where('username = '.$_POST['username'])->find();// output 为自定义方法// $isAjax - bool$this->output(false);}$this->display();}}/**+----------------------------------------------------------* 得到分表的的数据表名+----------------------------------------------------------* @access public+----------------------------------------------------------* @param array $data 操作的数据+----------------------------------------------------------* @return string+----------------------------------------------------------*/public function getPartitionTableName($data=array()) {// 对数据表进行分区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->getTableName().'_'.$seq;}else{// 当设置的分表字段不在查询条件或者数据中//进行联合查询,必须设定 partition['num']$tableName = array();for($i=0;$i<$this->partition['num'];$i++)$tableName[] = 'SELECT * FROM '.$this->getTableName().'_'.$i;$tableName = '( '.implode(" UNION ",$tableName).') AS '.$this->name;return $tableName;}}
温馨提示:
其中 partition 方法指定要查询的分表,where 方法则是查询条件。
需要注意的是,分表可能会给应用带来更高的维护成本和查询复杂度,需要在实际开发中根据业务需要进行选择
复杂模型实现不了的业务逻辑只能用原生sql 来实现。(团队封装的模型基本够用,大数据项目也不会用轻量级框架)有更好的分表查询方法可以欢迎留言。用到那、学到哪!!!
其他文档
ThinkPHP中的分表使用
相关文章:
thinkphp5水平分割表partition,以及查询操作
前言 先交代下背景,在一个项目中,有一个数据表有水平分表的需求。当时想找到一种方法,把对数据库的操作,写到一个模型里,通过去换模型属性中的table来达到代码不变操作的数据表变化的效果。 我们都知道,模型要想关联数据表的话&a…...
docker部署aria2-pro
前言 我平时有一些下载视频和一些资源文件的需求,有时候需要离线下载,也要速度比较快的方式 之前我是用家里的玩客云绝育之后不再写盘当下载机用的,但是限制很多 我发现了aria2 这个下载器非常适合我,而有个大佬又在原来的基础…...
vue中Mixins
使用 Mixins 的主要优点包括: 代码复用: 可以将常用的逻辑封装在 Mixin 中,然后在多个组件中重复使用。逻辑分离: 将不同功能的代码分开管理,使代码更加清晰和易于维护。灵活性: Mixins 允许你在组件中引入多个 Mixin,并且可以根…...
linux常用指令(定期更新)
linux常用指令 1.页相关页大小 2.系统参数3.启动参数4.网络参数查询网卡所属numa节点信息网络测速相关iperf测试sar监控网卡流量查看网卡txqueuelen和mtu抓包tcpdump 网络数据收发状态snmp协议栈netstat -i所有网口TX-OK、RX-OKnetstat-s查看各个协议的收发数据ethtool -S单个网…...
【项目】图书管理系统
目录 前言: 项目要求: 知识储备: 代码实现: Main: Books包: Book: BookList: Operate包: Operate: addOperate: deleteOperate: exitOperate: findOperate:…...
华为OD机试 - 疫情扩散时间计算 - 矩阵(Java 2024 C卷 200分)
目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2024C卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷B卷C卷&am…...
[数据集][图像分类]棉花叶子病害分类数据集2293张4类别
数据集类型:图像分类用,不可用于目标检测无标注文件 数据集格式:仅仅包含jpg图片,每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数):2293 分类类别数:4 类别名称:["diseased_cotton_leaf"…...
《辐射4》是一款什么样的游戏 怎样在mac电脑上玩到《辐射4》辐射4攻略 辐射4开局加点 怎么在Mac电脑玩Steam游戏
辐射4(Fallout 4)是由Bethesda开发的一款动作角色扮演类游戏,为《辐射》系列游戏作品的第四代,于2015年11月10日发行。游戏叙述了主角一家在核爆当天(2077年10月23日),被Vault-Tec(避…...
视频推拉流EasyDSS平台直播通道重连无法转推的原因排查与解决
视频推拉流EasyDSS视频直播点播平台,集视频直播、点播、转码、管理、录像、检索、时移回看等功能于一体,可提供音视频采集、视频推拉流、播放H.265编码视频、存储、分发等视频能力服务。 用户使用EasyDSS平台对直播通道进行转推,发现只要关闭…...
Javaweb之SpringBootWeb案例之自动配置案例的自定义starter测试的详细解析
3.2.4.3 自定义starter测试 阿里云OSS的starter我们刚才已经定义好了,接下来我们就来做一个测试。 今天的课程资料当中,提供了一个自定义starter的测试工程。我们直接打开文件夹,里面有一个测试工程。测试工程就是springboot-autoconfigurat…...
java包的相关概念
包:有效地管理类的一个机制。 包名的目的:通过隶属不同的包有效的区分不同源文件中名字相同的类 包语句 声明:通过关键字 package声明包语句。 位置:源文件中的第一条语句。 作用:为该源文件中声明的类指定包名。 …...
window搭建本地mongo数据库并导入数据
1 window下载mongo数据库 官网:www.mongodb.com 选择 Products > Community Edition 就能进入社区版 在这里下载 windows 版对应的安装包 注意:6.0.1 版本的 MongoDB 配置环境变量有问题,并且我不知道怎么解决,如果想要避免出…...
如何为Android车载应用开发通知?
如何为Android车载应用开发通知?在开发车载应用的通知时,开发者需要考虑到驾驶安全,确保通知不会分散驾驶员的注意力。这通常意味着通知应该是非侵入性的,或者在不影响驾驶的情况下提供信息。开发者可以使用Android的通知API来创建…...
centos上部署k8s
环境准备 四台Linux服务器 主机名 IP 角色 k8s-master-94 192.168.0.94 master k8s-node1-95 192.168.0.95 node1 k8s-node2-96 192.168.0.96 node2 habor 192.168.0.77 镜像仓库 三台机器均执行以下命令: 查看centos版本 [rootlocalhost Work]# cat /…...
网络安全: Kali Linux 进行 MSFvenom 程序利用
目录 一、实验 1.环境 2. Kali Linux 进行 MSFvenom 程序利用 3. 创建计划任务自动运行 MSFvenom 程序 二、问题 1.在线加密解密 2.MSF 运行失败 3.MobaXterm 连接Ubuntu 失败 一、实验 1.环境 (1)主机 表1 主机 系统版本IP备注Kali Linux20…...
浅显易懂C语言指针!!!(三)
文章目录 Pointers as function arguments - call by reference//函数传值vs传引用 Pointers as function arguments - call by reference//函数传值vs传引用 #include<stdio.h> void Increment(int a){//increment 增加 a a 1;//;函数中的是形式参数 形参…...
01 LM 算法及 Cpp 实现
文章目录 01 LM 算法及 Cpp 实现1.1 应用1.2 阻尼法推导1.3 Cpp 算法实现 01 LM 算法及 Cpp 实现 1.1 应用 LM 算法用于解决非线性最小二乘问题 min x F ( x ) 1 2 ∥ f ( x ) ∥ 2 2 (1) \min _x F(x)\frac{1}{2}\|f(\boldsymbol{x})\|_2^2 \tag{1} xminF(x)21∥f(x…...
【网络安全架构】互联网正对中国社会、经济、文化等各个领域产生巨大影响‘
摘 要: 中国互联网近年来飞速发展,普及率达到38.4%。已稳居世界第一网民大国的地位。互联网正对社会、经济、文化等各个领域产生巨大影响。2011年12月21日“泄密门”事件,再次敲响网络安全的警钟。网络攻击和入侵都是根据网络模型不同层次的特…...
【笔记】Android ServiceStateTracker 网络状态变化逻辑及SPN更新影响
业务简介 在网络状态变化的时候(数据或WiFi),会更新SPN。 基于Android U的代码分析。 分类:SPN Data_Dic-的博客-CSDN博客 功能逻辑 状态说明 飞行模式下注册上WFC的话,注册状态MD上报 regState: NOT_REG_MT_NOT…...
2PC和3PC的区别是什么
2PC提交协议是什么 二阶段提交是指,在计算机网络一级数据库领域内,为了使基于分布式系统的架构下的所有节点在进行事务提交时保持一致性而设计的一种算法。在分布式系统中,每个节点虽然可以知晓自己操作的成功和失败,但是无法知道…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
