Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One to Many, but Identifying One of the Many as the 'Default'

I have a tables Person and Address. A Person can have multiple Address records, so a simple 1..* relationship with Address having a field referencing 'Person ID'.

Now, for a given Person I wish to identify their 'default' or 'primary' Address.

I've came up with two ideas, but I'm not convinced about either. Before I decide, can anyone offer any comments with regards to potential issues I could face down the line with either option...

(a). Could have a 'Default Address ID' on Person which would store the ID of the default Address record. Possible pitfall here is that an Address not belonging to this Person could be set here, so would need an additional check constraint to prevent this.

(b). Could have a 'Default' flag on the Address table, but this has the possibility of allowing multiple selections, so would need further checks so that when setting the flag, it is also cleared on all records belonging to the same Person.

Any

like image 388
Gavin Avatar asked Jan 23 '12 21:01

Gavin


People also ask

What is one-to-many and many-to-many?

In a One-To-Many relationship, one object is the "parent" and one is the "child". The parent controls the existence of the child. In a Many-To-Many, the existence of either type is dependent on something outside the both of them (in the larger application context).

Is many to one the same as one-to-many?

These two are both ending with creating the same relationship as below: It means there is no difference in one-to-many or many-to-one, except the angle that you are reading that from. If you look at this from Stores table, you have a “one-to-many” relationship.

What is the difference between one-to-one and one-to-many relationships you can join two tables to create a many-to-many relationship?

One-to-one relationships associate one record in one table with a single record in the other table. One-to-many relationships associate one record in one table with many records in the other table. Save this answer.

How do you know if a relationship is one-to-many?

A one-to-many relationship is created if only one of the related columns is a primary key or has a unique constraint. In the relationship window in Access, the primary key side of a one-to-many relationship is denoted by a number 1. The foreign key side of a relationship is denoted by an infinity symbol.


2 Answers

I would go with (B) and then safeguard the setting of the default bit.

From reading your comments on your question I want to add that to enforce that there is always at least 1 address set with the default bit you just need to handle that in your stored procedure.

Something like:

for an insert:

DECLARE @IsDefault bit;
SET @IsDefault = 0;

IF NOT EXISTS (SELECT * from tblAddresses WHERE PersonID = @PersonID And Default = 1)
BEGIN
   SET @IsDefault = 1;
END

INSERT INTO tblAddress (.... Default ... )
       VALUES (... @IsDefault ... );

for an update:

IF (@Default = 1)
BEGIN
   Update tblAddress
   SET
   tblAddress.Default = 0
   FROM tblAddress
   WHERE tblAddress.PersonID = @PersonID;

   Update tblAddress
   SET
   tblAddress.Default = 1
   WHERE ID = @AddressID;
END
ELSE
BEGIN
   IF EXISTS (SELECT * FROM tblAddresses WHERE PersonID = @PersonID AND Default = 1 AND AddressID != @AddressID)
   BEGIN
      UPDATE tblAddresses 
      SET Default = 0
      WHERE AddressID = @AddressID;
   END
END

In addition, you could prevent this from your user interface as well, but it doesn't hurt to have an extra layer of protection in the DB.

like image 125
Jonathan Henson Avatar answered Sep 17 '22 17:09

Jonathan Henson


Another option is (normalizing the data by) adding another table DefaultAddress:

Person
------
PersonId
... other stuff
PRIMARY KEY (PersonId)

Address
-------
AddressId
PersonId 
... other stuff
PRIMARY KEY (AddressId)
FOREIGN KEY (PersonId)
  REFERENCES Person(PersonId)

DefaultAddress
--------------
AddressId
PersonId 
PRIMARY KEY (AddressId)
UNIQUE KEY (PersonId)           --- every person has (max) one default address
FOREIGN KEY (PersonId, AddressId)
  REFERENCES Address(PersonId, AddressId)
like image 34
ypercubeᵀᴹ Avatar answered Sep 18 '22 17:09

ypercubeᵀᴹ