使用MySQL工作台,我从一些相关的表中复制了create语句以放入一个干净的模式。它们都以某种方式相互引用,因此没有固有的顺序可以创建它们。我怎样才能强制MySQL创建表而忽略可能发生的任何警告,直到其余的表创建?
我是否必须将其分组到某种交易中?
一个非常简单的例子是:
CREATE TABLE `vehicle` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`gallery_id` int(11) DEFAULT NULL,
`make_id` int(11) NOT NULL,
`model_id` int(11) DEFAULT NULL,
`make` varchar(100) DEFAULT '',
`model` varchar(100) DEFAULT '',
`colour_id` int(11) DEFAULT NULL,
`currency_id` int(11) NOT NULL DEFAULT '1',
`fuel_id` int(11) DEFAULT NULL,
`status_id` int(11) DEFAULT NULL,
`stock_code` varchar(100) DEFAULT NULL,
`registration` varchar(20) DEFAULT NULL,
`title` varchar(100) DEFAULT NULL,
`description` text,
`month` tinyint(4) DEFAULT NULL,
`public` tinyint(4) NOT NULL DEFAULT '0',
`sold` tinyint(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `vehicle_fk_idx` (`status_id`),
CONSTRAINT `vehicle_fk` FOREIGN KEY (`status_id`) REFERENCES `vehicle_status` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `vehicle_status` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`slug` varchar(100) DEFAULT NULL,
`title` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug_UNIQUE` (`slug`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
vehicle
引用vehicle_status
,这意味着必须首先创建vehicle_status
。如何在不添加引用的情况下首先创建vehicle
然后vehicle_status
?
答案 0 :(得分:0)
创建表时没有定义外键,您可以在单独的查询中使用它们,如下所示:
ALTER TABLE `vehicle`
ADD CONSTRAINT `vehicle_ibfk_1` FOREIGN KEY (`status_id`)
REFERENCES `vehicle_status` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;
因此,您首先要创建表,然后创建外键。
我个人的做法是在一个文件中包含所有CREATE TABLE
个查询,我知道我只需导入即可,没有任何错误。我在一个单独的文件中有所有CONSTRAINT
个查询,我在创建了所有表后导入了这个查询,并且我在一个单独的文件中进行了所有INSERT INTO
个查询,该文件在设置了所有约束和表之后添加了数据。 / p>
答案 1 :(得分:0)
看起来vehicle_status是一个查找表,而vehicle是一个主要的事务表。
通常,查找表不引用其他表,尽管可能存在一个查找表引用另一个查找表的设计。在您的情况下,它很简单:首先创建vehicle_status。如果你的模式中有一百个表,那么它将需要一些工作来按顺序排序创建命令。
有些设计中参考链形成一个圆圈。在这种情况下,您必须执行GGio建议的操作:稍后添加约束。涉及循环引用的设计还存在其他问题,这些问题可能会或可能不会出现在您的架构中。
当你去填充表格时,你也不得不担心订单。通常,在开始填充事务表之前,您必须首先填充查找表。否则,您将在加载时获得引用违规。