织梦DedeCMS数据清空SQL命令8表归零方案

织梦DedeCMS交付前清空测试数据的8张核心表SQL命令清单:archives三件套、关键词两套、标签两表、栏目、评论留言、uploads物理文件,配合ALTER AUTO_INCREMENT一次性归零自增ID。

张文保 更新 26 分钟阅读 1,135 阅读

写在前面:交付前为什么必须清干净数据

保哥做企业站点交付,最常遇到的一个收尾环节就是:测试期间填充了一堆假数据、栏目和文章被反复增删,到了正式上线那一刻,客户希望整个后台是干净的,文章ID从1开始、栏目编号也从1开始。如果只是从后台一条条删,效率低不说,自增ID依然不会归零,看起来非常不专业。

这篇文章把保哥多年实操织梦DedeCMS(包括早期的5.7 SP2和后来的若干修复版、UTF8/GBK双编码版、DedeBIZ商业版)总结的批量清空SQL命令整理一遍,并把每条语句背后的原理、风险点、踩坑经验全部写清楚,方便后来者照单全收。所有命令在保哥本地的5.7 SP2 UTF8、5.7 SP2 GBK、DedeBIZ 6.2三套环境上实测过,差异点会单独标出。

5个真实需要清空数据的场景

不是所有"清空数据"都是交付,下面这5个场景在保哥客户中各占一定比例:

  1. 测试转正式交付(占60%)——测试期间灌了一两千条假数据,上线前要全部清掉、ID归零
  2. 站点内容重做(占15%)——SEO策略大改,旧文章对应的关键词布局已经不适用,整体推倒重来
  3. 合并多个测试站点(占10%)——把3个测试站合成1个生产站,要先把目标站清空再导入
  4. 灾备演练(占10%)——验证备份能否完整恢复,先清空再从备份还原
  5. 站点改版前的快照(占5%)——保留旧站快照后清空当前数据,做大改

3种常见的错误清理方式

错误做法问题表现正确做法
仅用后台"批量删除文档"翻页慢,ID不归零,容易超时用SQL命令行+ALTER AUTO_INCREMENT
仅Delete from dede_archives正文还在addonarticle表里占用空间三张文章表一起清
清完不清uploads物理文件磁盘空间没释放,附件管理乱SQL+FTP双清,配合附件检测

为什么要用SQL命令而不是后台逐条删除

刚接触织梦的朋友可能会问,后台不是有"批量删除文档"、"批量删除栏目"吗,为什么还要绕一圈写SQL?保哥早期也是这么干的,结果发现几个非常麻烦的问题。

问题一:后台批量删除受单页条数限制

织梦后台的批量删除默认每页20到100条,如果你测试阶段灌了几千条文章,光是翻页删除就要花掉一两个小时。而且中途网络一断就要重来,PHP超时也会让操作中断。SQL命令行一条Delete from语句几秒钟就完事。

问题二:自增ID不会归零

这是最关键的一点:后台删除并不会重置自增ID。比如你删了500篇文章,再发一篇新文章它的aid会从501开始而不是1。对于追求URL美观、对aid有规划的SEO项目来说这是不可接受的。比如有些站点的URL规则是/news/{aid}.html,aid直接出现在URL里,从1开始还是从501开始对用户感知和SEO评分都有影响。

问题三:数据分布在多张表,后台删除易留孤立

织梦的文章数据不是单表存储,它至少分布在dede_archivesdede_addonarticledede_arctiny三张表中(如果开了图集、软件下载模型还会更多)。后台删除偶尔会出现孤立数据,导致后台列表正常但前台模板渲染报错。这些孤立数据用SELECT很难发现,往往要等到客户报障才知道。

保哥的标准做法

所以保哥的标准做法是:直接进入织梦后台的SQL命令行工具(路径在"系统 -> 系统设置 -> SQL命令行工具"),勾选"多行命令",把下面分类整理好的语句复制粘贴执行,几秒钟就能完成所有清理。如果后台SQL命令行工具被禁用(少数加固版本会禁),用phpMyAdmin或Navicat直连数据库执行也是一样的。

DedeCMS数据库表结构速查

清空之前先把表结构搞清楚。DedeCMS的核心数据分布在以下8类表中,每一类都有自己的清空策略。

