【问题标题】:Why is a primary-foreign key relation required when we can join without it?当我们可以在没有它的情况下加入时,为什么需要主外键关系?
【发布时间】:2011-04-24 14:51:28
【问题描述】:

如果我们可以在没有主外键关系的情况下从两个表中获取数据,那么为什么我们需要这个规则呢?你能用合适的例子清楚地解释我吗? 这是一个测试数据库,不要介意糟糕的结构。

表格结构:

**

table - 'test1'
columns - id,lname,fname,dob
no primary and foreign key and also not unique(without any constraints)

**

**table - 'test2'
columns- id,native_city
again, no relations and no constraints** 

我仍然可以使用相同的列 'id' 加入这些表, 那么如果没有主外键,那有什么用呢?

【问题讨论】:

标签: sql database


【解决方案1】:

主键和外键的主要原因是强制数据一致性。

主键强制一个或多个列的值的唯一性保持一致。如果 ID 列具有主键,则不可能有两行具有相同的 ID 值。如果没有该主键,许多行可能具有相同的 ID 值,您将无法仅根据 ID 值区分它们。

外键强制指向其他地方的数据保持一致。它确保所指向的数据确实存在。在典型的父子关系中,外键确保每个子节点始终指向父节点并且父节点确实存在。如果没有外键,您可能会“孤立”指向不存在的父级的子级。

【讨论】:

  • 你能举个例子吗?
  • 没有主 ID test1 可能有 ''' id:1234 lname:wade fname:ka dob:1/1/1903 id:1234 lname:someone fname:elseWithSameID dob:1/1/1995 id :1234 lname:wade fname:ka dob:1/1/2016 // 同一个人有两条不同的记录
  • 没有外键,test1 可能有 id:1 lname:Renshaw id:3 lname:kawade。虽然 test2 可能有 id:1 Brooklyn id:2 Far-Rockaway id:3 Montreal。这将是不一致的,因为没有 ID 为 2 的 test1 记录。在 SQL 中定义外键使得您无法创建 ID 为 2 的 test2 记录,如果值 2 的 id 也不存在于 test1 中。如果 test2 中存在 id 值为 3 的记录,它也不允许您删除 test1 中 id 值为 3 的记录。
  • 这并不能回答问题。答案是肯定的,你可以。后果是其他问题。
【解决方案2】:

您需要两个相同类型的列,每个表上一个,才能加入。它们是主键还是外键都没有关系。

【讨论】:

  • 难道它们只需要在 JOIN 表达式中具有相同的类型,即对结果进行强制转换和 JOINing 也可以吗?
  • 主键和外键首先是关于规范化和参照完整性,其次是 JOIN。如果您不知道为什么需要为表中的每一行设置主键,那么您不应该使用关系数据库。
【解决方案3】:

您不需要 FK,您可以加入任意列。

但是拥有外键可以确保连接实际上会成功找到一些东西。

外键为您提供某些保证,否则这些保证将非常困难且容易出错。

例如,如果您没有外键,您可能会在系统中插入详细记录,然后在您检查到匹配的主记录存在之后,其他人将其删除。因此,为了防止这种情况发生,您需要在修改详细表时锁定主表(反之亦然)。如果您不需要/不想要该保证,请拧紧 FK。

根据您的 RDBMS,外键也可能会提高选择的性能(但也会降低更新、插入和删除的性能)

【讨论】:

  • @Jona “但是拥有外键可以确保连接实际上会成功找到某些东西”是误导性的。查询不需要约束,它们不会影响查询含义并且声明它们不会改变在正确的数据库状态下返回的内容。如果您可以声明 FK,那么无论您是否声明,查询都会从正确的 DB 状态返回相同的值。 FK 约束表示,在此数据库中,当某个值的子行参与关系(船)/关联时,它参与某个其他的一次。约束用于禁止不正确的数据库状态。
【解决方案4】:

我知道发帖太晚了,但我使用该网站作为我自己的参考,所以我想在这里给出一个答案,以供自己将来参考。我希望你(和其他人)觉得它有帮助。

让我们假设是一群超级爱因斯坦专家设计了我们的数据库。我们超完美的数据库有3张表,它们之间定义了如下关系:

TblA 1:M TblB
TblB 1:M TblC

Notice there is no relationship between TblA and TblC

在大多数情况下,这样一个简单的数据库很容易导航,但在商业数据库中,通常不可能在设计阶段说出数据、表甚至整个数据库的所有可能用途和用途组合,尤其是随着系统的建立和其他系统的集成或切换或退出。这个简单的事实催生了一个建立在称为商业智能的数据库之上的整个行业。但我离题了...

在上面的例子中,结构很容易理解,很容易看出你可以从 TblA 连接到 B,再到 C,反之亦然,以获得你需要的东西。它也非常模糊地突出了这样做的一些问题。现在将这个简单的链扩展到 10 或 20 或 50 条关系。现在突然之间,您开始设想对您的场景的需求。简单来说,就是从 A 到 C 的连接,反之亦然,或者从 A 到 F,或者从 B 到 Z,或者随着我们系统的增长。

确实有很多方法可以做到这一点。上面提到的一个是最受欢迎的,即通过所有链接。主要问题是它非常慢。您添加到链中的表越多,这些表增长得越多,并且您想要通过它越远,就会变得越来越慢。

解决方案 1:寻找通用链接。如果你教过加入 A 到 C 的理由,它一定在那里。如果不明显,建立一种关系,然后加入它。即,要加入 A 到 B 到 C 必须有一些共性,否则你的加入将产生零结果或大量结果(笛卡尔积)。如果您知道这种共性,只需将所需的列添加到 A 和 C 并直接链接它们。

关系的规则是它们必须有存在的理由。而已。如果你能找到从 A 链接到 C 的充分理由,那就去做吧。但你必须确保你的理由不是多余的(即它已经以其他方式处理)。

现在警告一句。有一些陷阱。但是我没有很好地解释它们,所以我会推荐你​​my source而不是在这里谈论它。但请记住,这涉及到一些沉重的东西,所以这个关于粉丝和鸿沟陷阱的视频实际上只是一个起点。您可以在没有关系的情况下加入。但我建议先看这个视频,因为这超出了大多数人在大学里学习的内容,并且深入到了 BI 和 SAP 人员的领域。这些人,虽然他们可以编程,但他们的日常工作就是专门研究这种事情。如何让海量数据相互交流并有意义。

这个视频是我在这个主题上看到的更好的视频之一。他的其他一些视频值得一看。我从他身上学到了很多。

【讨论】:

  • 这是包含您的帖子的简明精确摘要:给定表示关系(船舶)/关联的表格,它们的自然连接表示它们的关系(船舶)/关联的连词/AND。当人们有其他预期时,就会出现粉丝和鸿沟“陷阱”。约束(包括 PK、CK、超级键/UNIQUE、FK 和基数)既不需要也不足以查询。通过自然连接向表中添加列需要适当的连接/ANDing 来获得表示的新关系(船)/关联。
【解决方案5】:

不需要主键。也不需要外键。只要数据类型匹配或转换为匹配,您就可以在任何列上构建连接两个表的查询。不需要明确存在任何关系。

为此,您使用外部联接:

select tablea.code, tablea.name, tableb.location from tablea left outer join 
tableb on tablea.code = tableb.code

join with out relation

SQL join

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多