2016-09-16 56 views
0

我不太清楚怎么说这个,所以我会举个例子。我有一个程序从用户定义的csv文件读入数据库表。 (我使用的SQLite与Python)你可以有外键约束而不必创建另一个表?

说我们有表:

档案(
    PROFILE_NAME   TEXT,
   分区                      TEXT,
   份额                          REAL
    PRIMARY KEY(PROFILE_NAME,分区),

ProfileAssign(
   地理            TEXT,
年                                INTEGER,
    PROFILE_NAME     TEXT,
    PRIMARY KEY(地理,一年),
    FOREIGN KEY地理参考地理

我们想要每个地区有关联的分区配置文件。现在说我们也希望确保用户不分配不存在的地理轮廓,也就是说,我们希望有在ProfileAssign表的外键约束:

FOREIGN KEY PROFILE_NAME参考profile

现在显然这不可能发生,因为profile_name不是配置文件表的主键。我的解决方案是创建一个单独的表上,我们可以创建一个外键参考:

ProfileListing(
    PROFILE_NAME         TEXT,
    PRIMARY KEY(PROFILE_NAME)

这对用户来说很烦人,因为他们不仅需要定义这些配置文件,他们现在必须在一个单独的文件中列出他们的所有名称。任何想法如何规避这一点?

回答

1

外键需要标识父表中的一行。 这通常与主键完成,但任何其他独特的关键作品;唯一的要求是唯一性强制执行(使用UNIQUE约束):

CREATE TABLE Profile (
    profile_name TEXT UNIQUE, 
    zoning  TEXT, 
    ... 
    PRIMARY KEY (profile_name, zoning) 
); 

CREATE TABLE ProfileAssign (
    ... 
    FOREIGN KEY profile_name REFERENCES profile(profile_name) 
); 
+0

所有DBMS均不要求唯一性。最好将FK约束看作子集约束而不是引用。 – reaanb

+1

SQL标准和符合它的所有DBMS都需要唯一性。如果你告诉我这是MySQL的另一件事(这里没有题目)出错了,我不会感到惊讶。 –

+0

当你声明一个外键时,它必须引用某些东西,或者是同一个表中的另一行,或者是另一个表中的一行。但是,即使数据项没有被声明,数据项也可以像外键一样工作。根据您的CSV文件的来源,您可能正在读取脏数据。如果是这样,最好将数据放入没有约束的登台表中,并将临时表中的干净数据复制到实际表中。 –