类别表名用途是否必清
文章主表dede_archives所有文档的主信息(标题、栏目、时间)必清
文章附加表dede_addonarticle普通文章的正文body字段必清
文档索引dede_arctiny极简文档信息,URL路由用必清
图集附加表dede_addonimages图集模型的图片列表用图集才清
软件附加表dede_addonsoft软件下载模型的下载链接用软件模型才清
商品附加表dede_addonshop商品模型的价格库存用商品模型才清
栏目表dede_arctype所有栏目(含嵌套关系)看是否重置栏目
关键词表dede_keywords / dede_search_keywords文档关键词与搜索关键词建议清
标签表dede_tagindex / dede_taglist标签本身和文章标签关系建议清
评论表dede_feedback所有评论记录测试评论应清
留言表dede_guestbook所有留言记录测试留言应清

这张表很重要,是后面所有清空操作的依据。建议清空前先按你站点实际启用的模型对照一遍,缺什么补什么。

清空所有栏目(dede_arctype)

栏目表是织梦内容结构的骨架,所有文章都挂在栏目下,一旦栏目被清掉,文章列表也会出现"未指定栏目"的提示。所以如果你只是想重置文章而保留栏目,不要执行这一段

Delete from dede_arctype;
ALTER TABLE dede_arctype AUTO_INCREMENT = 1;

第一行把dede_arctype表里的所有记录干掉,第二行把这张表的自增ID重置为1,下次新建第一个栏目它的id就是1。这里保哥特别提醒一句:织梦的栏目支持嵌套,子栏目通过reid字段指向父栏目id,所以一旦清空就是连根拔起,不存在"只删某一个分类下所有子栏目"这种半截操作。

条件式删除:只删某个父栏目下的子栏目

如果只想删除某一个父栏目下的全部子栏目,可以用条件式删除:

-- 只删 reid 等于 5 的子栏目
Delete from dede_arctype WHERE reid = 5;

-- 同时删除该父栏目下所有文章(先查后删,避免误删)
SELECT id, title FROM dede_archives WHERE typeid = 5;
Delete from dede_archives WHERE typeid = 5;
Delete from dede_addonarticle WHERE typeid = 5;
Delete from dede_arctiny WHERE typeid = 5;

这条语句会把reid等于5的所有子栏目删掉,但不影响id等于5本身和其他不相关栏目。如果要连父栏目也删,加一条Delete from dede_arctype WHERE id = 5

清空所有文章(三张表必须一起处理)

这是保哥踩坑最多的地方。织梦的"一篇文章"其实是三张表配合写入的:

  • dede_archives:文档主表,存标题、栏目、发布时间、点击数等核心字段
  • dede_addonarticle:附加表,存正文body字段(普通文章模型)
  • dede_arctiny:极简索引表,存最简文档信息,主要给URL路由用

三张表的依赖关系

如果只删了dede_archives而忘了dede_addonarticle,会出现"文章已删除但正文仍在数据库占用空间"的状况,长期累计会让数据库膨胀;如果只删了dede_archives而忘了dede_arctiny,前台访问旧URL会出现路由异常。所以一定要三张表一起来:

Delete from dede_addonarticle;
ALTER TABLE dede_addonarticle AUTO_INCREMENT = 1;

Delete from dede_arctiny;
ALTER TABLE dede_arctiny AUTO_INCREMENT = 1;

Delete from dede_archives;
ALTER TABLE dede_archives AUTO_INCREMENT = 1;

顺序上保哥习惯是先删附加表、再删极简索引、最后删主表。原因是从依赖关系上讲,dede_addonarticledede_arctiny是依赖dede_archives.aid存在的,先删依赖方再删被依赖方逻辑上更干净。虽然在MySQL层面上由于织梦没有用外键约束,顺序对结果没有强制影响,但养成好习惯能在切换到有外键的系统时少踩坑。

含图集和软件模型的扩展清理

如果你的站点开了图集、软件下载等其他文档模型,还要补上对应的附加表:

-- 图集模型
Delete from dede_addonimages;
ALTER TABLE dede_addonimages AUTO_INCREMENT = 1;

-- 软件下载模型
Delete from dede_addonsoft;
ALTER TABLE dede_addonsoft AUTO_INCREMENT = 1;

-- 商品模型(DedeBIZ 商业版默认包含)
Delete from dede_addonshop;
ALTER TABLE dede_addonshop AUTO_INCREMENT = 1;

-- 专题模型
Delete from dede_addonspec;
ALTER TABLE dede_addonspec AUTO_INCREMENT = 1;

没用到的模型可以跳过。如果不确定开了哪些模型,先执行SHOW TABLES LIKE 'dede_addon%';列出所有附加表,挨个清即可。

