当我开始尝试实现这一点时,我很困惑。
一些业务规则
1帖子可以有很多标签。 1个标签可以有很多帖子
数据库看起来像。
当我插入时 - 直截了当
explode($tags)
获取个人标签我想知道这是不是最好的方法?如果标签存在,我可以取消循环到chk吗?或将其简化为1个查询?
更新一篇文章,更难实现
如何检查用户是否更新了任何标签。另一个循环?但这次会有一些变化(斜体)
explode($tags)
获取单个标签
我正在使用PHP 5.3,Zend Framework 1.10,Doctrine 2
答案 0 :(得分:2)
更新的想法:
答案 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行为。看看这个,这可以帮助。