如果我可以在不定义主键和外键的情况下加入,那么主键和外键的用途是什么?

时间:2013-03-27 20:24:56

标签: sql database database-design constraints

由于我可以在不使用关系密钥(主键和外键)的情况下连接两个表,因此首先定义这些键的目的是什么?

例如,我的第一张表是

customer table
fields are cust_id, lastname, firstname

我的第二张桌子是

product table
fields are product_id, productno, cust_id

即使我没有将任何字段声明为主键或foriegn键,我仍然可以加入这两个表:

SELECT *
FROM customer c
LEFT OUTER JOIN product p ON p.custid=c.cust_id

为什么我要定义键呢?

6 个答案:

答案 0 :(得分:5)

有一些很好的答案,请允许我稍微推断一下。

正如“dasblinkenlight”所述,检索的速度(数据库事先知道两个表之间的关系,并可能潜在地优化查询),更重要的是,参考/数据完整性。

让我们再讨论第二个问题。

考虑一个简单的场景,你有以下三个表(我简化了这一点。实际上,你可以订购许多产品,但为了简洁,我保持简单):

CustomerTable
   ID
   FirstName
   LastName


OrderTable
   ID
   CustomerID
   ProductID    

ProductTable
   ID
   Description

没有外键,我们可以自由地:

  • 创建没有产品的订单
  • 创建没有客户的订单
  • 删除包含订单的客户
  • 删除包含产品的订单 等...

这是灾难的秘诀

通过使用外键,我们可以重新设计上述内容,因此:

CustomerTable
   ID
   FirstName
   LastName


OrderTable
   ID
   CustomerID -> References CustomerTable.ID
   ProductID -> References ProductTable.ID

ProductTable
   ID
   Description

我们可以指定CustomerID和ProductID是“NOT NULL”(就像其他列一样)。这意味着要创建订单,我们拥有以拥有现有客户和现有产品。优良!

但它变得更好。如果我开始删除产品会怎样?除非我们已经指定了一些级联选项(参见this),否则数据库会摇摇晃晃地说“Nope。你不能删除它,它被某些东西引用”。

这是等式的数据完整性部分。我们不能指出那些不存在的东西(外键坚持我们指出它什么都没有[如果允许空值],或者那里有什么东西。主键有助于我们这样做。)

突然之间,数据库本身确保一切都能很好地协同工作并且很好地结合在一起。没有它,你可以删除所有订单...删除产品...删除你想要的任何东西,然后你的应用程序会想知道到底是怎么回事。

使用它们:)

答案 1 :(得分:3)

告诉你的RDBMS两个密钥相关的两个原因是

  • 加快检索 - 当您声明主要到外部的密钥关系时,RDBMS可能会添加隐式索引来加速联接
  • 处理引用完整性 - RDBMS可以检查是否删除主键,以查看是否删除了从“子”记录引用的行,并可选择删除子记录或抛出错误。您的RDBMS还会告诉您是否尝试插入具有父表中没有匹配主键的外键的记录。

除此之外,可以以类似的方式使用密钥和非密钥字段。特别是,加入未声明为主键或外键的列肯定是可以的。

答案 2 :(得分:3)

这不是关于“能够加入”它是关于允许进入表格的内容。此外,如果删除客户会发生什么,但数据库中有未完成的产品?如果没有外键,它们就是所谓的孤立记录。添加外键,默认情况下会阻止删除子表引用的对象。

答案 3 :(得分:2)

这些概念都与约束有关。

PRIMARY KEY是一个约束,表示一组列是唯一的,而不是NULL。大多数实现使用索引来支持这一点,在某些实现中,主键也是用于对磁盘存储中的页面中的数据进行排序的集群索引。

FOREIGN KEY是一个约束,表示一组列引用另一个表中的另一组列。通常,外键仍然可以是NULL,但如果它不是NULL,那么它必须是它引用的表中的有效键,并且也必须是唯一的。它引用的密钥不必是PRIMARY KEY,只是一个唯一的密钥(数据库通常通过约束来确定它,如唯一约束或索引)。外键本身不必具有索引,但这通常是个好主意,因为删除所引用的表中的行需要在允许删除之前检查所有外键。这些都属于参照完整性的概念。

通常,对数据库的所有约束都会保护数据完整性,并允许优化器了解限制并获得有关最佳执行计划的更多线索。但是,可以简单地在表上具有适当的唯一索引,并且仍然可以获得相同的执行计划,而不将索引作为主键的一部分或作为定义外键引用的前提,但索引是独特肯定会影响计划的选择。

查询中有许多允许(DML),但DDL声明了数据的结构

答案 4 :(得分:1)

简短回答,数据完整性。

同样使用这样的外键将确保搜索发生得更快,因为更多数据输入到表中。

答案 5 :(得分:0)

连接仅用于“公共变量”,因此连接可用于连接两个表中具有相等值的表。主键必须是唯一的,因此您始终可以引用它们,因此您也可以将它们用作其他表的引用。基本上当你从2个表中进行查询时,发生的事情是笛卡尔积。 (这不是在实际实现中发生的,因为时间是一个因素)并且这会产生大量数据,但是连接会减少结果中的数据(理论上)。 你可以在这里阅读更多关于加入的内容:

http://www.w3schools.com/sql/sql_join.asp