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

无法添加创建表MySQL的外键约束,mysql,sql,minecraft,Mysql,Sql,Minecraft,方法createTable()正在工作,我已经创建了其他简单的表,没有任何问题 我使用的是MySQL服务器8.0 这是对表的测试,然后我将制作一个脚本来创建它们。我一直有这样的错误: 无法创建表,SQLException:无法添加外键约束 但是我不知道怎么了 if(!database.checkTable("maps")){ String maps = "CREATE TABLE maps (" + "name VARCHAR(32) N

方法
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);
    }
[23:51:36警告]:java.sql.SQLException:无法添加外键 约束[23:51:36]:在 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073) [23:51:36]:在 checkErrorPacket(MysqlIO.java:3593)[23:51:36] 警告]:在 checkErrorPacket(MysqlIO.java:3525)[23:51:36] WARN]:位于com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1986) [23:51:36]:在 com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2140)[23:51:36] 警告]:在 com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2620) [23:51:36]:在 com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2570) [23:51:36]:在 com.mysql.jdbc.statementinpl.execute(statementinpl.java:779)[23:51:36] 警告]:在 com.mysql.jdbc.statementinpl.execute(statementinpl.java:622)[23:51:36] WARN]:位于power.database.MySQL.createTable(MySQL.java:104) [23:51:36]:在 power.managers.DatabaseManager.createTables(DatabaseManager.java:81) [23:51:36]:在 power.managers.DatabaseManager.startDatabase(DatabaseManager.java:40) [23:51:36]:在 power.managers.DatabaseManager.(DatabaseManager.java:30) [23:51:36]:在 power.logic.clandbattles.oneable(clandbattles.java:44)[23:51:36]: 位于org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:321) [23:51:36]:在 org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:340) [23:51:36]:在 org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:405) [23:51:36]:在 org.bukkit.craftbukkit.v1_8_R3.CraftServer.loadPlugin(CraftServer.java:357) [23:51:36]:在 org.bukkit.craftbukkit.v1_8_R3.CraftServer.enablePlugins(CraftServer.java:317) [23:51:36]:在 org.bukkit.craftbukkit.v1_8_R3.CraftServer.reload(CraftServer.java:741) [23:51:36警告]:在org.bukkit.bukkit.reload(bukkit.java:535) [23:51:36]:在 org.bukkit.command.defaults.ReloadCommand.execute(ReloadCommand.java:25) [23:51:36]:在 org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) [23:51:36]:在 org.bukkit.craftbukkit.v1_8_R3.CraftServer.dispatchCommand(CraftServer.java:641) [23:51:36]:在 net.minecraft.server.v1_8_R3.PlayerConnection.handleCommand(PlayerConnection.java:1162) [23:51:36]:在 net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java:997) [23:51:36]:在 net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java:45) [23:51:36]:在 net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java:1) [23:51:36]:在 net.minecraft.server.v1_8_R3.PlayerConnectionUtils$1.run(源文件:13) [23:51:36]:在 java.util.concurrent.Executors$RunnableAdapter.call(未知源) [23:51:36 WARN]:在java.util.concurrent.FutureTask.run(未知) 来源)[23:51:36]:在 net.minecraft.server.v1_8_R3.SystemUtils.a(源文件:44)[23:51:36] 警告]:在 net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:715) [23:51:36]:在 net.minecraft.server.v1_8_R3.dicatedserver.B(dicatedserver.java:374) [23:51:36]:在 net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:654) [23:51:36]:在 net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:557) [23:51:36 WARN]:位于java.lang.Thread.run(未知源)


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

由于您的
map
表具有
regionId
,因此您应该在map表中为其创建一个
外键,而不是在
区域
本身。因此,在创建
map
表的脚本中对其进行如下更改:

FOREIGN KEY (regionId) REFERENCES regions(id)
这同样适用于
region
表的
maxLocationId
列。外键应该在
区域
表中定义,而不是在
位置
本身中定义

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

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

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

有关创建外键的概念和语法,请参见参考。

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

所以在createtablemapsddl中应该是这样的

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

与FK inside location table相同,我认为应该是另一种方式,即不能在一个表中创建多个主键 就像你们在地图桌上做的一样

"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;";
要创建外键约束,您必须提供要绑定的表的主键的引用
CREATE TABLE Orders (
    OrderID int NOT NULL,
    OrderNumber int NOT NULL,
    PersonID int,
    PRIMARY KEY (OrderID),
    FOREIGN KEY (PersonID) REFERENCES Persons(PersonID)
);