В клоне StackOverflow, что отношения таблица Comments должны иметь к Вопросам и Ответам?

Для одного приложения я использую SchemaUpdate, встроенную в Hibernate, прямо из класса начальной загрузки, поэтому схема проверяется при каждом запуске приложения. Это заботится о добавлении новых столбцов или таблиц, что в основном происходит со зрелым приложением. Для обработки особых случаев, таких как удаление столбцов, загрузчик просто вручную запускает ddl в try / catch, поэтому, если он уже был удален один раз, он просто молча выдает ошибку. Я не уверен, что сделал бы это с критически важными данными в производственном приложении, но за несколько лет и сотни развертываний у меня никогда не было проблем с этим.

12
задан Tiny 2 August 2015 в 02:37
поделиться

6 ответов

Я бы выбрал почтовый подход. Это лучший способ обеспечить ссылочную целостность.

Если вам нужны дополнительные столбцы для ответов и вопросов, соответственно, поместите их в дополнительные таблицы с однозначной связью с сообщениями.

Например, в синтаксисе MySQL:

CREATE TABLE Posts (
  post_id     SERIAL PRIMARY KEY,
  post_type   CHAR(1),              -- must be 'Q' or 'A'
  -- other columns common to both types of Post
  UNIQUE KEY (post_id, post_type) -- to support foreign keys
) ENGINE=InnoDB;

CREATE TABLE Comments (
  comment_id  SERIAL PRIMARY KEY, 
  post_id     BIGINT UNSIGNED NOT NULL,
  -- other columns for comments (e.g. date, who, text)
  FOREIGN KEY (post_id) REFERENCES Posts(post_id)
) ENGINE=InnoDB; 

CREATE TABLE Questions (
  post_id     BIGINT UNSIGNED PRIMARY KEY,
  post_type   CHAR(1),              -- must be 'Q'
  -- other columns specific to Questions
  FOREIGN KEY (post_id, post_type) REFERENCES Posts(post_id, post_type)
) ENGINE=InnoDB;

CREATE TABLE Answers (
  post_id     BIGINT UNSIGNED PRIMARY KEY,
  post_type   CHAR(1),              -- must be 'A'
  question_id BIGINT UNSIGNED NOT NULL,
  -- other columns specific to Answers
  FOREIGN KEY (post_id, post_type) REFERENCES Posts(post_id, post_type)
  FOREIGN KEY (question_id) REFERENCES Questions(post_id)
) ENGINE=InnoDB;

Это называется наследованием таблицы классов. В этой статье есть хороший обзор моделирования наследования с помощью SQL: « Наследование в реляционных базах данных ».

Может быть полезно использовать post_type, чтобы данное сообщение могло быть только одним ответом или одним вопросом. Вы не хотите, чтобы и ответ, и вопрос ссылались на одно данное сообщение. Это цель столбца post_type выше. Вы можете использовать ограничения CHECK для принудительного применения значений в post_type , или используйте триггер, если ваша база данных не поддерживает ограничения CHECK.

Я также сделал презентацию, которая может вам помочь. Слайды доступны на http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back . Вам следует прочитать разделы о полиморфных ассоциациях и Entity-Attribute-Value.


Если вы используете наследование одной таблицы, как вы сказали, что используете Ruby on Rails, то SQL DDL будет выглядеть следующим образом:

CREATE TABLE Posts (
  post_id     SERIAL PRIMARY KEY,
  post_type   CHAR(1),              -- must be 'Q' or 'A'
  -- other columns for both types of Post
  -- Question-specific columns are NULL for Answers, and vice versa.
) ENGINE=InnoDB;

CREATE TABLE Comments (
  comment_id  SERIAL PRIMARY KEY, 
  post_id     BIGINT UNSIGNED NOT NULL,
  -- other columns for comments (e.g. date, who, text)
  FOREIGN KEY (post_id) REFERENCES Posts(post_id)
) ENGINE=InnoDB; 

Вы можете используйте в этом примере ограничение внешнего ключа, и я рекомендую вам это сделать! : -)

Философия Rails склоняется к тому, чтобы принудительно применять модель данных на уровне приложения. Но без ограничений, обеспечивающих целостность в базе данных, вы рискуете, что ошибки в вашем приложении или специальные запросы из инструмента запросов могут повредить целостность данных.

t поддерживает ограничения CHECK.

Я также сделал презентацию, которая может вам помочь. Слайды доступны на http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back . Вам следует прочитать разделы о полиморфных ассоциациях и Entity-Attribute-Value.


Если вы используете наследование одной таблицы, как вы сказали, что используете Ruby on Rails, то SQL DDL будет выглядеть следующим образом:

CREATE TABLE Posts (
  post_id     SERIAL PRIMARY KEY,
  post_type   CHAR(1),              -- must be 'Q' or 'A'
  -- other columns for both types of Post
  -- Question-specific columns are NULL for Answers, and vice versa.
) ENGINE=InnoDB;

CREATE TABLE Comments (
  comment_id  SERIAL PRIMARY KEY, 
  post_id     BIGINT UNSIGNED NOT NULL,
  -- other columns for comments (e.g. date, who, text)
  FOREIGN KEY (post_id) REFERENCES Posts(post_id)
) ENGINE=InnoDB; 

Вы можете используйте в этом примере ограничение внешнего ключа, и я рекомендую вам это сделать! : -)

Философия Rails склоняется к тому, чтобы принудительно применять модель данных на уровне приложения. Но без ограничений, обеспечивающих целостность в базе данных, вы рискуете, что ошибки в вашем приложении или специальные запросы из инструмента запросов могут повредить целостность данных.

t поддерживает ограничения CHECK.

Я также сделал презентацию, которая может вам помочь. Слайды доступны на http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back . Вам следует прочитать разделы о полиморфных ассоциациях и Entity-Attribute-Value.


Если вы используете наследование одной таблицы, как вы сказали, что используете Ruby on Rails, то SQL DDL будет выглядеть следующим образом:

CREATE TABLE Posts (
  post_id     SERIAL PRIMARY KEY,
  post_type   CHAR(1),              -- must be 'Q' or 'A'
  -- other columns for both types of Post
  -- Question-specific columns are NULL for Answers, and vice versa.
) ENGINE=InnoDB;

CREATE TABLE Comments (
  comment_id  SERIAL PRIMARY KEY, 
  post_id     BIGINT UNSIGNED NOT NULL,
  -- other columns for comments (e.g. date, who, text)
  FOREIGN KEY (post_id) REFERENCES Posts(post_id)
) ENGINE=InnoDB; 

Вы можете используйте в этом примере ограничение внешнего ключа, и я рекомендую вам это сделать! : -)

Философия Rails склоняется к тому, чтобы принудительно применять модель данных на уровне приложения. Но без ограничений, обеспечивающих целостность в базе данных, вы рискуете, что ошибки в вашем приложении или специальные запросы из инструмента запросов могут повредить целостность данных.

Слайды доступны на http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back . Вам следует прочитать разделы о полиморфных ассоциациях и Entity-Attribute-Value.


Если вы используете наследование одной таблицы, как вы сказали, что используете Ruby on Rails, то SQL DDL будет выглядеть следующим образом:

CREATE TABLE Posts (
  post_id     SERIAL PRIMARY KEY,
  post_type   CHAR(1),              -- must be 'Q' or 'A'
  -- other columns for both types of Post
  -- Question-specific columns are NULL for Answers, and vice versa.
) ENGINE=InnoDB;

CREATE TABLE Comments (
  comment_id  SERIAL PRIMARY KEY, 
  post_id     BIGINT UNSIGNED NOT NULL,
  -- other columns for comments (e.g. date, who, text)
  FOREIGN KEY (post_id) REFERENCES Posts(post_id)
) ENGINE=InnoDB; 

Вы можете используйте в этом примере ограничение внешнего ключа, и я рекомендую вам это сделать! : -)

Философия Rails склоняется к тому, чтобы принудительно применять модель данных на уровне приложения. Но без ограничений, обеспечивающих целостность в базе данных, вы рискуете, что ошибки в вашем приложении или специальные запросы из инструмента запросов могут повредить целостность данных.

Слайды доступны на http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back . Вам следует прочитать разделы о полиморфных ассоциациях и Entity-Attribute-Value.


Если вы используете наследование одной таблицы, как вы сказали, что используете Ruby on Rails, то SQL DDL будет выглядеть следующим образом:

CREATE TABLE Posts (
  post_id     SERIAL PRIMARY KEY,
  post_type   CHAR(1),              -- must be 'Q' or 'A'
  -- other columns for both types of Post
  -- Question-specific columns are NULL for Answers, and vice versa.
) ENGINE=InnoDB;

CREATE TABLE Comments (
  comment_id  SERIAL PRIMARY KEY, 
  post_id     BIGINT UNSIGNED NOT NULL,
  -- other columns for comments (e.g. date, who, text)
  FOREIGN KEY (post_id) REFERENCES Posts(post_id)
) ENGINE=InnoDB; 

Вы можете используйте в этом примере ограничение внешнего ключа, и я рекомендую вам это сделать! : -)

Философия Rails склоняется к тому, чтобы принудительно применять модель данных на уровне приложения. Но без ограничений, обеспечивающих целостность в базе данных, вы рискуете, что ошибки в вашем приложении или специальные запросы из инструмента запросов могут повредить целостность данных.


Если вы используете наследование одной таблицы, как вы сказали, что используете Ruby on Rails, то SQL DDL будет выглядеть так:

CREATE TABLE Posts (
  post_id     SERIAL PRIMARY KEY,
  post_type   CHAR(1),              -- must be 'Q' or 'A'
  -- other columns for both types of Post
  -- Question-specific columns are NULL for Answers, and vice versa.
) ENGINE=InnoDB;

CREATE TABLE Comments (
  comment_id  SERIAL PRIMARY KEY, 
  post_id     BIGINT UNSIGNED NOT NULL,
  -- other columns for comments (e.g. date, who, text)
  FOREIGN KEY (post_id) REFERENCES Posts(post_id)
) ENGINE=InnoDB; 

