dede多个附加表关联

99ANYc3cd6
预计阅读时长 20 分钟
位置: 首页 DEDE建站 正文

为什么需要多个附加表?

在 DedeCMS 中,主表(如 dede_archives)存储了文章的核心信息,如 ID、标题、发布时间、作者等,但文章的很多内容,比如不同类型的字段(文本、数字、下拉列表、编辑器内容等),如果都放在主表中,会使主表结构变得臃肿且不灵活。

dede多个附加表关联
(图片来源网络,侵删)

为了解决这个问题,DedeCMS 引入了“附加表”(也叫“附加字段”)的概念,你可以为不同的栏目创建不同的附加表,将特定栏目文章的专属字段存放在对应的附加表中,这样做的好处是:

  1. 数据结构清晰:主表只保留通用信息,附加表存放特定信息,便于管理和维护。
  2. 查询效率高:当查询文章时,如果不需要附加表中的字段,数据库不会去扫描附加表,提高了查询速度。
  3. 灵活性高:可以自由地为不同栏目定制不同的字段,而不会影响其他栏目。

实现原理:addtables 字段

关联的核心在于主表 dede_archives 中的 addtables 字段,这个字段是一个字符串,用来存储当前文章所关联的附加表的表名。

  • 当文章没有附加表时addtables 字段的值为空。
  • 当文章有关联的附加表时addtables 字段的值就是附加表的表名,dede_addonarticle

要实现多表关联查询,我们必须先从 dede_archives 表中读取 addtables 字段,获取附加表名,然后再动态地将附加表与主表进行 JOIN 关联。


实战案例:为不同栏目创建不同的附加字段并关联查询

假设我们有以下需求:

dede多个附加表关联
(图片来源网络,侵删)
  • 栏目A:产品介绍
    • 需要额外字段:price (价格)、brand (品牌)、specs (规格)。
  • 栏目B:新闻资讯
    • 需要额外字段:source (来源)、author_intro (作者简介)。

我们将分步实现这个需求。

第一步:创建附加表和字段

  1. 进入后台:登录 DedeCMS 后台。
  2. 找到附加表管理:菜单路径通常是 核心 -> 内容模型管理 -> 附加表管理
  3. 为“产品介绍”栏目创建附加表
    • 点击 增加附加表
    • 表前缀:保持默认 dede_addon
    • 表名:输入 product,系统会自动生成完整表名 dede_addonproduct
    • 字段列表:在这里添加我们需要的字段。
      • 字段名:price,字段类型:数字,最大长度:10,小数位数:2
      • 字段名:brand,字段类型:单行文本
      • 字段名:specs,字段类型:多行文本(文本区域)
    • 点击 确定
  4. 为“新闻资讯”栏目创建附加表
    • 再次点击 增加附加表
    • 表名:输入 news,系统会自动生成完整表名 dede_addonnews
    • 字段列表
      • 字段名:source,字段类型:单行文本
      • 字段名:author_intro,字段类型:多行文本(文本区域)
    • 点击 确定

你的数据库里有了 dede_addonproductdede_addonnews 这两张表。

第二步:为栏目绑定附加表

  1. 进入栏目管理:菜单路径是 频道 -> 栏目管理
  2. 编辑“产品介绍”栏目
    • 找到“产品介绍”栏目,点击后面的 [修改]
    • 在栏目设置中,找到 “绑定附加表” 这个选项。
    • 从下拉菜单中选择 dede_addonproduct
    • 保存。
  3. 编辑“新闻资讯”栏目
    • 同样地,找到“新闻资讯”栏目,点击 [修改]
    • 将其绑定到 dede_addonnews
    • 保存。

重要提示:绑定附加表后,只有在该栏目下发布的新文章才会自动在对应的附加表中生成一条记录,旧文章不会自动拥有。

第三步:发布文章并验证数据

  1. 在“产品介绍”栏目下发布一篇文章,填写标题、内容,并在“高级选项”或“自定义字段”区域填写你刚才创建的 pricebrandspecs
  2. 在“新闻资讯”栏目下发布另一篇文章,填写 sourceauthor_intro
  3. 登录你的数据库管理工具(如 phpMyAdmin),查询 dede_archivesdede_addonproductdede_addonnews 表。
    • 你会看到 dede_archives 表中这两篇文章的 addtables 字段分别被设置为 dede_addonproductdede_addonnews
    • dede_addonproduct 表里有对应文章的 pricebrandspecs 数据。
    • dede_addonnews 表里有对应文章的 sourceauthor_intro 数据。

第四步:编写代码进行多表关联查询(最关键的一步)

