2014-10-22 77 views
1

在一些数据库重构过程中,我需要引入未来的多对多关系,我偶然发现了一些我认为一定可能的事情。数据库重构为多对多的关系

给定一个原始表:

CREATE TABLE a (
    id serial NOT NULL, 
    field1 varchar, 
    field2 varchar, 
    field3 varchar 
); 

和新创建的表:

CREATE TABLE b (
    id serial NOT NULL, 
    field1 varchar, 
    field2 varchar 
); 

我想FIELD1和FIELD2的内容从移动到B。为了适应多对一对多的关系,关联表也可:

CREATE TABLE a_b (
    aid serial NOT NULL, 
    bid serial NOT NULL 
); 

这里原来的A-ID的和新建的B-ID的应该结束。

因此,如果我像这样

| 33 | John | Jane | Juli | 
| 34 | Fred | Carl | Josh | 

的a-表开始我想看到它在B-表结束:

| 1 | John | Jane 
| 2 | Fred | Carl 

和关联A_B

| 33 | 1 | 
| 34 | 2 | 

原始表将然后删除FIELD1和FIELD2删除,因此我会像这样

| 1 | Juli | 
| 2 | Josh | 

我立即想到使用with-queries,但没有找到办法让它工作。 这显然不起作用:

WITH new AS (
    INSERT INTO b (field1, field2) 
    SELECT field1, field2 FROM a 
    RETURNING id 
) 
INSERT INTO a_b (???, bid) SELECT * FROM new; 

但说明了问题。我没有找到插入b的方法,同时保持与相应的a-id的关系。我认为这一定是可能的。

有什么想法?

瑟伦

PS我omitteded之类的东西为简洁的外键。

回答

0

简洁不是你的朋友。当缺少某些东西时,我们无法判断你是否简短或者是否犯了大错。

CREATE TABLE a (
    id serial primary key, 
    field1 varchar, 
    field2 varchar, 
    field3 varchar 
); 

CREATE TABLE b (
    id serial primary key, 
    field1 varchar, 
    field2 varchar 
); 

“关联”表存储外键;你应该存储“a”的ID号和“b”的ID号。所以应该这样宣布。

CREATE TABLE a_b (
    aid integer NOT NULL, 
    bid integer NOT NULL, 
    primary key (aid, bid), 
    foreign key (aid) references a (id), 
    foreign key (bid) references b (id) 
); 

让我们添加几行到“a”。仔细观察下面第二行和第三行的重复,“Fred”和“Carl”。

insert into a (field1, field2, field3) values 
('John', 'Jane', 'Juli'), 
('Fred', 'Carl', 'Josh'), 
('Fred', 'Carl', 'Abby'), 
('Art', 'Carl', 'Abby'); 

要填充“b”,插入不同的(唯一)组合。

insert into b (field1, field2) 
select distinct field1, field2 
from a; 

select * from b; 
 
id field1 field2 
-- 
1 John Jane 
2 Art  Carl 
3 Fred Carl 

的 “关联” 表需要ID号从 “a”,与来自 “B” 及其相应的ID号一起。你需要加入“a”和“b”。

insert into a_b 
select a.id aid, b.id bid 
from a 
inner join b on a.field1 = b.field1 and a.field2 = b.field2 

现在你可以加入这三个表来查看完整的关联。基于像这样的查询创建视图通常很有用。

select b.id bid, b.field1, b.field2, a.id aid, a.field3 
from a_b 
inner join a on a.id = a_b.aid 
inner join b on b.id = a_b.bid 
order by a.id; 
 
bid field1 field2 aid field3 
-- 
1 John Jane 1 Juli 
3 Fred Carl 2 Josh 
3 Fred Carl 3 Abby 
2 Art  Carl 4 Abby 

当你确信数据是正确的,你可以从下拉列“字段1”和“域2”。