2012-07-03 64 views
0

我正在處理最初使用複合外鍵/主鍵設計的SQLite數據庫模式,並試圖將其更改爲使用代理鍵代替。爲代理鍵創建一個新的列很容易,但是現在我需要將代理鍵鏈接回父表 - 最好的方法是什麼?如何使用複合外鍵在數據庫上創建代理鍵?

舊架構摘錄:

CREATE TABLE "parent" (
    "caseid" TEXT NOT NULL, 
    "issueid" INTEGER NOT NULL, 
    "data" TEXT, 
    PRIMARY KEY("caseid", "issueid") 
) 

CREATE TABLE "child" (
    "caseid" TEXT NOT NULL, 
    "issueid" INTEGER NOT NULL, 
    "childdata" TEXT, 
    FOREIGN KEY("caseid", "issueid") REFERENCES parent("caseid", "issueid") 
) 

新的模式摘錄:

CREATE TABLE "parent" (
    "id"  INTEGER PRIMARY KEY, 
    "caseid" TEXT NOT NULL, 
    "issueid" INTEGER NOT NULL, 
    "data" TEXT 
) 

CREATE TABLE "child" (
    "id"  INTEGER PRIMARY KEY, 
    "childdata" TEXT, 
    "parent_id" INTEGER REFERENCES parent("id") 
) 

我的問題是,填補了新的子表從原來的子表中的數據,以後我怎麼填「parent_id」字段,現在是代理鍵而不是複合外鍵?有沒有一種簡單的方法來做到這一點作爲一個SQL命令?

回答

2

首先改變child表通過追加新id列,但(還)沒有拆除舊caseid + issueid列:

CREATE TABLE "parent" (
    "id"  INTEGER PRIMARY KEY, 
    "caseid" TEXT NOT NULL, 
    "issueid" INTEGER NOT NULL, 
    "data" TEXT 
); 

CREATE TABLE "child" (
    "id"  INTEGER PRIMARY KEY, 
    "caseid" TEXT NOT NULL, 
    "issueid" INTEGER NOT NULL, 
    "childdata" TEXT, 
    "parent_id" INTEGER REFERENCES parent("id") 
); 

更新child.parent_id一些有意義的值:

UPDATE child 
SET parent_id = (
    SELECT parent.id 
    FROM parent 
    WHERE parent.caseid = child.caseid 
    AND parent.issueid = child.issueid 
); 

現在您可以放心地刪除childcaseid/issueid列。

+0

謝謝!我正在收斂到類似的解決方案,但我暫時忘記了如何使用select語句更新行。 (也太糟糕SQLite不允許你直接刪除列 - 我必須做一個額外的步驟複製一個表與新的數據刪除多餘的列,但否則它的工作完美) –

+0

通過使用CREATE TEMPORARY VIEW '如果需要的話,可以只使用一個完整的表格副本:) – biziclop