先明确单一来源的含义:同一篇文章、同一条数据只在一个地方录入和修改,其他栏目通过引用或聚合显示它,而不是各存一份。判断该用哪种方式,关键看内容是否需要被独立检索、独立设置发布时间,以及编辑是否愿意接受跨栏目同步的代价。若同一内容要出现在新闻、行业动态和首页推荐三个位置,且三处都要求可被搜索到、可各自排序,那么物理复制往往比强行引用更省事;反之,如果只是首页推荐位和栏目列表展示同一批内容,引用是更稳的选择。
第一种做法是引用式单一来源:内容只存一次,其他栏目通过关联关系、聚合规则或查询条件把它取出来。它成立的前提是各栏目对这条内容的展示需求足够接近,比如都只需要标题、摘要、缩略图和发布时间,不需要各自改写标题、各自设定不同的上下线时间。第二种做法是受控复制:内容在主栏目保留一份,进入其他栏目时生成独立记录,各自拥有标题、排序和发布时间。它成立的前提是各栏目对同一内容的呈现差异较大,或者栏目本身有独立的生命周期,例如活动结束后要单独下架,而主栏目仍需保留。
选择依据可以归结为三条:这条内容是否需要在多个栏目里分别被检索到;各栏目是否需要不同的标题、摘要或排序权重;编辑团队能否接受修改一次即影响多处。三条都偏向“是”时,受控复制更合适;只有展示位置不同、字段基本一致时,引用式更省维护成本。
把内容表与栏目关系表分开,是最常见的落地方式。内容表只存正文、标题、发布时间等本体字段,栏目关系表存内容与栏目的对应关系,附加该栏目下的排序值和显示状态。前台渲染时按栏目查询关系表,再取出内容本体。这样做的一个直接结果是:修改正文只需改一处,所有引用它的栏目同步变化;但若某个栏目想单独改标题,就必须在关系表里增加覆盖字段,否则改不动。
这里有一个实际动作及其影响:给关系表增加一个可空的“栏目内标题”字段。若该字段为空,前台回退到内容本体的标题;若填写了值,则优先显示该值。这个动作的结果是,编辑可以在不改动正文的情况下为不同栏目设置不同标题,代价是标题出现两套来源,后续排查“为什么这个栏目标题和别处不一样”时需要先看关系表。是否值得做,取决于你的栏目是否真的需要差异化标题。
受控复制不是随手复制粘贴,而是要在复制时记录来源标识,让后续能追溯。常见做法是在内容表增加一个来源字段,复制生成的新记录填入原始记录的标识。这样当原始内容发生实质性修改时,可以通过来源字段找到所有副本,决定是否同步。代价是同步逻辑要自己维护,且副本一旦被独立编辑过,自动同步就可能覆盖人工修改,因此通常只对特定字段做同步,比如正文,而不动副本自己的标题和排序。
假设一个场景:某条政策解读同时进入“政策法规”和“行业动态”两个栏目,前者要求按发文时间倒序,后者要求按编辑推荐排序。若用引用式,排序值可以分别存在关系表里,问题不大;但若两个栏目还要求不同的导语,引用式就需要覆盖字段,受控复制则天然支持。此时选择受控复制的代价是,正文若更正一处错别字,需要同步两次,漏掉一次就会出现两个版本。
有些内容天生不适合单一来源。比如同一主题在不同栏目下需要完全不同的正文结构,或者某个栏目只是临时聚合、生命周期只有几天,为它建立引用关系反而增加清理负担。这类情况下,允许独立存在、到期整体删除,比维护引用关系更简单。判断标准是:这条内容的多个出现位置是否共享同一份事实。如果共享,就值得维护单一来源;如果各自承担不同的表达任务,就不必强求。
另一个例外是外部数据。若栏目内容来自接口或第三方推送,本地只做缓存展示,那么“单一来源”在上游,本地不应再建第二份可编辑副本,否则会出现本地改了、下次拉取又被覆盖的情况。此时应把本地记录标记为只读,编辑入口指向上游系统。
这些检查不依赖具体工具,用后台列表或数据库查询都能完成。做完之后,你会更清楚当前这套结构是偏向引用还是偏向复制,也就知道下一次新增栏目时该沿用哪种方式。