首先,这是我在这里的第一篇文章,但多年来这个网站一直是#34;这个地方"当我需要回答我的问题。但是,我在MySQL数据库设计问题上遇到了麻烦,我似乎无法找到答案或解决自己。
此处发布了所涉及表格的代码片段(Workbench已生成)。问题出现在
之后CREATE TABLE IF NOT EXISTS `TestCenter`.`test` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`report_number` VARCHAR(10) GENERATED ALWAYS AS (CONCAT(YEAR(create_time), '-', seq_number)) VIRTUAL,
`seq_number` INT(5) ZEROFILL NOT NULL,
`test_state_id` TINYINT NOT NULL DEFAULT 1,
`customer_id` BIGINT NOT NULL,
`sample_rate` INT NOT NULL,
`comment` VARCHAR(255) NULL,
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`start_time` DATETIME NULL,
`end_time` DATETIME NULL,
PRIMARY KEY (`id`),
INDEX `fk_idx_test_customer_id` (`customer_id` ASC),
INDEX `fk_idx_test_test_state_id` (`test_state_id` ASC),
INDEX `idx_test_start_and_end_time` (`start_time` ASC, `end_time` ASC),
UNIQUE INDEX `report_number_UNIQUE` (`report_number` ASC),
CONSTRAINT `fk_test_customer_id`
FOREIGN KEY (`customer_id`)
REFERENCES `TestCenter`.`customer` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_test_test_state_id`
FOREIGN KEY (`test_state_id`)
REFERENCES `TestCenter`.`test_state` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `TestCenter`.`machine` (
`id` TINYINT NOT NULL AUTO_INCREMENT,
`description` VARCHAR(45) NOT NULL,
`is_controlled` TINYINT(1) NOT NULL DEFAULT 0,
`active` TINYINT(1) NOT NULL DEFAULT 1,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `TestCenter`.`motion` (
`id` TINYINT NOT NULL,
`description` VARCHAR(45) NOT NULL,
`plc_value` TINYINT NOT NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `TestCenter`.`machine_motion` (
`machine_id` TINYINT NOT NULL,
`motion_id` TINYINT NOT NULL,
`active` TINYINT(1) NOT NULL DEFAULT 1,
INDEX `fk_idx_machine_motion_motion_id` (`motion_id` ASC),
PRIMARY KEY (`machine_id`, `motion_id`),
CONSTRAINT `fk_machine_motion_machine_id`
FOREIGN KEY (`machine_id`)
REFERENCES `TestCenter`.`machine` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_machine_motion_motion_id`
FOREIGN KEY (`motion_id`)
REFERENCES `TestCenter`.`motion` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `TestCenter`.`test_step` (
`step_number` INT NOT NULL,
`test_id` BIGINT NOT NULL,
`machine_id` TINYINT NOT NULL,
`motion_id` TINYINT NOT NULL,
`step_state_id` TINYINT NOT NULL DEFAULT 1,
`auto_continue` TINYINT(1) NOT NULL DEFAULT 0,
`start_time` DATETIME NULL,
`end_time` DATETIME NULL,
INDEX `fk_idx_test_step_machine_and motion_id` (`machine_id` ASC, `motion_id` ASC),
PRIMARY KEY (`test_id`, `step_number`),
INDEX `fk_idx_test_step_step_state_id` (`step_state_id` ASC),
INDEX `fk_idx_test_step_test_id` (`test_id` ASC, `machine_id` ASC),
CONSTRAINT `fk_test_step_machine_and motion_id`
FOREIGN KEY (`machine_id` , `motion_id`)
REFERENCES `TestCenter`.`machine_motion` (`machine_id` , `motion_id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_test_step_test_id`
FOREIGN KEY (`test_id`)
REFERENCES `TestCenter`.`test` (`id`)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT `fk_test_step_step_state_id`
FOREIGN KEY (`step_state_id`)
REFERENCES `TestCenter`.`test_state` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
来自EER图Image of involved tables
的相同表格的图像我的问题是' machine_id'在' test_step'表(见图),它真的不属于那里,应该在“测试”中。作为单个测试的表由同一台机器完成,无论进行测试涉及多少步骤。但是我也想在' test_step'中使用fk约束。表只允许有效的' machine_motion'组合
正如我所看到的,一个解决方案是,拥有' machine_id'在'测试'表格,但这将引入一个循环参考作为测试'然后桌子会引用机器'表
另一个解决方案是,从' test_step'中删除fk约束。表,移动' machine_id'进入测试'表并将“fk”约束添加到' motion_id'在' test_step'表引用'动作'表
实际上,在写这篇文章时,我发现解决方案2可能是要走的路,但是,
我错过了什么吗?我真的很感激一些投入,因为我现在几天都在努力。
答案 0 :(得分:1)
在现有设计中:
每个测试可能有多个测试步骤;每个测试步骤都属于一个测试。
每项测试可由多台机器执行。
因此,无论是谁设计的,都希望不止一台机器可以参与一次测试。这可能是当时的要求。
您的陈述
...单一测试由同一台机器完成..
更改了这些内容,并且引入了可以用语言表达的约束:
每个测试都由一台机器完成,对于每台机器,该机器可以进行多项测试。
对于每个测试步骤,该步骤由分配给测试步骤所属的测试的机器执行。
因为你基本上引入了新的约束,你应该:
machine_id
添加到test
表格; machine_id
表格向test
表格添加FK {machine
}; id, machine_id
}添加到test
表格; test_id, machine_id
表格向test_step
表格添加FK {test
}; test_id
表格中删除冗余FK {test_step
}到test
。这样,如果需求再次发生变化,您可以简单地删除这四个DB对象。 可能是整个测试系统将来可能会扩展,原始要求可能仍然存在。
test { id , report_number , seq_number , test_state_id , customer_id , sample_rate , comment , create_time , start_time , end_time , machine_id -- added, point 1 } PK {id} AK1 {report_number} AK2 {id, machine_id} -- added, point 3 FK1 {customer_id} REFERENCES customer {id} FK2 {test_state_id} REFERENCES test_state {id} FK3 {machine_id} REFERENCES machine {id} -- added, point 2 machine { id , description , is_controlled , active } PK {id} motion { id , description , plc_value } PK {id} machine_motion { machine_id , motion_id , active } PK {machine_id, motion_id} FK1 {machine_id} REFERENCES machine {id} FK2 {motion_id} REFERENCES motion {id} test_step { step_number , test_id , machine_id , motion_id , step_state_id , auto_continue , start_time , end_time } PK {test_id, step_number} FK1 {machine_id, motion_id} REFERENCES machine_motion {machine_id, motion_id} FK2 {test_id} REFERENCES test {id} -- redundant, pt 5 FK3 {step_state_id} REFERENCES step_state {id} FK4 {test_id, machine_id} REFERENCES test {id, machine_id} -- added, pt 4