规范化多对多数据

Normalize many-to-many data

我有一个以这种方式建立多对多关系的非规范化数据库。

文章table:

| id  | category_ids | some_more_columns |
| --- | ------------ | ----------------- |
| 1   | []           |                   |
| 2   | [1, 2]       |                   |
| 3   | [3]          |                   |

类别table:

| id  | some_more_columns |
| --- | ----------------- |
| 1   |                   |
| 2   |                   |
| 3   |                   |

我想建立一个适当的多对多关系,例如:

文章table:

| id  | some_more_columns |
| --- | ----------------- |
| 1   |                   |
| 2   |                   |
| 3   |                   |

类别table:

| id  | some_more_columns |
| --- | ----------------- |
| 1   |                   |
| 2   |                   |
| 3   |                   |

最后,文章有类别 table:

| id  | article_id | category_id |
| --- | ---------- | ----------- |
| 1   | 2          | 1           |
| 2   | 2          | 2           |
| 3   | 3          | 3           |

我想编写一个脚本来使用 MySQL 中文章 table 中的 category_ids 列来填充 Article_has_categories 的 table。 我在 SQL 还很年轻,所以这让人不知所措。 请发光!

您必须将类别 ID 数组转换为单独的行。您可以通过连接派生的 table 整数来做到这一点。看起来数组是 JSON 格式,所以你可以使用 MySQL's JSON_EXTRACT() function.

INSERT INTO Article_has_categories (article_id, category_id)
 SELECT a.id, JSON_EXTRACT(a.category_ids, CONCAT('$[', num.num, ']'))
 FROM Article AS a
 CROSS JOIN (SELECT 0 AS num
  UNION SELECT 1 
  UNION SELECT 2 
  UNION SELECT 3 
  ...as many as the longest list of category_id...
 ) AS num
 WHERE JSON_EXTRACT(a.category_ids, CONCAT('$[', num.num, ']'));

(我还没有测试过这个,但它应该能让你入门。)

如果这太难了,那么另一种解决方案是开发代码来进行转换。您将必须编写一个程序来获取 category_ids 数组,将其分解为单个值,然后遍历它们以将行插入 Article_has_categories.

如果这还是太难了,那么你应该聘请软件开发人员来做。