2014-10-22 74 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」。