我是否需要设置主外键关系来进行连接?

时间:2015-09-02 12:12:25

标签: mysql database

我有一个包含五个表的数据库,其结构如下:

DROP DATABASE IF EXISTS newsagent;

CREATE DATABASE newsagent;
USE newsagent;

CREATE TABLE paper (id VARCHAR(20)PRIMARY KEY,name VARCHAR(30)) ENGINE = INNODB;

CREATE TABLE round (id INTEGER PRIMARY KEY,name VARCHAR(20),paperboy VARCHAR(20)) ENGINE = INNODB;

CREATE TABLE subscriber (id VARCHAR(10) PRIMARY KEY,name VARCHAR(20),address VARCHAR(30),suburb VARCHAR(20),state VARCHAR(3),postcode VARCHAR(4),round_id INTEGER NOT NULL,FOREIGN KEY (round_id) REFERENCES round (id) ON UPDATE CASCADE ON DELETE RESTRICT) ENGINE = INNODB;

CREATE TABLE current_order (paper_id VARCHAR(20),subscriber_id VARCHAR(10),PRIMARY KEY (paper_id, subscriber_id),FOREIGN KEY (paper_id) REFERENCES paper (id) ON UPDATE CASCADE ON DELETE RESTRICT,FOREIGN KEY (subscriber_id) REFERENCES subscriber (id) ON UPDATE CASCADE ON DELETE RESTRICT) ENGINE = INNODB;

CREATE TABLE receipt (id INTEGER PRIMARY KEY AUTO_INCREMENT, receipt_date DATE,paid_till_date DATE,paper_id VARCHAR(20),subscriber_id VARCHAR(10)) ENGINE = INNODB;

我应该运行一些查询来检索已逾期订阅付款的当前订单。查询如下:

SELECT DISTINCT t1.* FROM current_order AS t1 LEFT
JOIN receipt AS t2 USING (paper_id, subscriber_id)
WHERE t2.paid_till_date IS NULL
OR t2.paid_till_date < Now() 
ORDER BY subscriber_id, paper_id;

此查询运行正常,但我注意到current_order表和收据表之间没有主/子关系。

  • 我需要列出这种关系吗?如何建立关系?
  • 我是否将Paper_IDSubscription_ID引用到current_order中的复合主键,或者最好将它们分别引用到纸质表和订阅表中?
  • 它会对查询准确性和数据库性能产生影响吗?

1 个答案:

答案 0 :(得分:1)

你问了

  

我需要列出这种关系吗?

您不需要为查询建立FK关系以使其正常工作。 FK关系通过使INSERT和UPDATE操作在断开关键关系时失败来帮助您维护数据库完整性。如果没有这种完整性,您可能在某些表中有一些孤立行 - 与其他表中的行无关的行。这可能会让你的审计师和你疯狂,因为他们代表了错位的订单和交易。

  

如何建立关系?

您已经拥有,通过使id列在所有表中具有相同的数据类型,并在JOIN操作中使用它们。你也搞定了一些FK关系。

  

我是否将Paper_ID和Subscription_ID引用到current_order中的复合主键,或者最好将它们分别引用到纸质表和订阅表中?

单独引用它们,因为它更准确地表示关系。

  

它会对查询准确性和数据库性能产生影响吗?

良好的FK设置可能有助于查询性能,因为实现它们的索引可能对查询规划器有用。

约束将使您的数据更加一致。这可能有助于提高查询准确性。

专业提示:避免使用JOIN ... USING(col1,col2),因为在更复杂的查询中它可能不明确。而是做这种事情。

 FROM tablea a
 JOIN tableb b ON a.col1 = b.col1 AND a.col2 = b.col2

它更冗长,更具体。