清空关键词与搜索词

织梦有两套关键词机制,新手很容易混淆,保哥这里掰开讲清楚。

文档关键词(dede_keywords)

第一套是文档关键词,存在dede_keywords表里,用于"关键词维护"功能。早期可以做关键词替换内链(在文章正文里自动给某些词加链接),但因为容易被搜索引擎判定为黑帽内链,新版本DedeCMS已经默认关闭这个功能。

Delete from dede_keywords;
ALTER TABLE dede_keywords AUTO_INCREMENT = 1;

搜索关键词(dede_search_keywords)

第二套是搜索关键词,存在dede_search_keywords表里,用于记录用户在前台搜索框中输入过的词,便于后台统计热门搜索。

Delete from dede_search_keywords;
ALTER TABLE dede_search_keywords AUTO_INCREMENT = 1;

两张表互不干扰,都建议在交付前清空,避免把测试阶段乱搜的"测试"、"123"之类的词留给客户看到。客户进后台第一眼看到热门搜索是"测试1"、"asdf"会非常不专业。

清空标签系统(dede_tagindex 与 dede_taglist)

标签也是两张表配合的:

  • dede_tagindex:存标签本身,包括tag名、点击数、is_hot标记等
  • dede_taglist:存"这个标签下有哪些文章"的对应关系

两张表必须一起清,否则会出现"标签已经不存在但文章列表里还显示该标签"的诡异情况:

Delete from dede_tagindex;
ALTER TABLE dede_tagindex AUTO_INCREMENT = 1;

Delete from dede_taglist;
ALTER TABLE dede_taglist AUTO_INCREMENT = 1;

清完之后,原先在文章发布页填过的TAG也会一并消失,下次发新文章时重新填即可。

只清没文章的孤立标签

如果只想清"已经没有任何文章引用"的孤立标签(保留还在使用的标签):

-- 先查哪些标签没文章在用
SELECT t.id, t.tag FROM dede_tagindex t
LEFT JOIN dede_taglist l ON t.id = l.tid
WHERE l.tid IS NULL;

-- 删掉这些孤立标签
DELETE t FROM dede_tagindex t
LEFT JOIN dede_taglist l ON t.id = l.tid
WHERE l.tid IS NULL;

这种用法在已上线运行一段时间的站点上更实用——不需要全清,只清掉历史遗留的"测试"、"123"这类无意义标签。

清空评论与留言

测试期间客户或开发自己发的评论留言也要清掉。这部分比较简单:

-- 评论
Delete from dede_feedback;
ALTER TABLE dede_feedback AUTO_INCREMENT = 1;

-- 留言板
Delete from dede_guestbook;
ALTER TABLE dede_guestbook AUTO_INCREMENT = 1;

如果用了第三方评论插件(畅言、Disqus等),还要去对应插件的后台单独清。

清空上传目录中的图片与附件

SQL语句只能处理数据库,处理不了文件系统。织梦后台上传的图片、附件物理文件存放在站点根目录的uploads文件夹下,以年月命名子目录。

uploads的标准目录结构

uploads/
  allimg/      # 文章插图、缩略图
    191110/    # 2019年11月10日上传的文件
    191111/
    200115/
  userup/      # 会员上传文件
  soft/        # 软件下载模型上传的安装包
  media/       # 媒体模型上传的音视频
  flink/       # 友情链接的logo

清理方式一:FTP图形化删除

用FTP工具(FileZilla、WinSCP、Cyberduck)连接服务器,进入uploads目录,把所有日期格式的子文件夹选中删除。注意uploads本身不要删,它是织梦默认的上传根目录,删掉之后再上传图片会报路径错误。

清理方式二:SSH命令行删除

如果你有SSH权限,进入站点根目录后执行:

cd /www/wwwroot/site/uploads/allimg
rm -rf 19* 20* 21*

cd ../userup
rm -rf 19* 20* 21*

cd ../soft
rm -rf 19* 20* 21*

这条命令会删掉以19、20、21开头的所有子目录(覆盖2019到2199年的可能命名),干净利落。删完之后建议再看一眼uploads/mediauploads/flink这几个常用子目录,按需清理。

同步清理附件管理表

执行完文件清理后,记得回到织梦后台"核心 -> 附件管理"里再点一下"不存在文件检测",把数据库里残留的附件记录也一并清理。或者直接清表:

Delete from dede_uploads;
ALTER TABLE dede_uploads AUTO_INCREMENT = 1;

