2009-05-26 54 views
0

我正在將使用單表繼承的舊項目移動到更加結構化的新數據庫中。我將如何編寫一個SQL腳本來移植它?擺脫STI-SQL將單表拆分爲新的多表結構

舊結構

我已經簡化了易讀性的SQL。

CREATE TABLE customers (
    id int(11), 
    ... 
    firstName varchar(50), 
    surname varchar(50), 

    address1 varchar(50), 
    address2 varchar(50), 
    town varchar(50), 
    county varchar(50), 
    postcode varchar(50), 
    country varchar(50), 

    delAddress1 varchar(50), 
    delAddress2 varchar(50), 
    delTown varchar(50), 
    delCounty varchar(50), 
    delPostcode varchar(50), 
    delCountry varchar(50), 

    tel varchar(50), 
    mobile varchar(50), 
    workTel varchar(50), 
); 

新結構

CREATE TABLE users (
    id int(11), 
    firstName varchar(50), 
    surname varchar(50), 
    ... 
); 

CREATE TABLE addresses (
    id int(11), 

    ForeignKey(user), 
    street1 varchar(50), 
    street2 varchar(50), 
    town varchar(50), 
    county varchar(50), 
    postcode varchar(50), 
    country varchar(50), 
    type ..., 
); 

CREATE TABLE phone_numbers (
    id int(11), 
    ForeignKey(user), 
    number varchar(50), 
    type ..., 
); 
+0

這不是單表繼承,這只是一個非規範化的表。這將是你的工作,構建一個看起來完全一樣的視圖。我們能否編輯OP來反映這確實是這種情況?單表繼承涉及實際的繼承,並且在OP中沒有提及。 – 2009-05-26 18:51:01

回答

1

通過適當的跨數據庫符號的表引用如果合適的話:

INSERT INTO Users(id, firstname, surname, ...) 
    SELECT id, firstname, surname, ... 
     FROM Customers; 
INSERT INTO Addresses(id, street1, street2, ...) 
    SELECT id, street1, street2, ... 
     FROM Customers; 
INSERT INTO Phone_Numbers(id, number, type, ...) 
    SELECT id, phone, type, ... 
     FROM Customers; 

如果你想同時新的和舊的地址(德爾*版本),然後用適當的標記在兩組源列上重複地址操作。同樣,對於這三個電話號碼,重複電話號碼操作。或者在每種情況下使用UNION。

+0

這有點棘手 - 你沒有考慮到3個表之間的關鍵關係。 – Joe 2009-05-26 17:23:35

+0

@Joe - 是的,我是:我在所有三個表中使用相同的ID值。請注意,新表的直接狀態ID是引用新用戶表的外鍵。 Addresses表中的ID列不是獨立的新標識列;它被記錄爲用戶表中值的副本。 – 2009-05-26 17:32:09

1

首先確保備份您的現有數據!

如果您打算使用原始ID字段或生成一個新字段,則該過程是不同的。

假設您打算使用原始數據庫,請確保您有能力在開始之前將id字段插入到表中(如果您正在自動創建數字,則爲SQL Server等效項設置標識插入,不確定是什麼mysql會使用)。 Wirte從舊錶格到父表格的插入:

insert newparenttable (idfield, field1, field2) 
select idfield, field1, field2 from old parent table 

然後根據您需要的字段爲所有子表寫入類似的插入。例如,如果您在不同字段中輸入多個電話號碼,則可以使用聯合所有標記作爲插入選擇。

Insert newphone (phonenumber, userid, phonetype) 
select home_phone, id, 100 from oldparenttable 
union all 
select work_phone, id, 101 from oldparenttable 
Union all 
select cell_phone, id, 102 from oldparenttable 

如果您要生成一個新的ID,那麼創建一個帶有舊ID的字段的表。最後可以放棄這個(儘管我會保留它六個月)。然後,可以將新父表連接到oldid上的舊父表,並在插入子表時從新父表中獲取新ID。就像:

Insert newphone (phonenumber, userid, phonetype) 
select home_phone, n.id, 100 from oldparenttable o 
    join newparenttable n on n.oldid = o.id 
union all 
select work_phone, n.id, 101 fromoldparenttable o 
    join newparenttable n on n.oldid = o.id 
Union all 
select cell_phone, n.id, 102 from oldparenttable o 
    join newparenttable n on n.oldid = o.id