这是实现“关联”的核心,我们不能直接写死 JOIN 到某个附加表,因为文章可能属于不同的栏目,我们需要在 PHP 代码中动态构建 SQL 查询语句。

dede多个附加表关联
(图片来源网络,侵删)

下面是一个在首页或列表页调用文章,并显示其附加字段的完整示例代码,这段代码会自动判断文章是否有附加表,并正确关联。

{dede:arclist titlelen='40' row='10'}
    <li>
        <!-- 1. 调用主表中的常规字段 -->
        <a href="[field:arcurl/]">[field:title/]</a>
        <span>发布时间:[field:pubdate function="MyDate('Y-m-d',@me)"/]</span>
        <!-- 2. 调用附加表中的字段(核心逻辑) -->
        [field:array runphp='yes']
            // 获取当前文章的附加表名
            $addtable = @me['addtables'];
            // 如果附加表名不为空,则进行关联查询
            if($addtable != '')
            {
                // 引入数据库操作类
                require_once(DEDEINC.'/dedesql.class.php');
                // 创建一个SQL查询实例
                $dsql = new DedeSql(false);
                // 拼接SQL语句,关联主表和附加表
                // 注意:主表的ID字段是 `id`,而附加表的ID字段是 `aid`
                $query = "SELECT * FROM `{$addtable}` WHERE aid='{@me['id']}'";
                // 执行查询
                $dsql->SetQuery($query);
                $dsql->Execute('one');
                // 获取附加表中的一行数据
                $addfields = $dsql->GetArray('one');
                // 释放资源
                $dsql->Close();
                // 根据附加表名,判断并输出不同的字段
                // strpos() 函数用于查找字符串是否包含另一个字符串
                if(strpos($addtable, 'addonproduct') !== false)
                {
                    // 如果是产品附加表,输出产品相关字段
                    @me = "<br/>品牌:" . $addfields['brand'] . 
                          "<br/>价格:" . $addfields['price'] . "元" . 
                          "<br/>规格:" . $addfields['specs'];
                }
                elseif(strpos($addtable, 'addonnews') !== false)
                {
                    // 如果是新闻附加表,输出新闻相关字段
                    @me = "<br/>来源:" . $addfields['source'] . 
                          "<br/>作者简介:" . $addfields['author_intro'];
                }
                else
                {
                    // 如果是其他附加表,可以在这里扩展
                    @me = '';
                }
            }
            else
            {
                // 如果没有附加表,则输出空
                @me = '';
            }
        [/field:array]
    </li>
{/dede:arclist}

代码逻辑解析

  1. {dede:arclist ...}:循环调用文章列表。
  2. [field:array runphp='yes']...[/field:array]:这是一个强大的标签,允许我们对当前文章的所有字段(存放在 @me 数组中)进行 PHP 操作。
  3. $addtable = @me['addtables'];:从当前文章的数据中,提取出 addtables 字段的值,也就是附加表的表名。
  4. if($addtable != ''):判断是否有附加表。
  5. 动态构建 SQL$query = "SELECT * FROM{$addtable}WHERE aid='{@me['id']}'"; 这是最关键的一步,我们使用变量 $addtable 来拼接 SQL,实现了动态关联。WHERE aid='{@me['id']}' 确保我们只获取到当前文章对应的附加数据。
  6. 判断并输出:通过 strpos 检查附加表名中是否包含我们定义的关键词(如 addonproduct),来决定显示哪些附加字段,这样即使未来增加更多附加表,也可以在这里轻松扩展。

总结与注意事项

  • 核心addtables 字段是关联的“钥匙”,动态构建 JOIN SQL 是关联的“方法”。
  • 性能:这种动态查询方式虽然灵活,但在文章列表非常多时,可能会因为需要为每篇文章执行一次附加表的查询而对性能造成一定影响,对于高并发、大数据量的网站,建议使用更专业的缓存机制或考虑对系统进行深度优化。
  • 除了 arclist,在 listarticle 等标签页中,也可以使用类似的 {field:array} 方法来获取附加字段。
  • 字段名:附加表中的字段名是你在后台自定义的,调用时要确保名称完全正确。
  • 旧数据:为已有栏目新增附加表并绑定后,该栏目下已有的旧文章不会自动拥有附加数据,需要通过后台的“内容维护” -> “一键更新所有栏目”中的相关选项(如果提供)或手动处理来为旧数据补充附加表记录。

通过以上步骤,你就可以在 DedeCMS 中熟练地使用多个附加表,并灵活地调用它们的数据了。

-- 展开阅读全文 --
头像
dede生成静态页为何会显示空白?
« 上一篇 03-15
dede图片水印无法添加怎么办?
下一篇 » 03-15

相关文章

取消
微信二维码
支付宝二维码

目录[+]