gpt4 book ai didi

sql - 外键关系和 "belongs to many"

转载 作者:搜寻专家 更新时间:2023-10-30 23:23:34 28 4
gpt4 key购买 nike

edit - 根据下面的回复,我将重新审视我的设计。我认为我可以通过更加巧妙地设置我的业务目标和规则来避免这种困惑。感谢大家的帮助!

--

我有以下模型:

S属于T

T有很多S

A,B,C,D,E (etc) 各有 1 T,所以 T 应该属于 A,B,C,D,E (etc) 中的每一个

起初我设置了我的外键,这样在 A 中,fk_a_t 将是 A.t 到 T(id) 的外键,在 B 中它是 fk_b_t,等等。在我的 UML 中一切看起来都很好(使用 MySQLWorkBench) ,但是生成 yii 模型会导致它认为 T 有很多 A、B、C、D(等),这对我来说是相反的。

在我看来,我需要 A_T、B_T、C_T(等)表,但这会很痛苦,因为有很多表都具有这种关系。我还用谷歌搜索过,更好的方法是某种行为,例如 A、B、C、D(等)可以表现为 T,但我不清楚具体如何做到这一点(我会继续谷歌更多关于这个)

编辑 - 澄清一下,T 只能属于 A、B、C 等之一,不能属于两个 A,也不能属于 A 和 B(也就是说,它不是多对多) .我的问题是关于如何在 Yii 框架模型中描述这种关系 - 例如, (A,B,C,D,...) HAS_ONE T ,并且 T 属于 (A,B,C,D,.. .).从业务用例来看,这一切都是有道理的,但我不确定我是否在数据库中正确设置了它,或者如果我这样做了,我需要在 Yii 中使用“行为”来让它理解这种关系. @rwmnau 我明白你的意思,希望我的说明能有所帮助。

UML: uml diagram

这是 DDL(自动生成)。假设有超过 3 个表引用 T。

-- -----------------------------------------------------
-- Table `mydb`.`T`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`T` (
`id` INT NOT NULL AUTO_INCREMENT ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`S`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`S` (
`id` INT NOT NULL AUTO_INCREMENT ,
`thing` VARCHAR(45) NULL ,
`t` INT NOT NULL ,
PRIMARY KEY (`id`) ,
INDEX `fk_S_T` (`id` ASC) ,
CONSTRAINT `fk_S_T`
FOREIGN KEY (`id` )
REFERENCES `mydb`.`T` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`A`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`A` (
`id` INT NOT NULL AUTO_INCREMENT ,
`T` INT NOT NULL ,
`stuff` VARCHAR(45) NULL ,
`bar` VARCHAR(45) NULL ,
`foo` VARCHAR(45) NULL ,
PRIMARY KEY (`id`) ,
INDEX `fk_A_T` (`T` ASC) ,
CONSTRAINT `fk_A_T`
FOREIGN KEY (`T` )
REFERENCES `mydb`.`T` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`B`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`B` (
`id` INT NOT NULL AUTO_INCREMENT ,
`T` INT NOT NULL ,
`stuff2` VARCHAR(45) NULL ,
`foobar` VARCHAR(45) NULL ,
`other` VARCHAR(45) NULL ,
PRIMARY KEY (`id`) ,
INDEX `fk_A_T` (`T` ASC) ,
CONSTRAINT `fk_A_T`
FOREIGN KEY (`T` )
REFERENCES `mydb`.`T` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`C`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`C` (
`id` INT NOT NULL AUTO_INCREMENT ,
`T` INT NOT NULL ,
`stuff3` VARCHAR(45) NULL ,
`foobar2` VARCHAR(45) NULL ,
`other4` VARCHAR(45) NULL ,
PRIMARY KEY (`id`) ,
INDEX `fk_A_T` (`T` ASC) ,
CONSTRAINT `fk_A_T`
FOREIGN KEY (`T` )
REFERENCES `mydb`.`T` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;

最佳答案

您的问题部分在于您无法区分它与哪个表相关。

此外,如果您只能有一个记录与其他三个或四个表中的任何一个匹配,则这不是正常关系,无法使用正常技术建模。触发器可以确保这是真的,但其中只有 id 列阻止它匹配 10 的表 A 中的 id 和 10 的表 C 中的 anid(违反规则)。

顺便说一句,命名列 ID 通常不是维护的好选择。如果您将列命名为 PK 的表名称并使用 Pk 的确切名称作为 FK,则发生的事情会更加清楚。

您的另一种解决方案是在中间表中为每种类型的 id 和触发器设置一个列,以确保其中只有一个具有值,但如果您需要所有 id,查询起来会很痛苦。 id 和 idtype 的复合 PK 可以确保一个类型内没有重复,但要完全没有重复,您将需要一个触发器。

关于sql - 外键关系和 "belongs to many",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2790844/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com