Вот один из способов реализации таблиц супертипа / подтипа для вашего приложения.
Во-первых, таблица супертипов. Он содержит все столбцы, общие для всех подтипов.
CREATE TABLE publications (
pub_id INTEGER NOT NULL PRIMARY KEY,
pub_type CHAR(1) CHECK (pub_type IN ('A', 'B', 'P', 'S')),
pub_url VARCHAR(64) NOT NULL UNIQUE,
CONSTRAINT publications_superkey UNIQUE (pub_id, pub_type)
);
Далее, несколько таблиц подтипов.
CREATE TABLE articles (
pub_id INTEGER NOT NULL,
pub_type CHAR(1) DEFAULT 'A' CHECK (pub_type = 'A'),
placeholder CHAR(1) NOT NULL, -- placeholder for other attributes of articles
PRIMARY KEY (pub_id, pub_type),
FOREIGN KEY (pub_id, pub_type) REFERENCES publications (pub_id, pub_type)
);
CREATE TABLE stories (
pub_id INTEGER NOT NULL,
pub_type CHAR(1) DEFAULT 'S' CHECK (pub_type = 'S'),
placeholder CHAR(1) NOT NULL, -- placeholder for other attributes of stories
PRIMARY KEY (pub_id, pub_type),
FOREIGN KEY (pub_id, pub_type) REFERENCES publications (pub_id, pub_type)
);
Ограничения CHECK () и FOREIGN KEY в этих подтипах запретить строки ссылаться на неправильный тип строки в супертипе. Он эффективно разделяет значения pub_id среди подтипов, гарантируя, что любой данный pub_id может отображаться в одной и только одной из подтипов. Вот почему вам нужно либо ограничение PRIMARY KEY, либо NOT NULL UNIQUE для пары столбцов {publications.pub_id, publications.pub_type}.
Таблица для комментариев проста. Учитывая, что он должен иметь одну и ту же структуру для всех подтипов, вы можете ссылаться на супертип.
CREATE TABLE comments (
pub_id INTEGER NOT NULL REFERENCES publications (pub_id),
comment_timestamp TIMESTAMP NOT NULL DEFAULT now(),
commenter_email VARCHAR(10) NOT NULL, -- Only allow people who have
-- really short email addresses
comment_text VARCHAR(30) NOT NULL, -- Keep 'em short!
PRIMARY KEY (pub_id, comment_timestamp, commenter_email)
);
Добавьте немного данных.
INSERT INTO publications VALUES
(1,'A', 'url 1 goes here'),
(2,'A', 'url 2 goes here'),
(3,'S', 'url 3 goes here');
INSERT INTO articles VALUES
(1,'A', 'A'),
(2,'A', 'B');
INSERT INTO stories VALUES
(3,'S', 'A');
INSERT INTO comments VALUES
(1, now(), 'a@b.com','You''re stupid'),
(1, now(), 'b@c.com', 'You''re stupid, too!');
Теперь вы можете создать просмотр всех статей и разрешение соединения. Вы бы сделали то же самое для каждого из подтипов.
CREATE VIEW articles_all AS
SELECT P.*, A.placeholder
FROM publications P
INNER JOIN articles A ON (A.pub_id = P.pub_id)
Вы можете предпочесть такие имена, как «publish_articles» вместо «articles_all».
Чтобы выбрать одну статью и все ее комментарии, вы можете просто присоединиться к двум таблицам. (Но см. Ниже, почему вы, вероятно, этого не сделаете.)
SELECT A.*, C.*
FROM articles_all A
LEFT JOIN comments C ON (A.pub_id = C.pub_id)
WHERE A.pub_id = 1;
Возможно, вы на самом деле не сделали этого для веб-интерфейса, потому что dbms должны были бы вернуть 'n' копии статья, где 'n' равно количеству комментариев. Но имеет смысл делать это в некоторых приложениях. В приложениях, где это имеет смысл, вы должны использовать одно обновляемое представление для каждого подтипа, а код приложения чаще всего будет использовать обновляемые представления.
Более распространенное деловое приложение супертипа / Подтип включает в себя «Стороны» (супертип), «Организации» и «Физические лица» (подтипы, неофициально компании и people . Адреса, такие как «комментарии» в приведенном выше примере , связаны с супертипом, поскольку все подтипы (организации и отдельные лица) имеют адреса.
Вам необходимо изменить культуру вашего приложения:
http://msdn.microsoft.com/en-us/library/b28bx3bh(v=VS.100).aspx