1

我有表格来组织标签..

文章和文章标签的 3 个表格:

article_tags
---
tag_id *
tag_name

articles
---
article_id *
article_name 

individual_article_tags
----
article_id *
tag_id *

以及 3 个用于图像和图像标签的单独表格

image_tags
---
tag_id *
tag_name

images
---
image_id *
image_name 

individual_image_tags
----
image_id *
tag_id *

我希望文章和图像表仅引用 1 个标签表,而不是像这样的 2 个标签表:

tags
---
tag_id *
tag_name

articles
---
article_id *
article_name 

individual_article_tags
----
article_id *
tag_id *

images
---
image_id *
image_name 

individual_image_tags
----
image_id *
tag_id *

问题是标签有不同的ID,我不知道如何合并它们..

4

1 回答 1

2

首先,tags_unified通过INSERT INTO ...SELECT使用UNION. 结果将是两个表中所有标签的不同集合。

CREATE TABLE tags_unified (
  tags_id INT PRIMARY KEY AUTO_INCREMENT,
  tag_name VARCHAR(64)
);

/* Load up all the tags with new ids */
INSERT INTO tags_unified (tag_name)
  SELECT tag_name FROM article_tags
  UNION
  SELECT tag_name FROM image_tags

然后UPDATE所有的individual_image_tagsinidividual_article_tags用一个JOIN查询来获取新的ID。

UPDATE
  individual_image_tags
  JOIN image_tags ON individual_image_tags.tag_id = image_tags.tag_id
  /* LEFT JOIN the old tags to the new tags by tag_name */
  LEFT JOIN tags_unified ON image_tags.tag_name = tags_unified.tag_name
SET individual_image_tags.tag_id = tags_unified.tag_id
/* And update those which have a match in the new tags table */
WHERE tags_unified.tag_id IS NOT NULL

UPDATE
  individual_article_tags
  JOIN article_tags ON individual_article_tags.tag_id = article_tags.tag_id
  LEFT JOIN tags_unified ON article_tags.tag_name = tags_unified.tag_name
SET individual_article_tags.tag_id = tags_unified.tag_id
WHERE tags_unified.tag_id IS NOT NULL

在运行UPDATE语句之前,将它们重新形成为SELECT语句以验证结果。

SELECT
  individual_image_tags.*, 
  tags_unified.*
FROM
  individual_image_tags
  JOIN image_tags ON individual_image_tags.tag_id = image_tags.tag_id
  LEFT JOIN tags_unified ON image_tags.tag_name = tags_unified.tag_name
WHERE tags_unified.tag_id IS NOT NULL

SELECT
 individual_article_tags.*, 
 tags_unified.*
FROM
  individual_article_tags
  JOIN article_tags ON individual_article_tags.tag_id = article_tags.tag_id
  LEFT JOIN tags_unified ON article_tags.tag_name = tags_unified.tag_name
WHERE tags_unified.tag_id IS NOT NULL

编辑:

LEFT JOINandWHERE子句实际上不应该是必需的,因为应该表中每个现有标记的匹配项tags_unified

评论后更新:

创建临时表并从中重新填充原始链接表可能比删除和重新添加唯一约束或复合键更容易。使用CREATE TEMPORARY TABLE AS SELECT.... 然后从原始表中删除所有行并用于INSERT INTO ... SELECT从临时表中重新填充它。

CREATE TEMPORARY TABLE temp_individual_article_tags AS
    SELECT
     individual_article_tags.article_id 
     tags_unified.tag_id
    FROM
      individual_article_tags
      JOIN article_tags ON individual_article_tags.tag_id = article_tags.tag_id
      LEFT JOIN tags_unified ON article_tags.tag_name = tags_unified.tag_name
    WHERE tags_unified.tag_id IS NOT NULL
于 2013-01-26T23:05:12.697 回答