我已经研究了一些DataBase规范化和设计方法来正确构建数据,并且已经读到循环引用不是最佳的,因为它会危害数据的完整性。我有一个数据结构,我无法弄清楚如何消除循环引用或确保没有引入错误的引用。
数据库要求:
答案 0 :(得分:2)
您没有循环引用。多对一关联指向一方的方向。你所拥有的是两条需要保持一致的关联路径。
您可以通过将函数依赖项AttributeID -> FruitTypeID
和DeliveryID -> FruitTypeID
非规范化为Attribute_Fruit
,然后创建两个复合FK约束来实现:
CREATE TABLE Attribute (
ID INT NOT NULL,
FruitTypeID INT NOT NULL,
Name VARCHAR(255) NOT NULL,
PRIMARY KEY (ID),
FOREIGN KEY (FruitTypeID) REFERENCES FruitType (ID),
UNIQUE KEY (ID, FruitTypeID)
);
CREATE TABLE Delivery (
ID INT NOT NULL,
FruitTypeID INT NOT NULL,
Amount INT NOT NULL,
PRIMARY KEY (ID),
FOREIGN KEY (FruitTypeID) REFERENCES FruitType (ID),
UNIQUE KEY (ID, FruitTypeID)
);
我向Attribute
和Delivery
添加了复合唯一键,以支持Attribute_Fruit
表上的复合FK约束:
CREATE TABLE Attribute_Fruit (
AttributeID INT NOT NULL,
DeliveryID INT NOT NULL,
FruitTypeID INT NOT NULL,
PRIMARY KEY (AttributeID, DeliveryID),
FOREIGN KEY (AttributeID, FruitTypeID) REFERENCES Attribute (ID, FruitTypeID),
FOREIGN KEY (DeliveryID, FruitTypeID) REFERENCES Delivery (ID, FruitTypeID)
);
重叠的复合FK约束将强制实现您正在寻找的一致性。 FruitTypeID
中的Attribute_Fruit
在逻辑上是冗余的,但是对于完整性是必需的,并且由于FK约束,不存在更新异常的风险。
正如您所提到的,触发器是实现相同目标的另一种方式,并且正确实施,它们是可靠的而不是脆弱的。但是,我认为上述方法更简单。
答案 1 :(得分:1)
您需要做的是认识到“水果属性”不是交付的属性,而只是水果的属性。因此,您应该将交付模型与交付项目中的多对多关系进行建模,并且没有提及水果属性。
更好的是:拼出这些矩形应该意味着什么。也就是说,拼出这些表中的行事实表明现实世界中发生的事情。这样做,你会发现自己正在考虑问题。您将发现自己理解 所有中适用于您的业务案例的方面的问题。解决方案将自然而然地实现。而且很可能会涉及比你在这里更多的矩形。你目前还没有这样做。至少你还没有向我们提供任何细节。任何试图回应的人都会被迫进行猜测,这可能是无可救药的。就像我在第一段中所做的猜测一样(例如,我假设没有必要记录哪些“属性”已经在旧的交付中“交付”,这是在对某些属性应用之前完成的。一些水果)。