当前位置: 首页 > 知识库问答 >
问题:

无法添加外键约束来创建MySQL表

鄂慈
2023-03-14

方法createTable()正在工作,我已经创建了其他简单的表没有问题。

我用的是MySQL服务器8.0

这是对表的测试,然后我将创建一个脚本来创建它们。我一直有这个错误:

无法创建表,SQLException:无法添加外键约束

但我不知道怎么了。

    if(!database.checkTable("maps")){
        String maps = "CREATE TABLE maps (" 
                + "name VARCHAR(32) NOT NULL,"
                + "mapType VARCHAR(32) NOT NULL,"
                + "world VARCHAR(32) NOT NULL,"
                + "referenceId INT(32) NOT NULL,"
                + "regionId INT(32) NOT NULL,"
                + "testmode BIT(1) NOT NULL,"
                + "edition BIT(1) NOT NULL,"
                + "finished BIT(1) NOT NULL,"
                + "PRIMARY KEY (name, referenceId, regionId))"
                + "ENGINE = InnoDB "
                + "DEFAULT CHARACTER SET = utf8;";
        database.createTable(maps);
    }
    if(!database.checkTable("regions")){
        String regions = "CREATE TABLE regions ("
                + "id INT(32) NOT NULL AUTO_INCREMENT," 
                + "minLocationId INT(32) NOT NULL,"
                + "maxLocationId INT(32) NOT NULL,"
                + "PRIMARY KEY (id, minLocationId, maxLocationId),"
                + "CONSTRAINT `regionMapFk`"
                + "FOREIGN KEY (id)"
                + "REFERENCES maps (regionId)"
                + "ON DELETE CASCADE "
                + "ON UPDATE CASCADE)"
                + "ENGINE = InnoDB "
                + "DEFAULT CHARACTER SET = utf8;";
        database.createTable(regions);
    }
    if(!database.checkTable("locations")){
        String locations = "CREATE TABLE locations ("   
                + "id INT(16) NOT NULL AUTO_INCREMENT, "
                + "x INT(16) NOT NULL, "
                + "y INT(16) NOT NULL, "
                + "z INT(16) NOT NULL, "
                + "PRIMARY KEY(id),"
                + "CONSTRAINT `minLocationRegionFk`"
                + "FOREIGN KEY (id)"
                + "REFERENCES regions (minLocationId)"
                + "ON DELETE CASCADE "
                + "ON UPDATE CASCADE,"
                + "CONSTRAINT `maxLocationRegionFk`"
                + "FOREIGN KEY (id)"
                + "REFERENCES regions (maxLocationId)"
                + "ON DELETE CASCADE "
                + "ON UPDATE CASCADE,"
                + "CONSTRAINT `locationMapFk`"
                + "FOREIGN KEY (id)"
                + "REFERENCES maps (referenceId)"
                + "ON DELETE CASCADE "
                + "ON UPDATE CASCADE)"
                + "ENGINE = InnoDB "
                + "DEFAULT CHARACTER SET = utf8;";
        database.createTable(locations);
    }

plhd--11/>ConnectionImpl.execSQL(ConnectionImpl.java:2570)[23:51:36 WARN]:在com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:779)[23:51:36 WARN]:在com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:622)[23:51:36 WARN]:在power.数据库。MySQL. createTable(MySQL. java: 104)[23:51:36 WARN]:在power. Manager。数据库管理器。创建表(数据库管理器。java: 81)[23:51:36 WARN]:在power. Manager。数据库管理器。启动数据库(数据库管理器。java: 40)[23:51:36 WARN]:在power. Manager。数据库管理器。(数据库管理器。java: 30)[23:51:36 WARN]:在power. logic。ClanBattle. onEnable(ClanBattle. java: 44)[23:51:36 WARN]Bukkit. reload(Bukkit. java: 535)[23:51:36 WARN]:在org. bukkit.指令.默认值。Reload指令.执行(Reload指令. java: 25)[23:51:36 WARN]:在org. bukkit.指令。简单命令地图。调度(简单命令地图。java: 141)[23:51:36 WARN]:在org. bukkit. craftbukkit.v1_8_R3。CraftServer.调度命令(CraftServer. java: 641)[23:51:36 WARN]:在net. minecraft. server。v1_8_R3。PlayerConnec. handleader(PlayerConnec. java: 1162)[23:51:36 WARN]:在net. minecraft. server。v1_8_R3。PlayerConnec. a(PlayerConnec. java: 997)[23:51:36 WARN]:在net. minecraft. serverSystemUtils. a(SourceFile: 44)[23:51:36 WARN]: at net. minecraftServer. server.v1_8_R3. MinecraftServer. B(MinecraftServer. java: 715)[23:51:36 WARN]: at net. minecraft. server.v1_8_R3. DedicatedServer. B(DedicatedServer. java: 374)[23:51:36 WARN]: at net. minecraftServer. server.v1_8_R3. MinecraftServer. A(MinecraftServer. java: 654)[23:51:36 WARN]: at net. minecraftServer. server.v1_8_R3. MinecraftServer. run(MinecraftServer. java: 557)[23:51:36 WARN]: at java. lang. Thread. run(未知来源)

共有3个答案

璩无尘
2023-03-14

不能像在Maps表中那样在一个表中创建多个主键

