如何规范化标签表

时间:2012-09-07 13:08:00

标签: php mysql database normalization

我有这样的表:

post:
+----------------+-----------+
| article_id     | tags      | 
+----------------+-----------+
| 1              |  x1,x2,x3| 
| 2              |  x1,x4,x5 | 
+----------------+-----------+

我想要做的是将其标准化,所以我再创建两个表:

tags:
+----------------+-----------+
| tag_id         | tag_name  | 
+----------------+-----------+
| 1              |    x1     | 
| 2              |    x2     | 
| 3              |    x3     |
+----------------+-----------+

post_tag:
+----------------+-----------+
| id_post         | id_tag  | 
+----------------+-----------+
| 1              |    1     | 
| 1              |    2     | 
| 2              |    1     |
+----------------+-----------+

我已经将所有标签从post表导出到tags表,现在每个标签在tags表中都有自己的id,但是当我在考虑如何使用post_tag表时,我很困惑?

编辑:questin是如何填充post_tag表,查询的样子如何?

尝试这样

$sql=mysql_query("SELECT * FROM post"); 
    while($row=mysql_fetch_array($sql)) {
        $article_id=$row['article_id'];
  $all_tags =$row['tags'];      
  $tags= explode(",",$all_tags);                                
    foreach($all_tags as $tag) {
     $sql2=mysql_query("SELECT * FROM tags WHERE tag_name = '$tag'");
      while($row=mysql_fetch_array($sql2)) {                               $tag_id=$row['tag_id'];                                  $q = "INSERT INTO post_tag (id_post, id_tag) VALUE ('$article_id', $tag_id')";
        $r = mysql_query($q);
      }
    }
}

但它没有写完整的post_tag表

4 个答案:

答案 0 :(得分:1)

对于帖子所拥有的每个标记,您都可以在post_tag表中插入一个条目。它被称为m-to-n关系。谷歌吧;)

  • post_id:1,tag_id:1
  • post_id:1,tag_id:2
  • post_id:1,tag_id:3

  • POST_ID

标签

  • TAG_ID
  • TAG_NAME

post_tag

  • POST_ID
  • tag_id

答案 1 :(得分:1)

我知道,你想用一个sql查询解决你的问题,但这不方便。尝试使用php-power,你就会成功。

php的方式。 1.创建表tagsposts_tags(就像您在问题中描述的那样)。 2.在php中获取当前post表中的所有行并循环它:

foreach($query_results as $row) {
  $article_id = $row['article_id];
  $tags = explode('|', $row['tags']);
  foreach($tags as $tag) {
    // here check if this tag exists in your new `tags` table (by tag's name). If it is, save its id in $tag_id variable.
    // if a tag don't exists then insert it. And put its new id (mysql returns it after inserting) into $tag_id.
    // After that add a row ($article_id, $tag_id) to table `posts_tags`
  }
}

然后从旧tags表中删除列post。利润!

P.S。在tags表中的标记名称和posts_tags表中的对(article_id,tag_id)上创建唯一索引。

答案 2 :(得分:1)

也许这个会起作用?

$sql= mysql_query("SELECT * FROM post"); 
while($row=mysql_fetch_array($sql)) {
    $article_id=$row['article_id'];
    $all_tags = $row['tags'];      
    $tags = explode(",",$all_tags);              
    foreach($all_tags as $tag_title) {
        $tag_id = null;
        $tag=mysql_fetch_assoc(mysql_query('SELECT * FROM tags WHERE tag_name = "'.$tag_title.'"'));
        if ($tag) {
            $tag_id = $tag['tag_id']; 
        } else {
            mysql_query('INSERT INTO tags SET tag_name = "'.$tag_title.'"');
            $tag_id = mysql_insert_id();
        } 
        $q = "INSERT INTO post_tag (id_post, id_tag) VALUE ('$article_id', $tag_id')";
        $r = mysql_query($q);
    }
}

运行循环后,您需要删除post

中的旧列

答案 3 :(得分:0)

假设您有一个名为my cat!的帖子,其ID为1。您希望将标记catshome添加到其中。

您应首先在代码表中创建代码catshome(如果它们尚不存在)。我们可以说它们是cats | 2home | 4(数字是他们的ID)。

然后,您需要在post_tag表中存储值1 | 21 | 4,其中第一个值是帖子的ID,第二个值是标签的ID。

要查找第1号帖子的标签,您需要类似

的内容

SELECT Tags.name FROM Tags, Tags_Posts WHERE Tags_Posts.post_id = 1 AND Tags.id = Tags_Posts.tag_id