如何在具有复合外键的数据库上创建代理键?

时间:2012-07-03 03:36:56

标签: sql sqlite

我正在研究最初使用复合外键/主键设计的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命令吗?

1 个答案:

答案 0 :(得分: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列。