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提交协议是什么 二阶段提交是指,在计算机网络一级数据库领域内,为了使基于分布式系统的架构下的所有节点在进行事务提交时保持一致性而设计的一种算法。在分布式系统中,每个节点虽然可以知晓自己操作的成功和失败,但是无法知道…...
DDrawCompat开源项目:让Windows经典游戏在现代系统重生
DDrawCompat开源项目:让Windows经典游戏在现代系统重生 【免费下载链接】DDrawCompat DirectDraw and Direct3D 1-7 compatibility, performance and visual enhancements for Windows Vista, 7, 8, 10 and 11 项目地址: https://gitcode.com/gh_mirrors/dd/DDraw…...
从SES价签到ESP32墨水屏驱动板:自制低成本电子价签全记录
1. 从废品到宝藏:SES电子价签的二次生命 第一次看到SES电子价签是在一家即将倒闭的超市里,成堆的废弃价签被当作垃圾处理。当时我就想:这些自带墨水屏的小玩意,能不能变废为宝?后来在二手平台以每片不到20元的价格收购…...
对比直接采购与通过Taotoken使用大模型的月度账单差异
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 对比直接采购与通过Taotoken使用大模型的月度账单差异 1. 背景与观察方法 我们是一个小型技术工作室,日常工作需要频繁…...
InfluxDB-从时序数据模型到实战:核心原理与Web UI高效入门
1. 时序数据库与InfluxDB初探 第一次接触时序数据库时,我盯着监控大屏上跳动的曲线发愣——这些每秒产生数万条记录的传感器数据,传统数据库根本扛不住。直到同事推荐了InfluxDB,这个专门为时间序列数据设计的数据库,才真正解决了…...
别再一段段拼了!用UE4蓝图+Spline Component一键生成连续管道/道路模型
UE4蓝图Spline Component自动化生成复杂路径模型实战指南 在游戏开发中,创建蜿蜒的管道、复杂的赛道或是连绵的城墙往往需要耗费大量时间。传统的手动拼接SplineMesh组件的方式不仅效率低下,而且难以保证模型的连续性和一致性。本文将深入探讨如何利用UE…...
Armv9内存拷贝指令优化与性能调优
1. Arm架构内存拷贝指令深度解析在Armv9架构中,内存拷贝操作通过FEAT_MOPS(Memory Operations)特性得到显著增强。这套指令集专为高效内存操作设计,其中CPYFP/CPYFM/CPYFE系列指令实现了分阶段的内存拷贝机制。与传统的循环拷贝相比,这种设计…...
初创团队如何利用 Taotoken 模型广场快速进行 AI 技术选型
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 初创团队如何利用 Taotoken 模型广场快速进行 AI 技术选型 对于资源有限的初创团队而言,在产品原型阶段快速验证想法是…...
【独家首发】NotebookLM语义搜索底层架构图谱(基于2024 Q2最新API逆向分析,含7层向量映射逻辑)
更多请点击: https://intelliparadigm.com 第一章:NotebookLM语义搜索功能全景概览 核心能力定位 NotebookLM 的语义搜索并非传统关键词匹配,而是基于用户上传文档(PDF、TXT、Google Docs)构建的私有知识图谱进行上下…...
Webpack优化实战:从配置到性能调优
Webpack优化实战:从配置到性能调优 大家好,我是蔓蔓。在大厂工作时,我负责过多个大型项目的Webpack配置和优化。今天我来和大家分享Webpack优化的实战技巧。 基础优化 合理配置mode // webpack.config.js module.exports {mode: process.env…...
通过用量看板与账单追溯实现团队 AI 成本精细化管理
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 通过用量看板与账单追溯实现团队 AI 成本精细化管理 对于技术团队而言,将大模型能力集成到产品与研发流程中已成为常态…...
