无法添加创建表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)
);