在MySQL中将几列规范化为一对多表

时间:2016-08-19 12:34:19

标签: mysql database many-to-many relational-database

我希望将包含多列数据的表规范化为多对多表。

就我而言,我的person表格包含hobby1hobby2hobby3hobby4字符串列,其中包含hobby中找到的名称1}}表。有些是空的,有些则不是。

目前,db设计如下所示:

original database design

目前person_hobby为空。

您能否帮我使用SQL查询来填充person_hobby表,其中包含与hobby相关的hobby.name列中的所有字符串,以便我以后可以删除它们?

由于

2 个答案:

答案 0 :(得分:3)

E.g:

DROP TABLE IF EXISTS person;

CREATE TABLE person
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,name VARCHAR(12) NOT NULL
,hobby1 VARCHAR(15) NULL
,hobby2 VARCHAR(15) NULL
,hobby3 VARCHAR(15) NULL
,hobby4 VARCHAR(15) NULL
);

DROP TABLE IF EXISTS person_hobby;

CREATE TABLE person_hobby
(person_id INT NOT NULL 
,hobby_id INT NOT NULL
,PRIMARY KEY(person_id,hobby_id)
);

DROP TABLE IF EXISTS hobby;

CREATE TABLE hobby
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,name VARCHAR(15) NOT NULL UNIQUE
);

INSERT INTO person VALUES
(1,'John'  ,'Reading'   ,'Cycling','Swimming',NULL),
(2,'Paul'  ,'Travelling','TV','Bird watching','Cinema'),
(3,'George','Fishing'   ,'Swimming',NULL,NULL),
(4,'Ringo',NULL,NULL,NULL,NULL);

INSERT INTO hobby (name) 
SELECT hobby1 FROM person WHERE hobby1 IS NOT NULL UNION 
SELECT hobby2 FROM person WHERE hobby2 IS NOT NULL UNION 
SELECT hobby3 FROM person WHERE hobby3 IS NOT NULL UNION 
SELECT hobby4 FROM person WHERE hobby4 IS NOT NULL;

INSERT INTO person_hobby
SELECT p.id 
     , h.id 
  FROM
     (
SELECT id
     , hobby1 hobby
  FROM person
 UNION
SELECT id 
     , hobby2 
  FROM person
 UNION
SELECT id 
     , hobby3
  FROM person
 UNION
SELECT id 
     , hobby4
  FROM person
     ) p
  JOIN hobby h
    ON h.name = p.hobby;

Query OK, 9 rows affected (0.05 sec)
Records: 9  Duplicates: 0  Warnings: 0

SELECT * FROM person_hobby;
+-----------+----------+
| person_id | hobby_id |
+-----------+----------+
|         1 |        1 |
|         1 |        4 |
|         1 |        6 |
|         2 |        2 |
|         2 |        5 |
|         2 |        7 |
|         2 |        8 |
|         3 |        3 |
|         3 |        6 |
+-----------+----------+

现在从人员表中删除列。

答案 1 :(得分:0)

重复每个爱好字段(注意hobby1 - 子句中的ON):

INSERT IGNORE INTO person_hobby (person_id, hobby_id) 
     SELECT person.id, hobby.id
     FROM person
     INNER JOIN hobby ON (person.hobby1=hobby.name)