【问题标题】:How to fix foreign key errors in SQL如何修复 SQL 中的外键错误
【发布时间】:2019-04-29 15:05:13
【问题描述】:

我正在使用 Ubuntu 创建一个数据库,并尝试将外键添加到下表中。这是我的代码。

CREATE TABLE Vehicles (    
    Vehicle_ID int NOT NULL,
    Vehicle_Type VARCHAR(255) NOT NULL,
    Model_name VARCHAR(255) NOT NULL,
    Engine_Size numeric(2,1) NOT NULL,
    Vehicle_Condition VARCHAR(255) NOT NULL,
    Price numeric(9,2) NOT NULL,
    PRIMARY KEY (Vehicle_ID)
);


CREATE TABLE Models (
    Model_ID int NOT NULL,
    Manufacturer VARCHAR(255) NOT NULL,
    Model_name VARCHAR(255) NOT NULL,
    Wheel_Drive_Type VARCHAR(255) NOT NULL,
    PRIMARY KEY (Model_ID)
);

每当我运行以下代码时,它都会返回错误“错误 1215 (HY000): 无法添加外键约束”,我不知道为什么 - 特别是因为它们都具有相同的输入类型。

ALTER TABLE Vehicles
    ADD FOREIGN KEY (Model_Name) REFERENCES Models(Model_Name);

ERROR 1215 (HY000): 无法添加外键约束

【问题讨论】:

  • 嗯,主键是Model_ID,所以看起来更适合外键引用。

标签: mysql sql database foreign-keys


【解决方案1】:

根据https://www.w3schools.com/sql/sql_foreignkey.asp

您需要创建的 FK 必须参考 Models 表 PK,即 Model_ID。

您正在尝试将其链接到不唯一的 Model_name。

CREATE TABLE Vehicles (    
Vehicle_ID int NOT NULL,
Vehicle_Type VARCHAR(255) NOT NULL,
Model_ID INT NOT NULL,
Engine_Size numeric(2,1) NOT NULL,
Vehicle_Condition VARCHAR(255) NOT NULL,
Price numeric(9,2) NOT NULL,
    PRIMARY KEY (Vehicle_ID)
);


CREATE TABLE Models (
    Model_ID int NOT NULL,
    Manufacturer VARCHAR(255) NOT NULL,
    Model_name VARCHAR(255) NOT NULL,
    Wheel_Drive_Type VARCHAR(255) NOT NULL,
    PRIMARY KEY (Model_ID)
);

你将被允许这样做

ALTER TABLE Vehicles
    ADD FOREIGN KEY (Model_ID ) REFERENCES Models(Model_ID );

这里证明http://www.sqlfiddle.com/#!9/8b6ad7

【讨论】:

    【解决方案2】:

    我可以通过做一些事情来解决这个问题。我为纠正这个问题所做的一切都来自这里:

    https://dev.mysql.com/doc/refman/5.5/en/alter-table.html

    特别是标题:“外键和其他约束”

    我注意到并改变了几件事。第一个引起我注意的是您使用 Model_name 作为外键,即使它不是模型表上的主键。我不确定这是一个要求,但它似乎关闭了。

    意见:外键和主键字段应始终为“ID”而不是“名称”。因此,我将 Vehicles 中的 model_name 字段替换为 Model ID,并更新为 INT(以匹配 Models)。

    然后我在alter table中稍微改变了语法:

    ALTER TABLE Vehicles
        ADD CONSTRAINT model_FK FOREIGN KEY (Model_ID) REFERENCES Models(Model_ID); 
    

    这一切都奏效了!

    我认为如果你想在 Vehicles 中使用 Model_name 作为外键,要么需要将其设为 Models 的主键,要么可以使用 Model_name 在 Models 上添加索引。这更符合我在尝试更改表以创建 model_name FK 时看到的错误消息......关于“引用表模型中的约束缺少索引”。

    【讨论】:

      【解决方案3】:

      这可能是因为您尝试使用 Varchar 字段作为外键,而 MySQL 不喜欢使用 VarChar 作为键,除非它们被指定为 BINARY。指定 CHARSET 和 COLLATE 属性也很麻烦/

      将 BINARY 添加到列规范和 ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;表规格应该可以解决它。例如:

      CREATE TABLE Vehicles (    
          Vehicle_ID int NOT NULL,
          Vehicle_Type VARCHAR(255) NOT NULL,
          Model_name VARCHAR(255) NOT NULL,
          Engine_Size numeric(2,1) NOT NULL,
          Vehicle_Condition VARCHAR(255) NOT NULL,
          Price numeric(9,2) NOT NULL,
          PRIMARY KEY (Vehicle_ID)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
      
      
      CREATE TABLE Models (
          Model_ID int NOT NULL,
          Manufacturer VARCHAR(255) NOT NULL,
          Model_name VARCHAR(255) BINARY NOT NULL,
          Wheel_Drive_Type VARCHAR(255) NOT NULL,
          PRIMARY KEY (Model_ID)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
      

      【讨论】:

      • 我相信解释否决票,所以这就是我否决票的原因:MySQL 不需要 BINARY 作为外键,它只要求 FK 列与它引用的 PK 列具有相同的排序规则。您的回答也完全忽略了真正的问题,即 OP 问题中的 FK 引用了一个非关键列。
      猜你喜欢
      • 2019-09-16
      • 2020-11-07
      • 2020-04-20
      • 1970-01-01
      • 1970-01-01
      • 2016-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多