2

我们正计划使用类似于在该站点上实施的标记系统。

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

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

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

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'
  ),
)

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

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

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

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

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

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

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

(术语='别针')

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

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

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

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

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

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

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

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

任何一种方法都比另一种更好吗?还是有第三个版本?

4

1 回答 1

2

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

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

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

于 2012-10-06T14:22:48.313 回答