Php 处理标签

Php 处理标签,php,mysql,database-design,autocomplete,tagging,Php,Mysql,Database Design,Autocomplete,Tagging,我们正计划使用一个类似于在这个网站上实现的标签系统 我们有实际的标签前端和自动完成等工作 但我是一个很好的人,但对于在后端处理它的最佳方式感到困惑 基本上,当我们在后端获得标记时,我们最终得到一个如下所示的数组: array( array( 'value' => 1, 'label' => 'First Tag' ), array( 'value' => 2, 'label' => 'Second Tag' ), arr

我们正计划使用一个类似于在这个网站上实现的标签系统

我们有实际的标签前端和自动完成等工作

但我是一个很好的人,但对于在后端处理它的最佳方式感到困惑

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

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\u encode()
'd。当它自动完成时,它会显示标签,并存储id以便将其发送回

因此,具有值
1
2
3
的标记是从自动完成中选择的标记。
值为
Third tag
的标记不是从自动完成中选择的,可能存在,也可能不存在于数据库中,但已手动键入

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

array(
  'value' => 3,
  'label' => 3
)
可以通过,但还不存在,所以我们不能假设如果值是int,那么它已经存在

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

我目前的方法是,当标签插件通过autocomplete请求标签时,我会发回一个数组,如

(术语='pin')

然后在后端,假设任何以| |开头的标记都来自自动完成,并且已经存在

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

但这让我感觉很不舒服,这意味着我们使用的是填充项(
|
),一定有更优雅的方式来做吗

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

某些标记已与问题链接。如何处理它,以免在一个问题上出现重复的标记引用

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

查询数据库中与问题相关的所有标记,在数组上循环,从数组中删除这些标记,然后插入其余标记。(2项查询)


两种方法都比另一种好吗?或者是否有第三个版本?

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

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

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

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