我一直在从事有关游戏租赁商店的sql项目。
我已经创建了下表
CREATE TABLE CUSTOMER(
MEMBERSHIP_ID NUMERIC(10) PRIMARY KEY,
FNAME VARCHAR(10) NOT NULL,
LNAME VARCHAR(10) NOT NULL,
ADDRESS VARCHAR(100) NOT NULL,
TELEFONE NUMERIC(10) NOT NULL,
EMAIL VARCHAR(50) NOT NULL,
BIRTHDAY DATE);
和:
CREATE TABLE INVENTORY(
-> GAME_ID VARCHAR(10) PRIMARY KEY,
-> TITLE VARCHAR(20) NOT NULL,
-> PLATAFORM VARCHAR(10) NOT NULL,
-> EDITION YEAR,
-> GENRE VARCHAR(10) NOT NULL,
-> PUBLISHER VARCHAR(10) NOT NULL,
-> PRICE NUMERIC(4,2) DEFAULT 00.00 NOT NULL);
和:
CREATE TABLE RENTAL (
-> RENTAL_NO VARCHAR(10) PRIMARY KEY,
-> DATE_OUT DATE NOT NULL,
-> DATE_OF_RETURN DATE NOT NULL,
-> MEMBERSHIP_ID NUMERIC(10),
-> GAME_ID VARCHAR(10),
-> INDEX (MEMBERSHIP_ID),
-> CONSTRAINT FK_RENTAL_CUST FOREIGN KEY(MEMBERSHIP_ID) REFERENCES
-> CUSTOMER (MEMBERSHIP_ID),
-> INDEX (GAME_ID),
-> CONSTRAINT FK_RENTAL_INV FOREIGN KEY(GAME_ID) REFERENCES
-> INVENTORY (GAME_ID));
现在我需要一个交易表来连接价格,并且我一直在收到提到的错误:
CREATE TABLE OPEN_TRANSACTION (
RENTAL_NO VARCHAR (10),
MEMBERSHIP_ID NUMERIC (10),
DATE_OUT DATE NOT NULL,
DATE_OF_RETURN DATE NOT NULL,
GAME_ID VARCHAR (10),
ITEM_PRICE NUMERIC(4,2) DEFAULT 00.00 NOT NULL,
INDEX (RENTAL_NO),
INDEX (MEMBERSHIP_ID),
INDEX (GAME_ID),
INDEX (ITEM_PRICE),
INDEX (DATE_OUT),
INDEX (DATE_OF_RETURN),
CONSTRAINT PK_OPEN_TRANSACTION PRIMARY KEY (RENTAL_NO, GAME_ID, DATE_OUT),
CONSTRAINT FK_OPENTRAN_RENTAL FOREIGN KEY (RENTAL_NO, DATE_OUT, DATE_OF_RETURN) REFERENCES
RENTAL (RENTAL_NO, DATE_OUT, DATE_OF_RETURN),
CONSTRAINT FK_OPENTRAN_CUST FOREIGN KEY (MEMBERSHIP_ID) REFERENCES
CUSTOMER (MEMBERSHIP_ID),
CONSTRAINT FK_OPENTRAN_INV FOREIGN KEY (GAME_ID) REFERENCES
INVENTORY (GAME_ID),
CONSTRAINT FK_OPENTRAN_INV FOREIGN KEY (ITEM_PRICE) REFERENCES
INVENTORY (PRICE));
在您的情况下,您在OPEN_TRANSACTION中具有以下列:RENTAL_NO,DATE_OUT,DATE_OF_RETURN,并且您尝试引用RENTAL表中三个具有相同名称的列,但是RENTAL表的主键只是RENTAL_NO单列。
在我看来,OPEN_TRANSACTION具有单列外键:RENTAL_NO,引用RENTAL(RENTAL_NO)会很好。那将是合法的外键。它不能是模棱两可的,因为RENTAL_NO已经是RENTAL表的主键,因此对于给定的RENTAL_NO值,该表中只有一条记录。
一种替代方法是在RENTAL表中为三列的集合创建一个冗余的UNIQUE KEY。这将允许OPEN_TRANSACTION的三列组成一个外键,但它似乎并不是良好的关系数据库设计。
为什么您在OPEN_TRANSACTIONS表中有DATE_OUT和DATE_OF_RETURN列?如果这些列必须始终具有与RENTAL表中相同的值,则将多余地存储它们。如果这些列可以更改OPEN_TRANSACTIONS表中的值,则不应将它们用作外键。
除了该外键,您还有另一个问题:
ITEM_PRICE上OPEN_TRANSACTIONS中的外键引用INVENTORY.PRICE列,该列不是PRIMARY KEY或UNIQUE KEY。目前尚不清楚为什么要在此列上放置外键,或者为什么要在OPEN_TRANSACTIONS表中存储价格,因为它已经在INVENTORY表中。
我想出的最好的理由是,您想记录购买时的价格,因此您要记录所支付的价格。价格会涨跌,要生成分类账,您需要保存每次购买之日的价格。但是,您将不会在该价格上使用外键来引用库存中的价格,因为将价格复制到另一张表中的整个目的是应该允许值不同。
因此DATE_OUT
和DATE_OF_RETURN
列不属于OPEN_TRANSACTION
。只需在RENTAL_NO
中设置OPEN_TRANSACTION
。有了它,您可以在RENTAL
中找到右行并从中获取值。 ITEM_PRICE
中的OPEN_TRANSACTION
也一样。您具有GAME_ID
外键,可以在INVENTORY
中找到合适的游戏,因此也可以找到合适的价格。
相应地更改CREATE
语句。删除多余的列也将删除或更改外键约束,从而不再存在错误。
CREATE TABLE OPEN_TRANSACTION (
RENTAL_NO VARCHAR (10),
MEMBERSHIP_ID NUMERIC (10),
GAME_ID VARCHAR (10),
INDEX (RENTAL_NO),
INDEX (MEMBERSHIP_ID),
INDEX (GAME_ID),
CONSTRAINT PK_OPEN_TRANSACTION PRIMARY KEY (RENTAL_NO, MEMBERSHIP_ID, GAME_ID),
CONSTRAINT FK_OPENTRAN_RENTAL FOREIGN KEY (RENTAL_NO) REFERENCES
RENTAL (RENTAL_NO),
CONSTRAINT FK_OPENTRAN_CUST FOREIGN KEY (MEMBERSHIP_ID) REFERENCES
CUSTOMER (MEMBERSHIP_ID),
CONSTRAINT FK_OPENTRAN_INV FOREIGN KEY (GAME_ID) REFERENCES
INVENTORY (GAME_ID));