我有一个包含五个表的数据库,其结构如下:
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_ID
和Subscription_ID
引用到current_order中的复合主键,或者最好将它们分别引用到纸质表和订阅表中?答案 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
它更冗长,更具体。