2012-10-06 86 views
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当d它自动填充,它显示标签,并存储该ID,以便它可以将其发回。

因此,值为1,2,3的标签是从自动填充中选择的标签。
值为Third Tag的标记是未从自动填充中选择的标记,可能已存在于数据库中,但可能尚未存在但已手动输入。

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

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

能来通过,但尚未存在,所以我们不能想当然地认为,如果值是一个int然后它已经存在。

所以,这个问题的第一部分是,我如何管理这个,所以我没有结束重复标签?

我目前的做法是,当在标记插件通过自动填充请求标签我发回的阵列等

(术语=“销”)

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

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

然后, 我们查询所有标签数据库, 与我们检查,看看是否在value存在数组的label键,如果它不,我们只是离开它是标签的休息,如果它不”我们创建它,然后我们用原始数组中的新id转换出该值。

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

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

一些标签已经链接到一个问题。你如何处理它,这样你就不会在一个问题上得到重复的标签引用?

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

查询数据库中与问题连接的所有标记,遍历数组从数组中移除这些标记,然后插入余数。 (2 queries)

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

回答

2

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

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

如果出于某种奇怪的原因,您过分急于尽量减少数据库的工作,您可以预先存储一个版本的标签,然后进行适合三角洲的查询,但这种方法要脆弱得多,而且也可能引入许多复杂的并发问题。