The problem with the accepted answer (Quassnoi) is that the object relationship is wrong: the company is not a subtype of the website owner; we had companies before we had websites, and we may have companies that own websites. In addition, it seems to me that website ownership is the relationship between the website and the person or company, that is, we must have a table of relations (or two) in the diagram. This may be an acceptable approach, allowing you to keep personal ownership of the website separately from corporate ownership of the website and reduce them only if necessary, for example. via VIEW s:
CREATE TABLE People ( person_id CHAR(9) NOT NULL UNIQUE, -- external identifier person_name VARCHAR(100) NOT NULL ); CREATE TABLE Companies ( company_id CHAR(6) NOT NULL UNIQUE, -- external identifier company_name VARCHAR(255) NOT NULL ); CREATE TABLE Websites ( url CHAR(255) NOT NULL UNIQUE ); CREATE TABLE PersonalWebsiteOwnership ( person_id CHAR(9) NOT NULL UNIQUE REFERENCES People ( person_id ), url CHAR(255) NOT NULL UNIQUE REFERENCES Websites ( url ) ); CREATE TABLE CorporateWebsiteOwnership ( company_id CHAR(6) NOT NULL UNIQUE REFERENCES Companies( company_id ), url CHAR(255) NOT NULL UNIQUE REFERENCES Websites ( url ) ); CREATE VIEW WebsiteOwnership AS SELECT url, company_name AS website_owner_name FROM CorporateWebsiteOwnership NATURAL JOIN Companies UNION SELECT url, person_name AS website_owner_name FROM PersonalWebsiteOwnership NATURAL JOIN People;
The problem with the above is that there is no way to use database restrictions to enforce the rule that a website belongs either to a person or company, but not to both.
If we can assume that the DBMS imposes control restrictions (in accordance with the accepted answer), we can use the fact that (the person) and the company are legal entities and use the supertype table ( LegalPersons ) but still maintain the approach of the relationship table ( WebsiteOwnership ) , this time using VIEW to separate personal ownership of a website separate from corporate ownership of a website, but this time with strongly typed attributes:
CREATE TABLE LegalPersons ( legal_person_id INT NOT NULL UNIQUE, -- internal artificial identifier legal_person_type CHAR(7) NOT NULL CHECK ( legal_person_type IN ( 'Company', 'Person' ) ), UNIQUE ( legal_person_type, legal_person_id ) ); CREATE TABLE People ( legal_person_id INT NOT NULL legal_person_type CHAR(7) NOT NULL CHECK ( legal_person_type = 'Person' ), UNIQUE ( legal_person_type, legal_person_id ), FOREIGN KEY ( legal_person_type, legal_person_id ) REFERENCES LegalPersons ( legal_person_type, legal_person_id ), person_id CHAR(9) NOT NULL UNIQUE, -- external identifier person_name VARCHAR(100) NOT NULL ); CREATE TABLE Companies ( legal_person_id INT NOT NULL legal_person_type CHAR(7) NOT NULL CHECK ( legal_person_type = 'Company' ), UNIQUE ( legal_person_type, legal_person_id ), FOREIGN KEY ( legal_person_type, legal_person_id ) REFERENCES LegalPersons ( legal_person_type, legal_person_id ), company_id CHAR(6) NOT NULL UNIQUE, -- external identifier company_name VARCHAR(255) NOT NULL ); CREATE TABLE WebsiteOwnership ( legal_person_id INT NOT NULL legal_person_type CHAR(7) NOT NULL UNIQUE ( legal_person_type, legal_person_id ), FOREIGN KEY ( legal_person_type, legal_person_id ) REFERENCES LegalPersons ( legal_person_type, legal_person_id ), url CHAR(255) NOT NULL UNIQUE REFERENCES Websites ( url ) ); CREATE VIEW CorporateWebsiteOwnership AS SELECT url, company_name FROM WebsiteOwnership NATURAL JOIN Companies; CREATE VIEW PersonalWebsiteOwnership AS SELECT url, person_name FROM WebsiteOwnership NATURAL JOIN Persons;
We need new DBMS functions for "distributed foreign keys" ("For each row in this table, there must be exactly one row in one of these tables") and "multiple assignment" to allow adding data to tables thus limited in one SQL expression . Unfortunately, we are far from getting such opportunities!