数据完整性和限制

发布于 2024-11-06 19:44:52 字数 1300 浏览 5 评论 0原文

使用以下表布局:

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 设置,我可以通过某种方式通过约束或索引进行限制,即对于 Something 表中标识的每个 SomethingTypeCode (1, 2, 3),只能有一个 IsObsolete = N与之相关?

我希望这能解释我正在努力实现的目标。我只是不知道要研究什么来解决这个问题。我希望数据库本身尽可能保持数据完整性,然后将其扩展到 PHP。


编辑:

为了回应我对 VoteyDisciple 答案的困惑。

电子邮件类型代码:P = 个人、B = 商业、S = 学校

这是我的设计:

将允许一个人在给定的类型代码中拥有不止一种类型的电子邮件(即 2 个业务电子邮件),并避免数据库中的重复,并且不需要任何空值。由于我只关心每个类别中有一封活动电子邮件(系统将使用的电子邮件),这就是 IsObsolete 发挥作用的地方。我可以保留历史记录,避免重复,避免空值,并确保在此处输入系统的电子邮件地址是唯一的。

当然,这也带来了我在原始问题中所述的问题。

VoteyDisciple 的方法

如果我描述错误(或正确),VoteyDisciple 请告诉我。

在此处输入图像描述

“如果给定类型只能有一个” - 只有一个活动而不是时间,不仅系统中的一个。
“现在 ActiveId 可以为 NULL” - 我已经强调过我不想要 NULL
“或者它可以指向特定的某项记录。”类型定义了记录。

除了我上面的回答之外,这似乎增加了任何查询的撤消复杂性。我的回答基于我对您所呈现内容的理解。我们要么不互相理解,要么这只是我的问题。我很欣赏您的意见,但就目前而言,我认为它不是一个可行的解决方案。

Using the following table layout:

TABLE Something
(
    SomethingId             
    Name      
    DateCreated
    IsObsolete ('Y','N')       
    PRIMARY KEY (SomethingId)
    Foreign Key (SomethingTypeCode)
;


TABLE SomethingType
(
    SomethingTypeCode ('1','2','3')             
    Description             
    PRIMARY KEY (SomethingTypeCode)
);

With a PHP/MySQL setup is there some way that I can restrict through a constraint or index that for each SomethingTypeCode (1, 2, 3) identified in the Something table, there can only be one IsObsolete = N associated with it?

I hope that explains what I am trying to accomplish. I just don't know what to look into to resolve this. I want data integrity to be maintained as much as possible in the db itself and then extend that to the PHP.


EDIT:

In response to the confusion I am getting with VoteyDisciple answer.

EmailTypeCode: P = Personal, B = Business, S = School

Here is my design:

enter image description here

This will allow a Person to have more then one type of email in a given typecode (i.e. 2 business emails) and avoid duplication in the db and not require any nulls. Since i am only concerned with having one active email in each category (the one that will be used by the system) that is where the IsObsolete comes into play. I can keep the history, avoid duplication, avoid nulls, and ensure unique email addresses entered into the system here.

Of course this also brings about my problem as stated in original question.

VoteyDisciple's approach

VoteyDisciple please let me know if I depicted it wrong (or correct).

enter image description here

"If there can be only one for a given type" - Only one active not a time, not only one in the system.
"Now ActiveId can be NULL" - I have emphasized I do not want NULLs
"or it can point to a specific Something record." The type defines the record.

On top of my responses above this seems to add undo complexity into any queries. My responses are based on my understanding of what you have presented. We are either not understanding each other or it is only on my end. I appreciate your input, but as presented I don't see it as a viable solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

渡你暖光 2024-11-13 19:44:52

您应该能够在 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 有问题。

You should be able to deal with this in a MySQL trigger:

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 ;

And something similar on insert.
The trigger will check to see if you're trying to set IsObselete to N and if you are then update all the rows that have the same type that are not the current row and set them to Y.

You may get into issues with deadlocks if you're using InnoDB but I don't think you'll have an issue with MyISAM.

九厘米的零° 2024-11-13 19:44:52

如果给定类型只能有一个属性,则该属性是 SomethingType 的属性,而不是 Something 的属性。

TABLE SomethingType
(
    SomethingTypeCode ('1','2','3')             
    ActiveId
    Description             
    PRIMARY KEY (SomethingTypeCode)
    Foreign Key (Something)
);

现在,ActiveId 可以为 NULL(表示此 SomethingType 没有未过时的 Something),也可以指向特定的 Something 记录。

显然,您不能在其中容纳多个 ID,因此保证您有零个或一个活动项目。

If there can be only one for a given type, that's a property of SomethingType, not of Something.

TABLE SomethingType
(
    SomethingTypeCode ('1','2','3')             
    ActiveId
    Description             
    PRIMARY KEY (SomethingTypeCode)
    Foreign Key (Something)
);

Now ActiveId can be NULL (indicating there is no non-obsolete Something for this SomethingType), or it can point to a specific Something record.

And you obviously can't fit more than one ID in there, so you're guaranteed to have either zero or one active item.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文