В этом примере вы можете использовать ограничение внешнего ключа, и я рекомендую вам это сделать ! : -)

Философия Rails склоняется к тому, чтобы принудительно применять модель данных на уровне приложения. Но без ограничений, обеспечивающих целостность в базе данных, вы рискуете, что ошибки в вашем приложении или специальные запросы из инструмента запросов могут повредить целостность данных.


Если вы используете наследование одной таблицы, как вы сказали, что используете Ruby on Rails, то SQL DDL будет выглядеть так:

CREATE TABLE Posts (
  post_id     SERIAL PRIMARY KEY,
  post_type   CHAR(1),              -- must be 'Q' or 'A'
  -- other columns for both types of Post
  -- Question-specific columns are NULL for Answers, and vice versa.
) ENGINE=InnoDB;

CREATE TABLE Comments (
  comment_id  SERIAL PRIMARY KEY, 
  post_id     BIGINT UNSIGNED NOT NULL,
  -- other columns for comments (e.g. date, who, text)
  FOREIGN KEY (post_id) REFERENCES Posts(post_id)
) ENGINE=InnoDB; 

В этом примере вы можете использовать ограничение внешнего ключа, и я рекомендую вам это сделать ! : -)

Философия Rails склоняется к тому, чтобы принудительно применять модель данных на уровне приложения. Но без ограничений, обеспечивающих целостность в базе данных, вы рискуете, что ошибки в вашем приложении или специальные запросы из инструмента запросов могут повредить целостность данных.

Но без ограничений, обеспечивающих целостность в базе данных, вы рискуете, что ошибки в вашем приложении или специальные запросы из инструмента запросов могут повредить целостность данных.

Но без ограничений, обеспечивающих целостность в базе данных, вы рискуете, что ошибки в вашем приложении или специальные запросы из инструмента запросов могут повредить целостность данных.

16
ответ дан 2 December 2019 в 06:09
поделиться

Вы можете создать одну таблицу комментариев с двумя внешними ключами: один для questions.questionID, а другой - для answers.answerId

2
ответ дан 2 December 2019 в 06:09
поделиться

In the social networks that I build I do something a bit different. If you think about it a comment could be attached to just about any Entity in a site. This could be a blog post, a forum thread or post, an article, someones picture, a persons profile, a vendor of a service, etc. For this reason I create a SystemObjects table which holds the object type (table reference). For the most part I create records for the Entities of my system that will accept comments...but these map directly to my tables. The SystemObjects table houses the SystemObjectID, and a friendly name for future reference (a lookup table).

With this in place I then create a Comments table which has the SystemObjectID reference to tell me what table to go look in. Then I also house the SystemObjectRecordID which tells me which PK of the referenced table I am interested in (along with all the standard comment data).

I use this notion of the SystemObject table for many other generic far reaching concepts in my sites. Think about Tags, Ratings, Comments, and any other dangling fruit that might be attached across your site and aggregated up for quick use.

Read more about this in my book ASP.NET 3.5 Social Networking.

4
ответ дан 2 December 2019 в 06:09
поделиться

Вам потребуются две таблицы доменов, которые объединяют отношения CommentsForQuestions и CommentsForAnswers. По сути, вам нужно создать 5 таблиц для этой цели:

Questions
Answers
Comments
CommentsForQuestions (relates comments to questions)
CommentsForAnswers (relates comments to answers)

Единственная проблема в том, что она уступает идее публикации, поскольку ссылочная целостность не так сильна. Я могу убедиться, что CommentsForQuestions связан с комментарием и вопросом, но я не могу предотвратить одновременное соединение вопроса и ответа с одним и тем же комментарием.

1
ответ дан 2 December 2019 в 06:09
поделиться

There are 2 ways that I can think of.

First, use another column in the Comment table to indicate whether the comment belongs to Question or Answer. So the PK of the Comment table becomes wher PostID is the foreign key to Question or Answer and PostType can be someting like 1=Question and 2=Answer.

Second, use a relationship table for each Question and Answer. So you have a Question, Answer, Comment, QuestionComment, and AnswerComment table.

Let's say the primary key of Question, Answer, Comment tables are QuestionID, AnswerID, and CommentID respectively. Then the columns of QuestionComment would be [QuestionID, CommentID]. Similarly, the columns of AnswerComment would be [AnswerID, CommentID].

1
ответ дан 2 December 2019 в 06:09
поделиться

Отношение внешнего ключа; у вас могут быть QuestionComments и AnswerComments, или вы можете иметь в комментариях столбец внешнего ключа и для вопросов, и для ответов (и эти столбцы должны быть исключительными).

Лично я бы выбрал подход сообщений.

Edit : На рассмотрение есть третий подход, который может сработать; у вас может быть таблица комментариев, а затем просто таблица ассоциации, которая связывает комментарии либо с вопросом, либо с ответом (так, чтобы у комментариев был идентификатор и комментарий, у объединенной таблицы были бы CommentID, AnswerID и QuestionID ). Или у вас может быть просто таблица комментариев, затем таблица ассоциаций "ответ-комментарий" и отдельная таблица связи "вопрос-комментарий".

1
ответ дан 2 December 2019 в 06:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: