简体   繁体   中英

Data integrity and restrictions

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:

在此输入图像描述

This will allow a Person to have more then one type of email in a given typecode (ie 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).

在此输入图像描述

"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.

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM