织梦栏目id重复如何排查
织梦栏目 id 是 dede_arctype 表的主键 id,理论上自增唯一。但实际运维中偶尔出现“两个栏目显示同样的 id”或“生成栏目页指向错误栏目”的现象,通常不是真的主键重复,而是缓存、自定义字段或模板调用问题。本文给出系统化排查路径。
一、症状与可能原因
| 症状 | 典型原因 |
|---|---|
| 后台两个栏目显示同一 id | 栏目排序缓存未刷新 / 表损坏 |
| 前台生成指向错误栏目 | 模板里 typeid 写死或 reid 错乱 |
| 移动/删除后栏目消失 | arctype 表 ispart 字段异常 |
二、第一步:核对数据库真实数据
宝塔面板 → 数据库 → phpMyAdmin,执行:
SELECT id, typename, reid, topid, ispart, sortrank
FROM dede_arctype
ORDER BY id;
重点检查:
- 是否有真的重复 id(主键冲突几乎不可能,除非表损坏);
reid(父栏目)和topid(顶级栏目)是否指向已删除的 id;ispart是否为 0(列表)或 1(封面)或 2(外部链接),异常值会导致栏目不显示。
如怀疑表损坏,执行修复:
REPAIR TABLE dede_arctype;
OPTIMIZE TABLE dede_arctype;
三、第二步:检查栏目缓存
织梦把栏目数据缓存在 /data/cache/inc_catalog_base.php。后台修改栏目后未刷新缓存,可能出现显示与实际不符。
处理方式:
- 后台
系统 - 系统设置 - 清除缓存; - 手动删除
/data/cache/inc_catalog_base.php; - 重新登录后台,让织梦重建缓存。
该缓存文件是 PHP 数组格式,删除后系统会自动重建,不会丢数据。
四、第三步:检查模板中的 typeid
很多“栏目 id 重复”的错觉,源于模板里写死了 typeid。例如:
{dede:arclist typeid='5' row='10'}
<a href="[field:arcurl/]">[field:title/]</a>
{/dede:arclist}
如果栏目 5 已经被删除或迁移,arclist 仍会按 5 取数据,造成“栏目内容错位”的假象。建议:
- 用
typeid='top'或typeid='self'等动态写法; - 定期用
grep -rn "typeid='5'" /templets全站扫描硬编码 id。
五、第四步:检查自定义字段与多站点
使用了“栏目自定义字段”或开启了多站点(不同域名绑定不同栏目)时,dede_arctype 表会多出 sitepath、moresite 等字段。如果同 id 出现在多个站点,多半是多站点配置导致同 id 但不同 siteurl。查询:
SELECT id, typename, siteurl, moresite FROM dede_arctype WHERE moresite=1;
六、第五步:日志回溯
查看 /data/log/ 与宝塔 Nginx 访问日志,定位栏目异常出现的时间点,再对照后台操作记录或备份,找出是哪次修改引发的。建议保留每周一次的 dede_arctype 表导出,便于回滚。
七、修复建议
1. 父子关系错乱
用一条 SQL 修复 topid:
UPDATE dede_arctype a
JOIN dede_arctype p ON a.reid=p.id
SET a.topid=IF(p.reid=0, p.id, p.topid);
2. 真的出现了重复 id(罕见)
先备份,再保留较小 id,把较大 id 的文档迁移:
UPDATE dede_archives SET typeid=旧id WHERE typeid=重复id;
DELETE FROM dede_arctype WHERE id=重复id;
3. 重建栏目静态
修复后务必 后台 - 生成 - 更新栏目 HTML,并更新 sitemap。
八、注意事项
- 任何对 arctype 表的直接修改前都要完整备份该表;
- 不要手工把自增 ID 改回较小值,会引发后续插入冲突;
- 多管理员站点要关闭“允许后台直接编辑栏目 id”选项;
- 升级织梦版本前先检查 arctype 表结构,避免字段缺失。
栏目 id 问题本质上是数据一致性问题,排查时先信数据库、再信缓存、最后看模板。把“定期备份表 + 清缓存 + 模板硬编码扫描”纳入日常巡检,能避免绝大多数所谓“id 重复”的故障反复出现。