AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 249217
Accepted
AskingForAFriend
AskingForAFriend
Asked: 2019-09-20 10:27:41 +0800 CST2019-09-20 10:27:41 +0800 CST 2019-09-20 10:27:41 +0800 CST

这个有名字吗?

  • 772

这个有名字吗?

我真的不知道如何描述这种情况,而且,这是一个设计缺陷吗?

T4 有通往 T3 和 T1 的 FK,但我可以通过 T3 到达 T1。

T1、T2 指的是必须与 T4 引用的相同。

情况

terminology foreign-key
  • 2 2 个回答
  • 97 Views

2 个回答

  • Voted
  1. Best Answer
    Peter Vandivier
    2019-09-25T04:33:44+08:002019-09-25T04:33:44+08:00

    这个有名字吗?

    冗余外键或冗余引用

    有关来自该网络的与此(某种)相关的实际用例查询的随机抽样,请参见此处和此处。

    这是设计缺陷吗?

    也许?大概?如果我在审查时遇到它,我肯定会闻到一股代码味道。是否采取行动来改变它(或实施它)需要比目前帖子中更多的信息;并且可能出于“互联网这么说”之外的实际原因而这样做。

    TL;博士:

    你可以做到。但你为什么要?


    正如评论中所指出的,提供示例 DDL 并使用模式通常有助于您自己了解它并帮助其他人更有效地响应。看看这个 DB Fiddle,看看它是否准确地代表了你想要描述的内容。

    create table t1 (
      i int not null primary key
    );
    create table t2 (
      i int not null primary key
        foreign key references t1(i)
        on delete cascade
    );
    create table t3 (
      i int not null primary key
        foreign key references t2(i)
        on delete cascade
    );
    create table t4 (
      i int not null primary key
        foreign key references t3(i)
        on delete cascade
    );
    alter table t4
      add constraint fk_t4_t1
      foreign key (i)
      references t1(i);
    

    如您所见,完全可以定义您描述的关系(至少在我的小提琴平台上),甚至可以强制执行级联关系。但是...如果您尝试将CASCADE操作应用于循环定义的关系,您可能会看到这一点(同样,取决于您的平台)...

    消息 1785 级别 16 状态 0 第 1 行

    在表 't4' 上引入 FOREIGN KEY 约束 'fk_t4_t1' 可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。

    ...数据库引擎会保护您免受自己的伤害;除非你在一些疯狂的奇异 DBMS 中,比如CASCADE允许冗余的PostgreSQL 。

    如果您想可视化适合这种模型的物化关系,它可能看起来像这样......

    select v.v, 
           t1.i t1, 
           t2.i t2, 
           t3.i t3, 
           t4.i t4
    from (values (1),(2),(3),(4),(5)) v (v)
    left join t4 on t4.i = v.v
    left join t3 on t3.i = v.v
    left join t2 on t2.i = v.v
    left join t1 on t1.i = v.v;
    

    ...这可能表明...

    +---+----+----+----+----+
    | v | t1 | t2 | t3 | t4 |
    +---+----+----+----+----+
    | 1 | 1  | 1  | 1  | 1  |
    | 2 | 2  | 2  | 2  | 2  |
    | 3 | 3  | 3  | 3  |    |
    | 4 | 4  | 4  |    |    |
    | 5 | 5  |    |    |    |
    +---+----+----+----+----+
    

    还值得注意的是,前面的小提琴使用和X->X->X“交叉键”样式映射(我已经看到“在野外”以合理的效果使用) - 尽管你的更严格地是......

    X->X->X
    ↳-----⬏
    

    如果实体真正不同,则对模型的另一种可能解释是X->Y->Z专用键映射,如本小提琴所示,对冲突级联有其独特的反应。

    • 2
  2. philipxy
    2019-09-25T02:14:28+08:002019-09-25T02:14:28+08:00

    FK 约束表示引用表的 FK 列的子行值必须是被引用表的相应列的唯一子行值——可能是 PK(主键)子行值。

    每当T (...) references U (...)& U (...) references V (...),T (...) references V (...)对于一些适当的列顺序。我们通过说 FK 约束是可传递的来描述这一点。我们会说后一个 FK 约束是可传递的,并且由前 2 个或任何更长的引用链隐含或者是其结果。如果我们声明/强制执行前 2,我们不需要声明/强制执行后者,因为声明/强制执行前者会强制执行后者。未声明的传递 FK 约束一直是设计的一部分。

    您似乎有 T4 参考 T3 参考 T2 参考 T1 和 T4 参考 T1。T4 引用 T1 是可传递的,由其他引用。所以它的声明和箭头是不必要的/多余的。我们可以将图表描述为具有冗余箭头。

    如果我们有 T1 引用 T4 而不是 T4 引用 T1,那将合理地称为(定向)FK(外键)(约束)循环。

    当有一个循环以相同的 FK 列集开始和结束时,结果是某个表中没有空值的每个 FK 子行值必须唯一地出现在相应列下的每个表中。(带有 NULL 的子行的详细信息取决于 FK MATCH 模式。)

    (在关系模型中,当同一组子行值必须出现在两个地方——不一定是唯一的——它被称为 EQD(平等依赖)约束。)

    如果 FK 列在表的某些子集中全部为 NOT NULL,那么您可以使用适当的列相等性将该子集替换为其表的 INNER JOIN。你可以只有一张桌子。

    带有循环的设计不一定是坏事——但如果所有 FK 目标都是 PK 或 UNIQUE NOT NULL,为什么不只有一个表?但是在某些情况下,我们可能希望为了清晰、对称、性能或其他原因而保持循环。

    通过分解归一化到更高的 NF 总是会引入这些循环。但是我们通常会决定更改我们的设计,让一个组件拥有比原始设计更多的行,这会将一个或多个 FK 从该组件转移到其他组件。

    当前的 SQL DBMS 碰巧不允许 FK 循环,尽管这样做很简单。因此,通常不能声明一个 FK,并且必须由触发器强制执行。(当然,这种不对称性抵消了我们可能在单独的表格中寻求的对称性。)

    • 1

相关问题

  • 什么是残差谓词?

  • “‘连接’表”是否与弱实体相同?

  • 非唯一多列外键

  • 软件工程师和 DBA [关闭]

  • 外键违规 - 不知道为什么

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve