Php 数据完整性和限制
使用下表布局:Php 数据完整性和限制,php,mysql,validation,data-integrity,Php,Mysql,Validation,Data Integrity,使用下表布局: TABLE Something ( SomethingId Name DateCreated IsObsolete ('Y','N') PRIMARY KEY (SomethingId) Foreign Key (SomethingTypeCode) ; TABLE SomethingType ( SomethingTypeCode ('1','2','3')
TABLE Something
(
SomethingId
Name
DateCreated
IsObsolete ('Y','N')
PRIMARY KEY (SomethingId)
Foreign Key (SomethingTypeCode)
;
TABLE SomethingType
(
SomethingTypeCode ('1','2','3')
Description
PRIMARY KEY (SomethingTypeCode)
);
对于PHP/MySQL设置,是否有某种方式可以通过约束或索引进行限制,即对于SomethingTypeCode表中标识的每个SomethingTypeCode(1、2、3),只能有一个Isobsolite=N与之关联
我希望这能解释我想要实现的目标。我只是不知道该怎么解决这个问题。我希望在数据库中尽可能多地维护数据完整性,然后将其扩展到PHP
编辑: 为了回应我对VoteyDisciple答案的困惑 EmailTypeCode:p=个人,B=商业,S=学校 这是我的设计: 这将允许一个人在给定的类型代码(即2封商业电子邮件)中拥有一种以上的电子邮件类型,避免数据库中的重复,并且不需要任何空值。因为我只关心在每个类别(系统将使用的类别)中有一封活动电子邮件,这是Isobsolite发挥作用的地方。我可以保留历史记录,避免重复,避免空值,并确保在系统中输入唯一的电子邮件地址 当然,正如原问题所述,这也带来了我的问题 VoteyDisciple的方法 如果我描述的是错误的(或正确的),请告诉我 “如果给定类型只能有一个”-一次只能有一个活动,而不是系统中的一个。
“现在ActiveId可以为NULL”-我强调我不想要NULL
“或者它可以指向特定的某物记录。”该类型定义该记录。
在我上面的回答之上,这似乎增加了任何查询的撤销复杂性。我的回答是基于我对你介绍的内容的理解。我们不是彼此不了解,就是我这边。我很感谢你的意见,但我认为这不是一个可行的解决方案 如果给定类型只能有一个属性,则该属性为
SomethingType
,而不是Something
TABLE SomethingType
(
SomethingTypeCode ('1','2','3')
ActiveId
Description
PRIMARY KEY (SomethingTypeCode)
Foreign Key (Something)
);
现在,ActiveId
可以是NULL
(表示此SomethingType没有非过时的某物),也可以指向特定的Something
记录
显然,您不能在其中放入多个ID,因此您可以保证有零个或一个活动项。您应该能够在MySQL触发器中处理此问题:
DELIMITER $$
CREATE TRIGGER before_something_update
BEFORE UPDATE ON Something
FOR EACH ROW BEGIN
IF NEW.IsObsolete = 'N' THEN
UPDATE Something SET IsObsolete = 'Y' WHERE SomethingId != NEW.SomethingId AND SomethingTypeID = NEW.SomethingTypeId;
END IF;
DELIMITER ;
还有类似的插页。
触发器将检查您是否正在尝试将IsObselete设置为N,以及是否正在更新所有类型与当前行不同的行,并将它们设置为Y
如果您使用InnoDB,您可能会遇到死锁问题,但我认为您不会对MyISAM产生问题。@VoteyDisciple我不确定这是我想要的。我知道我不想要
NULL
s。我还希望保留两个表之间的关系分解(规范化)。虽然您的方式是一种选择,但如果我理解正确,它会破坏我在整个数据库中拥有的内容。我理解您的建议,但问题是您拥有的内容没有规范化。您有一个功能上依赖于SomethingTypeCode
的字段,该字段存储在SomethingType
表之外的其他位置。如果您不想要NULL
值(即,必须始终有一个过时的东西
),您可以简单地指定列notnull
“问题是您拥有的东西没有规范化”。这是一个大胆的声明,特别是因为它是标准化的,而不是按照规定的要求Isobsolite
在功能上依赖于SomethingTypeCode
,而模式并不反映这一点。规范化不仅仅是将对象的属性存储在一个地方的问题;功能依赖性才是真正重要的。精确地遵循这些,您将得到一个规范化的模式。我确实向后阅读了IsObsolete=Y
。我将编辑我的答案以替换ActiveId
,因为很明显,您希望跟踪的是活动项,而不是过时项。感谢您的回复。以后才能深入研究。使用MySQL,因为您只能定义一个触发器操作,所以我必须选择操作(插入或更新)并将我能做的打包到其中,对吗?目前,这主要影响InnoDB表,尽管有些表可能会在需要时被更改,但这是有保证的。@enfield是的,您是对的,您需要将所有规则打包到一个或另一个触发器中,使用InnoDB,您可能能够避免死锁,以便锁定,因为您不需要在更新时触摸行或使用更新后触发器。此外(尽管我不完全确定),您可能还需要确保不在同一update语句中更新同一类型的多个项。