3

I have the following design. Each user has it's own contacts, it's own hosts and assign those to a domain which belongs only to him.

I want to insure that the host you assign to the domain belongs to the user that domain is assigned to.

Is it something that I have to insure in my application logic?

If I set domains.user_id foreign key to reference host.user_id and user_id.id does it eliminate my issue?

enter image description here

By the way can anyone suggest me a better design for my schema?

  • 1
  • Are domains assigned to hosts and contacts? And for every domain, the user of its host and the user of its contact should be one and the same (user)? – ypercubeᵀᴹ Sep 09 '13 at 11:09
  • In other words: Say that I am a contact of a particular user. Can I get a domain that belongs to a different user? – ypercubeᵀᴹ Sep 09 '13 at 11:12
  • Then the linked question above provides an answer. One last question. Can you have domains that are "free", not assigned (to hosts or users)? – ypercubeᵀᴹ Sep 09 '13 at 11:17
  • Ok,although I'm little bit confused, I'll try to explain to you. The difference I see with the link you provided to me is that it has many artists to many albums while mine domains,hosts,contacts are on one user and only. As for your last question domain can only exist without host. – giannis christofakis Sep 09 '13 at 11:23
  • It's 1 artist : many albums actually. It's the same diamond shape with user (or artist) at the top. The only differences may lie with whether an album track can exist without a track or an album (it cannot) which may not be the case with your requirements. – ypercubeᵀᴹ Sep 09 '13 at 11:27
  • @ypercube Oh,sorry I meant albums and tracks. I see a many to many relationship in this example,while in mine I can't see one. – giannis christofakis Sep 09 '13 at 11:29
  • A contact can have may domains and a host can have many domains, right? So the domains entity is basically a many to many relationship between contacts and hosts. – ypercubeᵀᴹ Sep 09 '13 at 11:30
  • @ypercube A contact of a user can be assign to multiple domains of that specific user and only,but a domain of that user can be assigned only to one contact of that user.The same to hosts. Isn't that a one to many relationship? Or I am fundamentally wrong? – giannis christofakis Sep 09 '13 at 11:38
  • One to many between contacts and domains, correct. One to many between hosts and domains, too. I was talking about the (implied) relationship. between contacts and hosts. – ypercubeᵀᴹ Sep 09 '13 at 11:42

1 Answers1

6

This is a rather common problem, when the design has a "diamond" shape. See similar questions:
Many to Many and Weak Entities

With MySQL, I'd use something like this:

(0) Note that I prefer user_id as name for the primary key of users and not id for all the tables. I find the SQL code totally confusing otherwise (plus you can use the JOIN ... USING (tablename_id) syntax).

(1) The extra UNIQUE constraints in tables hosts and contacts are needed for the foreign keys from the domains table.
(2) The two FOREIGN KEY constraints from the domains table are changed to use composite keys (include the user_id).

Table users

CREATE TABLE users
( user_id INT NOT NULL AUTO_INCREMENT
, username VARCHAR(45) NOT NULL
-- other columns
, PRIMARY KEY (user_id)
) ;

Table contacts

CREATE TABLE contacts
( contact_id INT NOT NULL AUTO_INCREMENT
, user_id INT NOT NULL
, info TEXT
, PRIMARY KEY (contact_id)
, UNIQUE INDEX (user_id, contact_id)       -- added, see comment 1 above
, INDEX (user_id)
, FOREIGN KEY (user_id)
    REFERENCES users (user_id)
) ;

Table hosts

CREATE TABLE hosts
( host_id INT NOT NULL AUTO_INCREMENT
, user_id INT NOT NULL
, name VARCHAR(45) NOT NULL
--
, PRIMARY KEY (host_id)
, UNIQUE INDEX (user_id, host_id)          -- added, see comment 1 above
, INDEX (user_id)
, FOREIGN KEY (user_id)
    REFERENCES users (user_id)
) ;

Table domains

CREATE TABLE domains
( domain_id INT NOT NULL AUTO_INCREMENT
, user_id INT NOT NULL
, contact_id INT NOT NULL
, host_id INT NULL                       -- nullable based on comments
, name VARCHAR(45) NOT NULL
-- other columns
, PRIMARY KEY (domain_id)
, FOREIGN KEY (user_id, contact_id)       -- composite FK, see comment 2
    REFERENCES contacts (user_id, contact_id)
, FOREIGN KEY (user_id, host_id)          -- composite FK, see comment 2
    REFERENCES hosts (user_id, host_id)
) ;
ypercubeᵀᴹ
  • 97,895
  • 13
  • 214
  • 305
  • @ypercube I see you used a composite reference key, but why you didn't use a composite primary key for hosts and contacts, like I did? – giannis christofakis Sep 26 '15 at 19:53
  • 1
    It doesn't matter if the composite key is primary or unique. If the columns are not null, there is no difference. Either can be referenced by foreign keys from other tables. – ypercubeᵀᴹ Sep 26 '15 at 19:58
  • 1
    The choice of primary key matters only in the specific implementation (MySQL's InnoDB engine uses the primary key as clustered key of the table). But that is about the physical design of the table, not the logical design. – ypercubeᵀᴹ Sep 26 '15 at 20:04