"CREATE TABLE maps (" 
                + "name VARCHAR(32) NOT NULL,"
                + "mapType VARCHAR(32) NOT NULL,"
                + "world VARCHAR(32) NOT NULL,"
                + "referenceId INT(32) NOT NULL,"
                + "regionId INT(32) NOT NULL,"
                + "testmode BIT(1) NOT NULL,"
                + "edition BIT(1) NOT NULL,"
                + "finished BIT(1) NOT NULL,"
                + "PRIMARY KEY (name, referenceId, regionId))"
                + "ENGINE = InnoDB "
                + "DEFAULT CHARACTER SET = utf8;";

要创建外键约束,您必须给出该表主键的引用,并用该主键绑定当前表

看一看https://www.w3schools.com/sql/sql_foreignkey.asp

CREATE TABLE Orders (
    OrderID int NOT NULL,
    OrderNumber int NOT NULL,
    PersonID int,
    PRIMARY KEY (OrderID),
    FOREIGN KEY (PersonID) REFERENCES Persons(PersonID)
); 
薛烨
2023-03-14

为什么在区域表中有外键(id)引用映射(regionId)?应该是另一种方式,不是吗(region table是主表,其id由表映射引用)?

所以在create table maps DDL中应该是这样的

FOREIGN KEY (regionId) REFERENCES region (id)
ON DELETE CASCADE 
ON UPDATE CASCADE

FK在位置表内也是一样,我想应该是反过来

陆子默
2023-03-14

我认为你是在反向创建外键,这是不正确的。

由于map表具有loconId,因此您应该在map表中为它创建一个FOREIGN KEY,而不是在区域本身中。因此,在创建map表的脚本中这样更改它:

FOREIGN KEY (regionId) REFERENCES regions(id)

这同样适用于region表的maxLocationId列。外键应该在区域表中定义,而不是在位置本身中定义。

任何外键都应该引用引用表中的主键,否则mysql不会创建它。

此外,在创建表和定义它们的主键,然后在它们之间创建任何引用外键时,应该保持依赖关系顺序。

例如,您应该首先创建区域表并定义其主键。之后,您应该创建映射表,该表引用了区域,现在您可以在映射表中定义外键,该外键引用了区域表在其区域id列上的id(通常是主键)。

有关创建外键的概念和语法,请参阅本参考资料。

 类似资料:
  • 问题内容: 因此,我作为项目需求试图将外键约束添加到数据库中,并且它第一次或在两个不同的表上运行,但是在尝试添加外键约束时,我在两个表上遇到错误。我收到的错误消息是: 错误1215(HY000):无法添加外键约束 这是我用来创建表的SQL,两个有问题的表是和。 问题答案: 要查找特定错误,请运行以下命令: 并查看该部分。 子列的数据类型必须与父列完全匹配。例如,由于是,也需要是,而不是。 另外,您

  • 我在创建mysql数据库中现有表的外键时遇到了一些问题。 我不想创建一个名为的新表来引用它,使用以下方法: 但我发现了错误: 为了获得更多的信息,我做了: 在我看来,这两个列的类型似乎是匹配的,因为它们都是varchar(45)。(我还尝试将列设置为not null,但这没有解决问题)所以我猜问题一定是。但我不太清楚这意味着什么,也不知道如何检查/修复它。有人有什么建议吗?是什么意思?

  • 问题内容: 我正在尝试将新模式转发工程到我的数据库服务器上,但是我不知道为什么会收到此错误。我试图在这里搜索答案,但是我发现的所有内容都说是将db引擎设置为Innodb或确保要用作外键的键是它们自己表中的主键。如果我没记错的话,我都做过这两件事。你们还有其他帮助吗? SQL脚本执行完成:语句:成功7次​​,失败1次 这是父表的SQL。 问题答案: 我猜,和/或不完全相同的数据类型和。 也许父表中的

  • 引用的表是“组”(InnoDB)。 它有一个“id”列,定义为INT(11),不可为空,自动递增,主键 引用表为“用户(InnoDB)” 它的group_id列定义为INT(11),不可为空。 在引用表中已经存在一个基于“group_id”列的唯一索引 但是whn正在执行 我出错了 错误:1215无法添加外键约束 我添加db转储 检查清单 Db是InnoDB吗?是的 所有表都是InnoDB吗?是的

  • 问题内容: 我正在尝试为体育馆管理系统创建数据库,但无法弄清楚为什么会出现此错误。我试图在这里搜索答案,但找不到。 这是父表。 你们能帮我解决这个问题吗?谢谢。 问题答案: 为了将字段定义为,引用的父字段必须在其上定义了索引。 根据有关约束的文档: 参考parent_tbl_name(index_col_name,…) 定义上,和分别。并确保子列定义必须与其父列定义匹配。 更改表定义如下: 更改表

  • 问题内容: 我已经阅读了 Silberschatz的 数据库系统概念 ,第6版。我将在MySQL的OS X上实现第2章所示的大学数据库系统。但是我在创建表时遇到了麻烦。桌子看起来像 __ 创建表将导致以下错误。 在google搜索外键约束之后,我刚刚了解到“外键约束”一词表示来自表中外键列的数据必须存在于表的主键列中。但是我应该在插入数据时遇到此错误。 如果没有,为什么作者让我执行该SQL语句?