dede_uploads表记录所有上传过的文件路径,物理文件删了但表记录还在,附件管理界面就会显示一堆"文件不存在"的项目,影响美观也影响后续审计。

5个生产场景的完整SOP

场景一:测试转正式交付(最常见)

完整步骤:

  1. 做完整数据库备份(必须)
  2. 关闭前台访问
  3. 清三张文章表(archives+addonarticle+arctiny)
  4. 清关键词与搜索词
  5. 清标签
  6. 清评论与留言
  7. 清uploads物理文件 + 附件管理表
  8. 更新主页、栏目、文档HTML
  9. 开放前台访问
  10. 客户验收:发一篇测试文章,确认aid是1

场景二:保留栏目结构只清文章

客户希望栏目分类保留(已经按SEO规划好了),但所有文章重做。这种场景跳过dede_arctype的清空,只清文章相关表。注意清完后栏目的"文章数"统计不会自动归零,要手动跑一遍后台的"文档重新审核"。

场景三:合并多个测试站

把3个测试站合成1个生产站。先清空目标站全部数据,然后从源站SELECT出文章导入目标站。注意typeid(栏目ID)的映射,源站和目标站栏目ID可能不一致,需要先建一张映射表,再用INSERT INTO target ... SELECT ... FROM source ...语法批量导入。

场景四:灾备演练

先备份,再清空,再从备份恢复,最后对比记录数是否一致。这种场景必须用独立的测试数据库实例,不能在生产库上做。恢复后检查关键SQL:SELECT COUNT(*) FROM dede_archivesSELECT MAX(aid) FROM dede_archives这些指标和备份前的快照对比。

场景五:站点改版前的快照

先备份当前数据库到本地(mysqldump --single-transaction),命名为backup_before_redesign_yyyymmdd.sql。然后清空当前数据准备灌入新数据。这种场景的备份必须保留至少6个月,应对客户突然要找旧文章的需求。

4种回滚方案

方案一:mysqldump整库还原

清空前如果做了mysqldump全库备份,回滚就是一行命令:

mysql -u root -p database_name < backup_before_clear.sql

整库覆盖式恢复,1分钟以内完成。要求:备份必须是清空前的完整dump,中间没有其他写入。

方案二:binlog点对点恢复

如果MySQL开了binlog(log_bin=ON),可以从binlog里找到Delete语句之前的时间点恢复:

mysqlbinlog --stop-datetime="2026-05-12 10:30:00" \
  /var/log/mysql/mysql-bin.000123 | mysql -u root -p database_name

精度可以到秒级。要求:开了binlog,并且binlog没有被清理掉。

方案三:单表逐表恢复

只想恢复某一张表(比如不小心多删了文章但不想恢复栏目),用mysqldump导出单表然后mysql导入:

mysqldump -u root -p database_name dede_archives > archives.sql
mysql -u root -p database_name < archives.sql

方案四:Innodb表空间文件恢复

最极端的情况——没备份、没binlog,只有物理文件。Innodb表的.ibd文件包含完整数据,可以用innodb_force_recovery模式启动MySQL尝试读取。这种方式成功率不高(30到50%),仅作为最后手段,不要依赖。

常见问题解答

执行SQL后提示Table doesn't exist是怎么回事?

大多数情况是因为你的织梦版本表前缀不是dede。早期版本默认前缀就是dede,但安装时可以自定义。打开站点根目录的data文件夹下的common.inc.php,找到cfg_dbprefix这一行,看到的就是你站点的真实前缀,把上面所有SQL中的dede替换成你的实际前缀即可。如果是DedeBIZ商业版,前缀可能默认是dedebiz_,要相应修改。还有一种情况:你的MySQL用户没有目标库的权限,执行SHOW TABLES都看不到表,这种要找DBA加权限。

执行后ID没有归零仍然从原来最大值往后加怎么办?

说明你只跑了Delete from却忘了跑ALTER TABLE加AUTO_INCREMENT等于1。Delete只删除数据行,自增计数器仍然记着上一次的最大值,必须显式重置。如果重置后仍然不归零请确认表是InnoDB引擎且MySQL版本足够新;早期MyISAM版本的织梦数据库一般没有这个问题。另外注意:如果Delete之后没有commit就执行ALTER(少数事务模式下),重置可能没生效,重新执行一次ALTER即可。

清空数据后能否撤销恢复?

