您现在的位置是:首页 > cms教程 > Discuz教程Discuz教程
discuz X3.1分表和分表数据迁移的操作方法
夏菡2025-07-07Discuz教程已有人查阅
导读// forum_thread 分表代码片段 -- 帖子列表{// 定位某个板块的帖子落在哪个表(forum_thread_0)
// *********** 关于读取分表的数据***********
{
// forum_thread 分表代码片段 -- 帖子列表
{
// 定位某个板块的帖子落在哪个表(forum_thread_0)
// ...
// 到指定的表(forum_thread_0、forum_thread_1)中,读取帖子列表
// 注意:(分表的时候,要分得刚刚好,同一个板块的帖子不能跨表,不然会查不到)
$threadlist = array_merge($threadlist, C::t('forum_thread')->fetch_all_search($filterarr, $tableid, $start_limit, $_G['tpp'], $_order, '', $indexadd)); // !!!
}
// forum_post 分表代码片段--回复列表
{
// 读取某个帖子(forum_post)的内容,并定位改帖子在处于哪个分表(forum_post_0、forum_post_1)
function get_thread_by_tid($tid, $forcetableid = null) {
global $_G;
// 加载分表的配置
loadcache('threadtableids');
$threadtableids = array(0);
if(!empty($_G['cache']['threadtableids'])) {
if($forcetableid === null || ($forcetableid > 0 && !in_array($forcetableid, $_G['cache']['threadtableids']))) {
$threadtableids = array_merge($threadtableids, $_G['cache']['threadtableids']);
} else {
$threadtableids = array(intval($forcetableid));
}
}
$threadtableids = array_unique($threadtableids);
foreach($threadtableids as $tableid) {
$tableid = $tableid > 0 ? $tableid : 0;
$ret = C::t('forum_thread')->fetch($tid, $tableid);
if($ret) {
$ret['threadtable'] = C::t('forum_thread')->get_table_name($tableid);
$ret['threadtableid'] = $tableid; // 帖子落在哪个表
$ret['posttable'] = 'forum_post'.($ret['posttableid'] ? '_'.$ret['posttableid'] : '');
break;
}
}
}
// 分表后:读取某个帖子的回复列表(forum_post)
// 注意:(分表的时候,要分得刚刚好,同一个帖子的回复不能跨表,不然会查不到)
{
foreach(C::t('forum_post')->fetch_all_by_tid_range_position($posttableid, $_G['tid'], $start, $end, $maxposition, $ordertype) as $post) { // ...
if($post['invisible'] != 0) {
$have_badpost = 1;
}
$cachepids[$post[position]] = $post['pid'];
$postarr[$post[position]] = $post;
$lastposition = $post['position'];
}
}
}
}
// *********** 关于创建分表和对分表数据进行迁移 ***********
{
// 0. 查看表的状态
{
// SHOW TABLE STATUS LIKE'pg_common_trade';
$status = DB::fetch_first("SHOW TABLE STATUS LIKE '".str_replace('_', '\_', $tablename)."'");
$status['Data_length'] = $status['Data_length']; // 数据的字节数
$status['Index_length'] = $status['Index_length']; // 索引的字节数
}
// 1. 创建目标表
{
$maxtableid = getmaxposttableid(); // 较大分表的ID
DB::query('SET SQL_QUOTE_SHOW_CREATE=0', 'SILENT');
$tableinfo = C::t('forum_post')->show_table_by_tableid(0);
$createsql = $tableinfo['Create Table']; // 表的创建语句
$targettable = $maxtableid + 1;
$newtable = 'forum_post_'.$targettable;
$createsql = str_replace(getposttable(), $newtable, $createsql); // 创建语句
DB::query($createsql); // 创建表
}
// 2. 定位要迁移的数据
{
$count = C::t('forum_post')->count_by_first($fromtableid, 1); // 帖子数
if($count) {
$tids = C::t('forum_post')->fetch_all_tid_by_first($fromtableid, 1, 0, 1000); // 帖子id列表,一次迁移1000条
movedate($tids); // 解析迁移
} else {
cpmsg('postsplit_done', 'action=postsplit&operation=optimize&tableid='.$fromtableid, 'form');
}
}
// 3. 进行迁移数据
{
function movedate($tids) {
global $sourcesize, $tableid, $movesize, $targettableid, $hash, $tableindex, $threadtableids, $fieldstr, $fromtableid, $posttable_info;
$fromtable = getposttable($fromtableid, true);
C::t('forum_post')->move_table($targettableid, $fieldstr, $fromtable, $tids);// 迁移数据
if(DB::errno()) {
C::t('forum_post')->delete_by_tid($targettableid, $tids);
} else {
foreach($threadtableids as $threadtableid) {
// 更新主帖子表的条目 forum_thread
$affected_rows = C::t('forum_thread')->update($tids, array('posttableid' => $targettableid), false, false, $threadtableid);
if($affected_rows == count($tids)) {
break;
}
}
C::t('forum_post')->delete_by_tid($fromtableid, $tids); // 删除主回复表的条目 forum_post
}
$status = helper_dbtool::gettablestatus(getposttable($targettableid, true), false);
$targetsize = $sourcesize + $movesize * 1048576; // 已经迁移的数据
$nowdatasize = $targetsize - $status['Data_length'];// 主表剩余的数量
if($status['Data_length'] >= $targetsize) {// 迁移完毕,进行优化
cpmsg('postsplit_done', 'action=postsplit&operation=optimize&tableid='.$fromtableid, 'form');
}
// 循环重定向
cpmsg('postsplit_doing', 'action=postsplit&operation=movepost&fromtable='.$tableid.'&movesize='.$movesize.'&targettable='.$targettableid.'&hash='.$hash.'&tindex='.$tableindex, 'loadingform', array('datalength' => sizecount($status['Data_length']), 'nowdatalength' => sizecount($nowdatasize)));
}
}
// 4. 优化
{
$fromtableid = intval($_GET['tableid']);
$optimize = true;
$tablename = getposttable($fromtableid);
if($fromtableid && $tablename != 'forum_post') {
$count = C::t('forum_post')->count_table($fromtableid); // 原表的记录数
if(!$count) {
C::t('forum_post')->drop_table($fromtableid); // 没数据,就进行删除
unset($posttable_info[$fromtableid]);
C::t('common_setting')->update('posttable_info', $posttable_info);
savecache('posttable_info', $posttable_info);
update_posttableids();
$optimize = false;
}
}
if($optimize) {
C::t('forum_post')->optimize_table($fromtableid);
}
}
//...
class table_forum_post extends discuz_table
{
/**
* 表的列表
*/
public function show_table() {
return DB::fetch_all("SHOW TABLES LIKE '".DB::table('forum_post')."\_%'");
}
/**
* 表的创建语句
*/
public function show_table_by_tableid($tableid) {
return DB::fetch_first('SHOW CREATE TABLE %t', array(self::get_tablename($tableid)));
}
/**
* 表的列
*/
public function show_table_columns($table) {
$data = array();
$db = &DB::object();
if($db->version() > '4.1') {
$query = $db->query("SHOW FULL COLUMNS FROM ".DB::table($table), 'SILENT');
} else {
$query = $db->query("SHOW COLUMNS FROM ".DB::table($table), 'SILENT');
}
while($field = @DB::fetch($query)) {
$data[$field['Field']] = $field;
}
return $data;
}
/**
* 优化表
*/
public function optimize_table($tableid) {
return DB::query('OPTIMIZE TABLE %t', array(self::get_tablename($tableid)), true);
}
/**
* 帖子数量
*/
public function count_by_first($tableid, $first) {
return DB::result_first('SELECT count(*) FROM %t WHERE %i', array(self::get_tablename($tableid), DB::field('first', $first)));
}
/**
* 帖子id列表
*/
public function fetch_all_tid_by_first($tableid, $first, $start = 0, $limit = 0) {
return DB::fetch_all('SELECT tid FROM %t WHERE first=%d '.DB::limit($start, $limit), array(self::get_tablename($tableid), $first));
}
/**
* 迁移数据
*/
public function move_table($tableid, $fieldstr, $fromtable, $tid) {
$tidsql = is_array($tid) ? 'tid IN(%n)' : 'tid=%d';
return DB::query("INSERT INTO %t ($fieldstr) SELECT $fieldstr FROM $fromtable WHERE $tidsql", array(self::get_tablename($tableid), $tid), true);
}
/**
* 表的记录数
*/
public function count_table($tableid) {
return DB::result_first('SELECT COUNT(*) FROM %t', array(self::get_tablename($tableid)));
}
}
}
本文标签:
很赞哦! ()
下一篇:Discuz模板风格制作方法
图文教程
ucenter php整合discuz用户的方法示例
1、登录后台管理。(在论坛中,用创建论坛的admin账号登陆,然后点“管理中心”)2、添加新应用,填写资料。其实就是“名称”和“密钥”重要一些而已。例如我这里添加的“代码号”
小白安装Discuz论坛步骤教程
1.下载Discuz 版本文件2.下载PHP把里面文件的php.ini-development 更名为php.ini Uncomment下列语句可以用命令检测是否能用php -v如果报错php.exe is not a valid win32 application,那就是这个php是32位版本,而OS是64位
discuz删除forum.php的方法
discuz删除forum.php的方法:首先依次进入“网站后台-全局-域名设置-应用域名”;然后将论坛设置为你的域名,如“ .****.net”;最后点击提交即可。
Discuz编码规范教程
本规范由编程原则组成,融合并提炼了开发人员长时间积累下来的成熟经验,意在帮助形成良好一致的编程风格。适用范围如无特殊说明
相关源码
-
(PC+WAP)门窗门业家居定制铝合金产品pbootcms模板下载基于PbootCMS内核开发的门窗门业企业专用模板,采用响应式设计结构,数据一次录入即可同步适配电脑与手机端浏览。通过简洁大气的视觉呈现,帮助门窗企业快速建立专业线上展示平台,有效传递产品价值与服务优势。查看源码 -
(PC+WAP)盆栽绿植观赏植物花卉租赁免费pbootcms网站模板为花卉盆栽租赁、园林绿化企业打造的PbootCMS网站模板,采用较新内核开发,PC与移动端数据实时同步。通过清新自然的视觉设计,精准展现植物养护、花卉展示等业务场景,帮助用户快速建立专业级行业网站。查看源码 -
(自适应)品牌策划网络设计作品公司个人pbootcms网站源码下载本款基于PbootCMS开发的网站模板专为品牌策划、设计公司打造,特别适合展示创意作品、设计案例和企业服务。模板采用现代化设计风格查看源码 -
(自适应)帝国CMS7.5模板淘宝客导购博客文章源码本模板基于帝国CMS7.5内核深度开发,为电商导购类网站设计。采用响应式布局技术,确保在手机、平板及电脑端均能获得优质浏览体验。模板内置商品推荐模块与优惠信息展示区,可快速搭建专业导购平台。查看源码 -
(自适应响应式)环保净化器家用电器网站免费模板针对环保设备、环境监测等领域的PbootCMS响应式模板,通过模块化设计清晰展示污水处理技术、空气净化系统等解决方案。移动端呈现环保数据可视化图表,后端统一管理确保项目案例、技术等资料多端同步。查看源码 -
(自适应多语言)WordPress开源主题MirageV资讯个人博客源码MirageV资讯类个人博客主题源码/WordPress主题/全开源MirageV 是一款开源的 WordPress 主题,支持自适应、暗黑模式、多语言等功能,查看源码
| 分享笔记 (共有 篇笔记) |
