Я обновил модель NORMA, чтобы более точно соответствовать вашей диаграмме. Я вижу, где вы допустили несколько ошибок, но некоторые из них, возможно, были связаны с моей более ранней моделью.
Я обновил эту модель, чтобы предотвратить дублирование тегов. На самом деле это не имело значения.Но так как вы хотите, здесь (для Postgres):
START TRANSACTION ISOLATION LEVEL SERIALIZABLE, READ WRITE;
CREATE SCHEMA so;
SET search_path TO SO,"$user",public;
CREATE DOMAIN so.HashedPassword AS
BIGINT CONSTRAINT HashedPassword_Unsigned_Chk CHECK (VALUE >= 0);
CREATE TABLE so."User"
(
USER_ID SERIAL NOT NULL,
USER_NAME CHARACTER VARYING(50) NOT NULL,
EMAIL_ADDRESS CHARACTER VARYING(256) NOT NULL,
HASHED_PASSWORD so.HashedPassword NOT NULL,
OPEN_ID CHARACTER VARYING(512),
A_MODERATOR BOOLEAN,
LOGGED_IN BOOLEAN,
HAS_BEEN_SENT_A_MODERATOR_MESSAGE BOOLEAN,
CONSTRAINT User_PK PRIMARY KEY(USER_ID)
);
CREATE TABLE so.Question
(
QUESTION_ID SERIAL NOT NULL,
TITLE CHARACTER VARYING(256) NOT NULL,
WAS_SENT_AT_TIME TIMESTAMP NOT NULL,
BODY CHARACTER VARYING NOT NULL,
USER_ID INTEGER NOT NULL,
FLAGGED_FOR_MODERATOR_REMOVAL BOOLEAN,
WAS_LAST_CHECKED_BY_MODERATOR_AT_TIME TIMESTAMP,
CONSTRAINT Question_PK PRIMARY KEY(QUESTION_ID)
);
CREATE TABLE so.Tag
(
TAG_ID SERIAL NOT NULL,
TAG_NAME CHARACTER VARYING(20) NOT NULL,
CONSTRAINT Tag_PK PRIMARY KEY(TAG_ID),
CONSTRAINT Tag_UC UNIQUE(TAG_NAME)
);
CREATE TABLE so.QuestionTaggedTag
(
QUESTION_ID INTEGER NOT NULL,
TAG_ID INTEGER NOT NULL,
CONSTRAINT QuestionTaggedTag_PK PRIMARY KEY(QUESTION_ID, TAG_ID)
);
CREATE TABLE so.Answer
(
ANSWER_ID SERIAL NOT NULL,
BODY CHARACTER VARYING NOT NULL,
USER_ID INTEGER NOT NULL,
QUESTION_ID INTEGER NOT NULL,
CONSTRAINT Answer_PK PRIMARY KEY(ANSWER_ID)
);
ALTER TABLE so.Question
ADD CONSTRAINT Question_FK FOREIGN KEY (USER_ID)
REFERENCES so."User" (USER_ID) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE so.QuestionTaggedTag
ADD CONSTRAINT QuestionTaggedTag_FK1 FOREIGN KEY (QUESTION_ID)
REFERENCES so.Question (QUESTION_ID) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE so.QuestionTaggedTag
ADD CONSTRAINT QuestionTaggedTag_FK2 FOREIGN KEY (TAG_ID)
REFERENCES so.Tag (TAG_ID) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE so.Answer
ADD CONSTRAINT Answer_FK1 FOREIGN KEY (USER_ID)
REFERENCES so."User" (USER_ID) ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE so.Answer
ADD CONSTRAINT Answer_FK2 FOREIGN KEY (QUESTION_ID)
REFERENCES so.Question (QUESTION_ID) ON DELETE RESTRICT ON UPDATE RESTRICT;
COMMIT WORK;
Обратите внимание, что теперь есть отдельная таблица тегов с TAG_ID
в качестве первичного ключа. TAG_NAME
- отдельный столбец с ограничением уникальности над ним, предотвращающий дублирование тегов. Таблица QuestionTaggedTag
теперь имеет (QUESTION_ID
, TAG_ID
), что также является ее основным ключом.
Надеюсь, я не зашел слишком далеко, ответив на это, но когда я попытался написать меньшие ответы, мне все равно пришлось распутать мои более ранние ответы, и было проще просто опубликовать это.
Спасибо за ваш ответ! - Я буду играть с этим :) –
Кстати, все части NORMA, которые я использовал для этого, являются самыми легкими частями. Если вы хотите изучить его, учебники находятся на их сайте: http://www.ormfoundation.org/filesers/normalabs/default.aspx –
Вы, кажется, имеете в виду, что база данных все еще нуждается в запросах UPDATE и DELETE. -- Спасибо за ссылку! –