Database 对所有父母/祖父母等在每个子表上使用外键的优点/缺点?

Database 对所有父母/祖父母等在每个子表上使用外键的优点/缺点?,database,database-design,Database,Database Design,将所有子表作为外键链接到层次结构中它们上面的所有表有什么危害(如果有的话)?我有一个包含6个查找表的位置组件: 大陆 国家 地区 城市 社区 位置类型 显然,每一级位置都是上述位置的子级,因此它将为父级提供外键,但如果我将所有位置的外键都加在一起,那有什么害处,即我的城市表有: 城市表 大陆id(fk到大陆) 国家/地区id(fk到国家/地区) 区域id(fk到区域) vs仅具有“区域\u id-fk到区域” 我所看到的好处是,如果我必须查找一个大陆上的城市,我可以直接从一个城市到另一个

将所有子表作为外键链接到层次结构中它们上面的所有表有什么危害(如果有的话)?我有一个包含6个查找表的位置组件:

  • 大陆
  • 国家
  • 地区
  • 城市
  • 社区
  • 位置类型
显然,每一级位置都是上述位置的子级,因此它将为父级提供外键,但如果我将所有位置的外键都加在一起,那有什么害处,即我的城市表有:

城市表

  • 大陆id(fk到大陆)
  • 国家/地区id(fk到国家/地区)
  • 区域id(fk到区域)
vs仅具有“区域\u id-fk到区域”

我所看到的好处是,如果我必须查找一个大陆上的城市,我可以直接从一个城市到另一个大陆,而不必先跳到一个地区,然后跳到另一个国家,然后跳到另一个大陆,但我当然不确定其缺点,或者这是否会影响性能或其他方面

这是一套桌子。我有很多这样的表,所以我试图理解这个概念,以便我可以使用它在我的其他组件上设计其他表,这些组件远远超过6个查找表。

危害在于(也称为重复)数据

如果已经有FK链接,则在层次结构的最后一个表中重复它们意味着重复数据,如果需要更改,则不会在多个位置重复数据

此外,对于多FK方案,除非您添加更多检查约束,否则您可能会在
城市
表中得到不一致的数据(其中一个国家和大陆不匹配)。

危害在于(也称为重复)数据

如果已经有FK链接,则在层次结构的最后一个表中重复它们意味着重复数据,如果需要更改,则不会在多个位置重复数据


此外,对于您的多FK方案,除非您添加更多的检查约束,否则您可能会在
城市
表中得到不一致的数据(其中一个国家和大陆不匹配)。

@mikey-对不起,我认为我没有资格对另一个答案发表评论-无论如何:

对于非规范化的单表方法,五(六)列上的复合主键是否足够


在决定单表非规范化方法还是多表规范化方法时,另一个需要考虑的问题是,您为更高级别的实体存储了哪些其他属性?例如,您只是存储城市名称,还是还需要纬度/经度对、电话拨号码之类的东西?您想要存储的属性越多,在非规范化模型中得到的重复(以及相关的数据管理问题)就越多。

@mikey-对不起,我认为我没有资格对另一个答案发表评论-无论如何:

对于非规范化的单表方法,五(六)列上的复合主键是否足够


在决定单表非规范化方法还是多表规范化方法时,另一个需要考虑的问题是,您为更高级别的实体存储了哪些其他属性?例如,您只是存储城市名称,还是还需要纬度/经度对、电话拨号码之类的东西?要存储的属性越多,在非规范化模型中得到的重复(以及相关的数据管理问题)就越多。

我通常不会以这种方式执行传递外键。一般来说,这会导致很多额外的头痛和许多额外的问题机会。保持简单。我不认为这本身就是一个非规范化问题。这只是一个让事情易于管理的问题。考虑以下事项:

CREATE TABLE employee (
    control code text primary key,
    date_of_birth date not null,
    ..,..
    id serial not null unique
);

CREATE TABLE wage_salary ( -- owners have drawings, not salaries, so this avoids nulls
    employee_id int not null references employee(id),
    wage_amt numeric not null,
    per_interval interval not null,
    primary key (employee_id)
);

CREATE TABLE reported_wages ( -- for tax purposes
    employee_id int not null references wage_salary,
    year int not null,
    reported_wages numeric not null,
    PRIMARY KEY (employee_id, year),
    FOREIGN KEY (employee_id) REFERENCES employee(id) -- unnecessary and troublesome
);

在很多情况下,多余的外键会咬你。因为它是以传递方式强制执行的,所以请将其关闭。

我通常不会以这种方式执行传递外键。一般来说,这会导致很多额外的头痛和许多额外的问题机会。保持简单。我不认为这本身就是一个非规范化问题。这只是一个让事情易于管理的问题。考虑以下事项:

CREATE TABLE employee (
    control code text primary key,
    date_of_birth date not null,
    ..,..
    id serial not null unique
);

CREATE TABLE wage_salary ( -- owners have drawings, not salaries, so this avoids nulls
    employee_id int not null references employee(id),
    wage_amt numeric not null,
    per_interval interval not null,
    primary key (employee_id)
);

CREATE TABLE reported_wages ( -- for tax purposes
    employee_id int not null references wage_salary,
    year int not null,
    reported_wages numeric not null,
    PRIMARY KEY (employee_id, year),
    FOREIGN KEY (employee_id) REFERENCES employee(id) -- unnecessary and troublesome
);

在很多情况下,多余的外键会咬你。因为它是临时强制执行的,所以请将其关闭。

但这里什么比什么更重要?更好的做法是进行2-3-4次联接以到达父表,还是通过fks将其非规范化,以便每个人之间都有直接关系?我假设因为所有的表都是通过FK关联的,所以不存在重复,因为它们都是相关的。所以我不能在一张表中输入“纽约”,在下一张表中输入“纽约”。因此,同样的数据将存在——是的,但在所有表格中都是准确的。这是一个社交网络,所以性能很重要,因此我不确定。@mikey-通过你的多FK计划,你可以在美国和非洲拥有一个城市,除非你增加更多的检查限制。例如:芝加哥到伊利诺伊州到美国再到北美。是的,若我在城市表格中输入了一个错误的fK id,那个么它可能会出现在芝加哥、伊利诺伊、非洲和北美。但我假设这就是它会出错的地方,因为在区域表中有芝加哥到伊利诺伊州和伊利诺伊到美国的FK,所以它不会检查“伊利诺伊到非洲”在区域表中是否无效,从而阻止在城市表中芝加哥到非洲的链接吗?@mikey-它不会检查整个层次结构的FK。如果将FK定义到“国家”表中,它将确保一个有效的国家,将另一个定义到“大陆”表中,它将确保它是一个有效的大陆。它不会确保从一个国家到另一个大陆的FK与您的表中的FK相同。嗯,如果有,如何强制mysql检查整个层次结构或层次结构的一部分,以确保FK的有效性?一定有b