【问题标题】:How do I fix the foreign key constraints?如何修复外键约束?
【发布时间】:2020-10-22 03:25:48
【问题描述】:
CREATE TABLE Vehicles(
        type VARCHAR(10) NOT NULL,
        year INT(4),
        cost INT(10),
        model VARCHAR(20) NOT NULL,
        manufacturer VARCHAR(20),
        country VARCHAR(20),
        licensename VARCHAR(20),
        stock INT(3),
        PRIMARY KEY (type, model)
);

CREATE TABLE Staff(
        sid CHAR(6) NOT NULL,
        phoneno INT(10),
        taxfile INT(9),
        salary INT(10),
        fname VARCHAR(20),
        lname VARCHAR(20),
        hours INT(4),
        PRIMARY KEY (sid)
);

CREATE TABLE Customers(
        cid INT NOT NULL AUTO_INCREMENT,
        fname VARCHAR(20),
        lname VARCHAR(20),
        PRIMARY KEY (cid)
);

CREATE TABLE ContactDetails(
        value VARCHAR(20) NOT NULL,
        type ENUM ("phone", "email"),
        cid INT,
        FOREIGN KEY (cid) REFERENCES Customers(cid) ON DELETE CASCADE,
        PRIMARY KEY (value, cid)
);

CREATE TABLE Sales(
        rego CHAR(7),
        salesprice INT(15),
        time DATE,
        comm INT(15),
        warrantee DATE,
        cid INT,
        sid CHAR(6),
        type VARCHAR(10),
        model VARCHAR(20),
        FOREIGN KEY (cid) REFERENCES Customers(cid) ON UPDATE CASCADE,
        FOREIGN KEY (sid) REFERENCES Staff(sid) ON UPDATE CASCADE,
        FOREIGN KEY (type) REFERENCES Vehicles(type) ON UPDATE CASCADE,
        FOREIGN KEY (model) REFERENCES Vehicles(model) ON UPDATE CASCADE,
        PRIMARY KEY (rego)
);
                                                                                                                                                                                          
CREATE TABLE License(
        name CHAR(30),
        expdate DATE,
        gdate DATE,
        cid INT,
        sid CHAR(6),
        FOREIGN KEY (cid) REFERENCES Customers(cid) ON UPDATE CASCADE,
        FOREIGN KEY (sid) REFERENCES Staff(sid) ON UPDATE CASCADE,
        PRIMARY KEY (name, sid, cid)
);

CREATE TABLE Interact(
        time DATE,
        cid INT,
        sid CHAR(6),
        type VARCHAR(10),
        FOREIGN KEY (cid) REFERENCES Customers(cid) ON UPDATE CASCADE,
        FOREIGN KEY (sid) REFERENCES Staff(sid) ON UPDATE CASCADE,
        PRIMARY KEY (time, cid, sid)
);

COMMIT;

输出 查询正常,0 行受影响(0.02 秒)

查询正常,0 行受影响(0.03 秒)

查询正常,0 行受影响(0.03 秒)

查询正常,0 行受影响(0.03 秒)

ERROR 1215 (HY000): 无法添加外键约束 查询正常,0 行受影响(0.03 秒)

查询正常,0 行受影响(0.04 秒)

查询正常,0 行受影响(0.00 秒)

问题出在销售表上,但我看不到语法

【问题讨论】:

  • 外键必须引用主键或唯一键。在您的 Vehicles 表中,类型或型号都不是唯一的(组合是唯一的,但各个列不是唯一的)。所以 Sales 表中的外键不能引用它们。
  • 请注意,varchar(10) 占用的空间并不比varchar(255) 少。它只是将最大大小限制为 10 个字符,除非您启用了严格的 SQL 模式,否则会截断其余字符。除非您有明确的理由限制列的最大大小,否则无需吝啬。 int(3) 不将其限制为 999,但它是一个可疑值的显示宽度。 time 是保留字,应避免作为列名,尤其是因为它是 date。考虑sold_at。最后,除非您不打算出售任何车辆,否则请务必设置您的外键列not null

标签: mysql database create-table


【解决方案1】:

Vehicles 有一个复合主键 PRIMARY KEY (type, model)。这也必须用作单个声明中的外键。

FOREIGN KEY (type, model) REFERENCES Vehicles(type, model) ON UPDATE CASCADE

你可能也想要on delete cascade

我建议使用简单的自动递增整数主键。它们更紧凑、更简单,并且避免了所有 ON UPDATE CASCADEs。

【讨论】:

  • 那么删除每张表中的所有UPDATE CASCADE?
  • @i_dont_know 当且仅当您切换到整数主键 否则,它们会确保在车辆类型或型号发生变化时更新外键。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-19
  • 2019-10-26
  • 2016-03-27
  • 1970-01-01
  • 2014-01-20
  • 2022-08-22
  • 2019-01-11
相关资源
最近更新 更多