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

JAV*_*AVA 1 sql database database-design constraints

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

例如,我的第一个表是

customer table
fields are cust_id, lastname, firstname
Run Code Online (Sandbox Code Playgroud)

我的第二张桌子是

product table
fields are product_id, productno, cust_id
Run Code Online (Sandbox Code Playgroud)

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

SELECT *
FROM customer c
LEFT OUTER JOIN product p ON p.custid=c.cust_id
Run Code Online (Sandbox Code Playgroud)

那我为什么要定义键呢?

Moo*_*ice 5

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

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

让我们再谈谈第二个问题.

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

CustomerTable
   ID
   FirstName
   LastName


OrderTable
   ID
   CustomerID
   ProductID    

ProductTable
   ID
   Description
Run Code Online (Sandbox Code Playgroud)

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

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

这是灾难的秘诀

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

CustomerTable
   ID
   FirstName
   LastName


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

ProductTable
   ID
   Description
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

使用它们 :)