我正在尝试制作基于CMS /博客的标签。没有什么复杂的,因为这主要是一个学习练习。我使用PHP和MySQL,虽然我怀疑使用自定义数据库代码写入磁盘会更容易。
无论如何,我希望有两个表,一个标签列表,一个名称和ID,一个帖子列表,包含内容,以及与之关联的标签ID列表。但是,您似乎无法将一个整数数组放在表的单个字段中。所以我制作了第三个表,posttags,其中包含OwningPost和TagID。表中有多个重复的OwningPost,每个都有不同的TagID,因此帖子可以有多个标签。这看起来不是很干净,但我想不出更好的事情。
现在,我希望获得包含特定标签的所有帖子的列表,并且没有其他标签。我甚至没有得到not标签,我仍然卡在包含指定标签的帖子上。我有这段代码:
printPostsTagged(array('Blog Post'),array('First'));
function printPostsTagged($iTags,$eTags)
{
$tagQ="SELECT ID from tags WHERE (";
for($i=0;$i<count($iTags)-1;$i++)
$tagQ=$tagQ."Name='".$iTags[$i]."' OR ";
$tagQ=$tagQ."Name='$iTags[$i]')";
$tagR=mysql_query($tagQ);
...
通过将所有iTags(包含的标签)与OR串联在一起进行查询,这将获得iTags中每个标签的ID列表,现在我想使用整个列表从邮政标签中选择OwningPost,然后使用该索引列表从posts表中获取所有相应帖子的列表。
之前我没有使用过SQL,但我的谷歌搜索似乎没有任何改变,我得到强烈的感觉我在这里做了一些完全错误的事情
答案 0 :(得分:2)
有关良好的表架构,请查看:http://forge.mysql.com/wiki/TagSchema#Recommended_Architecture
通常,商品不会被标签“name”查询,而是通过标签ID或标签slug来查询,无论如何,您可以使用JOIN来简化您的功能:
function printPostsTagged($iTags, $eTags) {
$in = '"' . implode('", "', array_map('mysql_real_escape_string', $iTags)) . '"';
$sql = "SELECT p.* FROM posts p
INNER JOIN post_tag pt ON pt.post_id = p.post_id
INNER JOIN tags t ON pt.tag_id = t.tag_id
WHERE name IN ($in)";
// it removes duplicates and fetch just the posts with all the iTtags assigned
$sql .= " GROUP BY p.id HAVING COUNT(p.id) = " . count($iTags);
}
答案 1 :(得分:1)
你的数据库设计实际上是正确的 - 我想不出比使用3个表更简洁的方法。您的SQL查询应如下所示:
SELECT * FROM content_table INNER JOIN OwningPost ON content_table.postID = OwningPost.postID WHERE OwningPost.tag = 'tag1' OR OwningPost.tag = 'tag2' etc...
如果有,请告诉我......
答案 2 :(得分:0)
答案 3 :(得分:0)
您的第三个表格是加入表格或链接表格。这是建模它的正确方法。正是这些关系构成了关系数据库关系。正如布兰登指出的那样,你应该使用子查询。不要担心您可能会丢弃第一个查询中的数据。没关系。另外,正如ThiefMaster所指出的,你应该尽可能使用 IN 而不是 OR 。