如何管理M:N Post-Tag关系(例如编辑/删除)

时间:2010-07-29 13:16:10

标签: php sql doctrine

当我开始尝试实现这一点时,我很困惑。

一些业务规则

1帖子可以有很多标签。 1个标签可以有很多帖子

数据库看起来像。

  • 帖子(身份证,头衔,身体......)
  • Posts_Tags(帖子,标签)
  • 标签(id,tag,...)

当我插入时 - 直截了当

  • 标签将来自用户输入,以逗号分隔值
  • explode($tags)获取个人标签
  • foreach $ tag
    • 检查标签是否存在
    • 如果是,请获取ID
    • 如果不是,请插入标签&得到身份
  • 插入带标签的帖子

我想知道这是不是最好的方法?如果标签存在,我可以取消循环到chk吗?或将其简化为1个查询?

更新一篇文章,更难实现

  • 如何检查用户是否更新了任何标签。另一个循环?但这次会有一些变化(斜体)

  • explode($tags)获取单个标签

  • foreach $ tag
    • 检查此帖子是否已使用此标记标记
    • 如果没有,
      • 标签存在吗?
        • 是的,得到身份
        • 不,插入并获取ID
    • 如果是,请获取ID
  • 使用代码更新帖子
嗯,......更新更令人困惑,你将如何实现?

我正在使用PHP 5.3,Zend Framework 1.10,Doctrine 2

5 个答案:

答案 0 :(得分:2)

更新的想法:

  • 将用户JS启用/禁用的值存储为隐藏值
  • 将onchange事件绑定到标签输入,然后将隐藏变量设置为true,以便您知道标签已更改
  • 如果JS已启用且标签已更改删除所有标签属于此帖子,则插入实际标签(如第一个)
    • 后备:如果JS被禁用,则需要针对已保存的标签检查已提交的标签。

答案 1 :(得分:2)

我的标签非常类似于更新后的伪代码,除了一个额外的步骤。您需要检查以确保该帖子中没有不在用户输入中的标签。例如,如果帖子被标记为“php,sql,doctrine”,并且用户将标记更改为“c#,sql,doctrine”,则必须知道删除php标记。

因此,我的代码循环遍历现有标记以查看需要删除哪些标记,然后我遍历用户提供的标记以查看需要添加的标记。

答案 2 :(得分:2)

我认为后标签关系应该是多对多的;即:帖子拥有并属于许多标签。这可以通过联结表实现。这是关于这个主题的一些literature。然后...

插入:执行与现在相同的操作,但您可以在一个查询中获取所有标记:

SELECT name FROM tags WHERE name IN ($tags)

更新:简单的方法:删除所有当前标签,插入标签就好像它们都是全新的一样。还是......

$tags = explode(',' $_POST['tags']); // remove whitespaces

# delete all current tags that were not included in the edit
DELETE FROM post_tags WHERE post_id=$post_id AND tag_id NOT IN ($tags)

# find out what the current tags are, use a JOIN to find out their labels
SELECT tag_id FROM post_tags WHERE post_id=$post_id
fetch results, remove found tags from $tags, then
foreach new $tag, insert as if they were new

答案 3 :(得分:0)

对于第一个问题,您可以将事物简化为单个查询。 (非参数化)SQL看起来像这样:

SELECT * FROM Tags WHERE name='foo' OR name='bar' OR name='etc'
/* and so on and so forth */

然后,您可以在PHP代码中循环以检查返回了哪些标记;我使用key_exists(“keyname”,$ associativeArrayContainingQueryResults)。

我也会在查询的第二部分做类似的事情。但我不知道性能优势是什么。 SQL可能会更好地缓存来自几个较小查询的结果,但我不知道它总体上会更快。

答案 4 :(得分:0)

我认为Doctrine中有一个Taggable行为。看看这个,这可以帮助。