不能直接撤销。Delete语句一旦提交事务就完成了,没有Ctrl+Z。唯一的恢复方式是从你之前做的数据库备份里还原,或者从MySQL的binlog点对点恢复,要求开了binlog并且没被清掉。所以保哥反复强调:执行任何批量删除前,先做备份、先做备份、先做备份。备份的最低标准是mysqldump整库dump出sql文件并下载到本地一份,加上服务器留一份,两个独立位置降低单点风险。

如果只想清理某一段时间内的测试文章而不是全部清空,怎么写SQL?

这个比较常见,保哥也经常这么干。可以加一个时间条件,比如Delete from dede_archives WHERE pubdate大于等于UNIX_TIMESTAMP两千零一九年十一月一日。但要注意单删dede_archives不够,对应的dede_addonarticle和dede_arctiny也要按aid一起删。可以先把要删的aid查出来用SELECT id FROM dede_archives WHERE pubdate大于等于某时间,然后用DELETE FROM dede_addonarticle WHERE aid IN 括号里aid列表的形式逐表删除比较保险。也可以用JOIN方式一次性删,但JOIN加DELETE的语法在不同MySQL版本表现略有差异,保哥推荐用IN语法更稳。

清空之后前台访问报500错误是怎么回事?

大概率是模板里的arclist标签设置了rownum但数据库里行数不够。比如模板写了rownum等于10但数据库里没有文章,arclist标签可能报undefined index。解决:去模板里把arclist改为容错写法,或者在模板顶部加判断"如果没有文章则显示暂无内容"。还有一种可能:清空后没更新缓存,访问的还是旧缓存里的引用关系,导致模板渲染时找不到对应数据。后台"生成 -> 更新主页"和"更新栏目"跑一遍通常能解决。

DedeCMS 5.7和DedeBIZ的清空命令一样吗?

核心表是一样的,dede_archives三件套、dede_arctype等,但DedeBIZ商业版多了几张商业相关的表,比如dede_addonshop商品、dede_addonproduct产品、dede_addonorder订单等。如果是DedeBIZ站点要清空所有数据,要把这些额外表也加上。执行SHOW TABLES LIKE dede_addon开头看到的所有附加表挨个检查是否要清。

清空之后再发布文章ID依然不是1可能是哪个环节没做到?

三个最可能的原因:第一你的SQL命令行工具实际执行失败但没报错,少数情况下织梦后台SQL工具静默吞掉错误,用phpMyAdmin重新执行ALTER TABLE确认;第二你的表是从备份还原的,备份里包含了AUTO_INCREMENT值,还原后需要再次ALTER重置;第三你用的是分库分表方案,如MyCAT、ShardingSphere,不同分片有不同的自增起点,这种情况需要联系DBA重置全局序列。前两个最常见,第三个比较罕见。

清空时MySQL报deadlock错误怎么办?

说明有其他连接正在写这些表,前台访问、后台编辑都可能触发。解决方法:第一在系统设置里把站点改为关闭状态,让前台返回维护页面;第二SHOW PROCESSLIST看哪些连接在跑,KILL掉非必要连接;第三在SQL命令行工具里加SET autocommit等于0然后START TRANSACTION,最后COMMIT。第四种是分批删除,比如DELETE FROM dede_archives WHERE id between 1 and 1000一次只删1000条,循环执行避免长事务锁表。

写在最后

织梦DedeCMS虽然这几年因为安全更新和版权问题逐渐淡出主流视野,但保哥手上仍有不少老客户的存量站点跑在DedeCMS上,运维交接时这套清空SQL几乎每个月都要用一次。把它整理成上面的标准化流程,既是给自己的备忘,也希望能帮到那些接手老站点、需要在交付前还原一个干净后台的同行。

所有命令都在保哥本地的5.7 SP2 UTF8、5.7 SP2 GBK、DedeBIZ三套环境上反复验证过,按步骤执行不会出现意外。如果你的版本是某些第三方修改版(例如带有DedeBIZ商业插件或某些定制版),表结构可能略有差异,记得先在测试环境跑一遍SHOW TABLES LIKE确认所有表名再上正式服务器。备份永远是底线——任何清空操作前的5分钟备份,能避免事后5小时甚至5天的恢复工作。

分享到
标签
版权声明

本文标题:《织梦DedeCMS数据清空SQL命令8表归零方案》

本文链接:https://zhangwenbao.com/dedecms-batch-clear-data-and-zero-sql-command.html

版权声明:本文原创,转载请注明出处和链接。许可协议: CC BY-NC-SA 4.0

继续阅读
发表评论
分享到微信 或在下方手动填写
支持 Ctrl + Enter 提交