方法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 WARN]:java.sql.SQLException:无法添加外键 约束[23:51:36警告]:at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1073) [23:51:36警告]:at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3593)[23:51:36 警告]:at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3525)[23:51:36 警告]:在com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1986) [23:51:36警告]:at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2140)[23:51:36 警告]:at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2620) [23:51:36警告]:at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2570) [23:51:36警告]:at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:779)[23:51:36 警告]:at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:622)[23:51:36 警告]:在power.database.MySQL.createTable(MySQL.java:104) [23:51:36警告]:at power.managers.DatabaseManager.createTables(DatabaseManager.java:81) [23:51:36警告]:at power.managers.DatabaseManager.startDatabase(DatabaseManager.java:40) [23:51:36警告]:at power.managers.DatabaseManager。(DatabaseManager.java:30) [23:51:36警告]:at power.logic.ClanBattles.onEnable(ClanBattles.java:44)[23:51:36警告]: 在org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:321) [23:51:36警告]:at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:340) [23:51:36警告]:at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:405) [23:51:36警告]:at org.bukkit.craftbukkit.v1_8_R3.CraftServer.loadPlugin(CraftServer.java:357) [23:51:36警告]:at org.bukkit.craftbukkit.v1_8_R3.CraftServer.enablePlugins(CraftServer.java:317) [23:51:36警告]:at org.bukkit.craftbukkit.v1_8_R3.CraftServer.reload(CraftServer.java:741) [23:51:36警告]:org.bukkit.Bukkit.reload(Bukkit.java:535) [23:51:36警告]:at org.bukkit.command.defaults.ReloadCommand.execute(ReloadCommand.java:25) [23:51:36警告]:at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) [23:51:36警告]:at org.bukkit.craftbukkit.v1_8_R3.CraftServer.dispatchCommand(CraftServer.java:641) [23:51:36警告]:at net.minecraft.server.v1_8_R3.PlayerConnection.handleCommand(PlayerConnection.java:1162) [23:51:36警告]:at net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java:997) [23:51:36警告]:at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java:45) [23:51:36警告]:at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java:1) [23:51:36警告]:at net.minecraft.server.v1_8_R3.PlayerConnectionUtils $ 1.run(的SourceFile:13) [23:51:36警告]:at java.util.concurrent.Executors $ RunnableAdapter.call(Unknown Source) [23:51:36警告]:在java.util.concurrent.FutureTask.run(未知 来源)[23:51:36警告]:at net.minecraft.server.v1_8_R3.SystemUtils.a(SourceFile:44)[23:51:36 警告]:at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:715) [23:51:36警告]:at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:374) [23:51:36警告]:at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:654) [23:51:36警告]:at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:557) [23:51:36警告]:在java.lang.Thread.run(未知来源)
答案 0 :(得分:0)
我认为你正在反向创建外键,这是不正确的。
由于您的map
表格有regionId
,因此您应该在地图表中为其创建FOREIGN KEY
,而不是region
本身。因此,在脚本中更改它以便以这种方式创建map
表:
FOREIGN KEY (regionId) REFERENCES regions(id)
同样适用于maxLocationId
表的region
列。外键应在region
表中定义,而不是locations
本身。
任何外键都应引用引用表中的PRIMARY KEY
,如果不引用,则mysql不会创建它。
此外,您应该在创建表和定义PRIMARY KEY时保持依赖顺序,然后在它们之间创建任何引用FOREIGN KEY。
例如,您应首先创建region
表并定义其PRIMARY KEY。之后,您应该创建一个map
表,其中引用了region
,现在您可以在map
表中定义引用id
(或通常为PRIMARY)的外键KEY region
列上的regionId
表格。
有关创建外键的概念和语法,请参阅this参考。
答案 1 :(得分:0)
为什么你的区域表中有FOREIGN KEY(id)REFERENCES map(regionId)?它应该是另一种方式不是它(区域表是主表,它的表由表映射引用)?
所以在创建表映射DDL
中应该是这样的OnResize
与FK内部位置表相同,我认为应该是相反的方式
答案 2 :(得分:0)
您无法在一个表中创建多个主键 就像你在地图表中所做的那样
"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.aspCREATE TABLE Orders (
OrderID int NOT NULL,
OrderNumber int NOT NULL,
PersonID int,
PRIMARY KEY (OrderID),
FOREIGN KEY (PersonID) REFERENCES Persons(PersonID)
);
答案 3 :(得分:0)
您只需要设置所有约束的唯一名称。 约束的名称在整个数据库中必须是唯一的。