1

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

例如,我的第一张桌子是

customer table
fields are cust_id, lastname, firstname

我的第二张桌子是

product table
fields are product_id, productno, cust_id

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

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

那我为什么要定义键呢?

4

6 回答 6

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),否则数据库将抛出一个不稳定的消息并说“不。你不能删除它,它被某些东西引用了”。

这是等式的数据完整性部分。我们不能指向不存在的东西(外键坚持我们不指向任何东西[如果允许 null],或者存在的东西。主键可以帮助我们解决这个问题)。

突然之间,数据库本身正在确保一切都很好地协同工作并很好地联系起来。没有它,您可以删除所有订单...删除产品...删除您想要的任何内容,然后您的应用程序会想知道到底发生了什么。

使用它们 :)

于 2013-03-27T20:38:12.407 回答
3

告诉您的 RDBMS 这两个键相关的两个原因是

  • 加快检索速度 - 当您声明主键到外键关系时,RDBMS 可能会添加隐式索引以加快连接速度
  • 处理参照完整性——RDBMS 可以检查删除主键以查看您是否正在删除从“子”记录引用的行,并可选择删除子记录或引发错误。如果您尝试使用在父表中没有匹配主键的外键插入记录,您的 RDBMS 也会告诉您。

除此之外,可以以类似的方式使用键和非键字段。特别是,在未声明为主键或外键的列上加入当然没问题。

于 2013-03-27T20:29:28.157 回答
3

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

于 2013-03-27T20:30:27.720 回答
2

这些概念都是关于约束的。

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

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

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

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

于 2013-03-27T20:52:25.600 回答
1

简短的回答,数据完整性。

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

于 2013-03-27T20:29:15.923 回答
0

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

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

于 2013-03-27T20:36:28.847 回答