【问题标题】:Can you have foreign key constraint without having to create another table?你可以有外键约束而不必创建另一个表吗?
【发布时间】:2017-01-24 22:16:12
【问题描述】:

我不太清楚如何用这个词,所以我举个例子。我有一个程序可以从用户定义的 csv 文件中读取它的数据库表。 (我在 Python 中使用 SQLite。)

假设我们有桌子:

个人资料(
profile_name 文本,
分区            TEXT,
分享             真实
主键(profile_name,分区),
)

ProfileAssign (
地理      TEXT,
年               整数,
profile_name  TEXT,
主键(地理、年份),
外键地理参考地理
)

我们希望每个地理区域都有相关的分区配置文件。现在假设我们还想确保用户不会将不存在的配置文件分配给地理,即我们希望在 ProfileAssign 表中有一个外键约束:

FOREIGN KEY profile_name REFERENCES profile

现在显然这不可能发生,因为 profile_name 不是 Profile 表的主键。我的解决方案是创建一个单独的表,我们可以在该表上创建外键引用:

个人资料列表(
profile_name    TEXT,
主键 (profile_name)
)

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

【问题讨论】:

    标签: python-3.x database-design sqlite


    【解决方案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)
    );
    

    【讨论】:

    • 并非所有 DBMS 都要求唯一性。最好将 FK 约束视为子集约束而不是参考。
    • SQL 标准以及所有符合该标准的 DBMS 都要求唯一性。如果你告诉我这是 MySQL(这里不是主题)出错的另一件事,我不会感到惊讶。
    • 当你声明一个外键时,它必须引用一些东西,要么是同一张表中的不同行,要么是不同表中的一行。但是,数据项可以像外键一样发挥作用,即使它没有被声明为外键。根据 CSV 文件的来源,您可能正在读取脏数据。如果是这样,您最好将数据无限制地放入临时表中,并将干净的数据从临时表复制到真实表中。
    猜你喜欢
    • 1970-01-01
    • 2011-01-26
    • 1970-01-01
    • 1970-01-01
    • 2018-05-01
    • 2019-01-04
    • 1970-01-01
    • 2011-04-22
    • 1970-01-01
    相关资源
    最近更新 更多