【问题标题】:Dealing with tags处理标签
【发布时间】:2012-09-27 10:46:09
【问题描述】:

我们正计划使用类似于本网站实施的标记系统。

我们有实际的标记前端,自动完成等工作。

但我对在后端处理它的最佳方式感到困惑。

基本上,当我们在后端获取标签时,我们最终会得到一个如下所示的数组:

array(
  array(
    'value' => 1,
    'label' => 'First Tag'
  ),
  array(
    'value' => 2,
    'label' => 'Second Tag'
  ),
  array(
    'value' => 'Third Tag',
    'label' => 'Third Tag'
  ),
  array(
    'value' => 3,
    'label' => 'Fourth Tag'
  ),
)

标签插件在自动完成时也会通过 ajax 接收相同的数组格式json_encode()'d,它会显示标签,并存储 id 以便将其发回。

因此,具有值123 的标签是从自动完成中选择的标签。
值为Third Tag 的标签是未从自动完成中选择的标签,它可能或可能不存在于数据库中,但已手动输入。

现在有一个变化,用户实际上可以创建一个恰好是数字的标签,因此

array(
  'value' => 3,
  'label' => 3
)

可以通过,但不存在,所以我们不能假设如果 value 是 int 则它已经存在。

所以,这个问题的第一部分是,我如何管理这个问题,这样我就不会得到重复的标签?

我目前的方法是,当标记插件通过自动完成请求标记时,我发回一个数组,如

(术语 = 'pin')

array(
  array(
    'value' => '||1',
    'label' => 'pink'
  ),
  array(
    'value' => '||4',
    'label' => 'pin cushion'
  )
)

然后在后端假设任何具有以 || 开头的值的标签来自自动完成并且已经存在。

那么, 我们在数据库中查询所有标签, 使用其余的标签,我们检查 value 是否存在数组的 label 键,如果存在,我们就保持原样,如果不存在,我们创建它,然后我们切换值在原始数组中使用新的id

但这对我来说感觉很奇怪,这意味着我们正在使用填充项 (||) 必须有更优雅的方式来做到这一点?

问题的下一部分是,实际上将这些标签链接到一个项目。 这更多是在本网站上编辑问题的背景下,

某些标签已与问题相关联。你如何处理它,这样你就不会在一个问题上出现重复的标签引用?

到目前为止,我看到了两个选项: 从问题中删除所有指向标签的链接,然后再次将它们全部插入。(2 个查询)

查询数据库中与问题相关的所有标签,遍历数组,从数组中删除这些标签,然后插入剩余部分。 (2 个查询)

哪一种方法比另一种更好?还是有第三个版本?

【问题讨论】:

    标签: php mysql database-design autocomplete tagging


    【解决方案1】:

    通过在相关字段上添加唯一约束,可以在数据库级别解决任何类型的重复键问题。您的所有代码与标签的交互都应使用文本标签完成,该标签应作为标签的唯一标识符。任何类型的数字 ID 对应用程序本身没有任何用途,因此无需从存储库层后面窥视。这也将解决区分现有/新标签的问题......实际上应用程序并不关心,它将标签视为持久值对象,而不是担心任何类型的实体样式生命周期。在标签与文章关联的存储库调用中,如果标签尚不存在,则创建该标签。在执行标记查询所需的 JOIN 时,ID 将主要有利于性能方面(实际上在其他任何地方都没有),这也是应用程序在执行连接的存储库之外不应该关心的事情。

    更新标签(包括删除)最安全和最简单的方法是删除现有标签并编写新标签。这确保了持久化状态完全一致地匹配 UI 输入,实际上这不会是一个昂贵的操作,也不会经常执行到足以关心(尽管一个简单的程序检查以查看是否需要更新将有助于防止不必要的写)。它是 2 个查询应该包装在一个事务中并且可以一起批处理,只要有适当的索引,DELETE 尤其应该非常便宜,所以它不是您需要担心的那种多重查询。

    如果出于某种奇怪的原因您过于担心最小化数据库的工作,您可以事先存储标签的一个版本,然后再执行适合增量的查询,但这要脆弱得多,并且可能还引入了许多复杂的并发问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      • 2018-05-26
      • 2021-11-10
      • 2011-01-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多