In einem Klon Stackoverflow, welche Beziehung sollte eine Kommentare Tabelle zu Fragen und Antworten haben?

StackOverflow https://stackoverflow.com/questions/987654

Frage

In einer Anwendung ähnlich wie Stackoverflow, dass ich bin Gebäude, Ich versuche, was Beziehung meiner Questions, Answers und Comments Tabellen haben sollen, zu entscheiden.

Ich kann Questions haben und Answers beide durch eine einzige Tabelle Posts dargestellt werden.

Das würde erlauben Comments einen einzigen Fremdschlüssel müssen Posts.

Aber wenn Questions und Answers getrennte Tabellen sind, welche Beziehungen sollten auf jeden dieser Comments haben?

UPDATE: Auch wenn die gewählte Antwort eine Klasse Table Inheritance Ansatz empfiehlt und dies scheint der beste Ansatz in der Datenbank Hinsicht ist diese Option nicht durch die Rails ORM unterstützt. Also, in Rails meine Modelle haben Single Table Inheritance zu bedienen und wird wahrscheinlich so aussehen:

class Post < ActiveRecord::Base  
end  

class Question < Post  
  has_many :answers, :foreign_key => :parent_id  
  has_many :comments, :foreign_key => :parent_id  
end  

class Answer < Post  
  belongs_to :question, :foreign_key => :parent_id  
  has_many :comments, :foreign_key => :parent_id  
end  

class Comment < Post  
  belongs_to :question, :foreign_key => :parent_id  
  belongs_to :answer, :foreign_key => :parent_id  
end


class CreatePosts < ActiveRecord::Migration  
    def self.up  
      create_table :posts do |t|  
        t.string :type 
        t.string :author   
        t.text :content  
        t.integer :parent_id   
        t.timestamps  
      end  
    end  


    def self.down  
      drop_table :posts  
    end  
end
CREATE TABLE "posts" (
  "id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,  
  "type" varchar(255),  
  "author" varchar(255),  
  "content" text,  
  "parent_id" integer,  
  "created_at" datetime, 
  "updated_at" datetime
  );
War es hilfreich?

Lösung

würde ich mit dem Ansatz Beiträge gehen. Dies ist der beste Weg, um referenzielle Integrität zu gewährleisten.

Wenn Sie zusätzliche Spalten für Antworten und Fragen müssen jeweils legt sie in zusätzlichen Tabellen mit einer Eins-zu-Eins-Beziehung mit Beiträgen.

Zum Beispiel in MySQL Syntax:

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;

Das ist die Klasse Tabelle Vererbung genannt. Es gibt einen schönen Überblick über die Modellierung Vererbung mit SQL in diesem Artikel: „ Vererbung in relationalen Datenbanken . "

Es kann hilfreich sein post_type zu verwenden, um ein gegebener Beitrag nur eine Antwort oder eine Frage sein kann. Sie wollen nicht, sowohl eine Antwort und eine Frage einen bestimmten Beitrag zu verweisen. Das ist also der Zweck der post_type Spalte oben. Sie können CHECK-Einschränkungen verwenden, um die Werte in post_type zu erzwingen, oder sonst einen Trigger verwenden, wenn die Datenbank nicht CHECK-Einschränkungen nicht unterstützt.

Ich habe auch eine Präsentation, die Ihnen helfen können. Die Folien sind bis unter http://www.slideshare.net/billkarwin/sql- Antipatterns-strike-back . Sie sollten die Abschnitte über Polymorphe Verbände und Entity-Attribut-Wert lesen.


Wenn Sie Single Table Inheritance verwenden, wie Sie sagen, Sie Ruby-verwenden on Rails, dann der SQL-DDL würde wie folgt aussehen:

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; 

Sie können einen Fremdschlüssel in diesem Beispiel verwenden, und ich empfehle, dass Sie tun! : -)

Rails-Philosophie neigt dazu, in der Anwendungsschicht setzen Durchsetzung des Datenmodells zu begünstigen. Aber ohne die Integrität der Durchsetzung Einschränkungen bei in der Datenbank haben Sie das Risiko, dass Fehler in der Anwendung oder Ad-hoc-Abfragen aus einem Abfrage-Tool können die Datenintegrität beeinträchtigen.

Andere Tipps

In den sozialen Netzwerken, die ich baue ich etwas tun, ein bisschen anders. Wenn man darüber nachdenkt ein Kommentar könnte in einer Website fast jede Entität angebracht werden. Dies könnte ein Blog-Post, ein Forum-Thread oder Post, ein Artikel, someones Bild sein, ein Personen-Profil, ein Anbieter eines Dienstes, etc. Aus diesem Grund habe ich eine SystemObjects Tabelle zu erstellen, die den Objekttyp (Tabelle Referenz) hält. Ich schaffe Datensätze für die Entities meines Systems zum größten Teil, die Kommentare akzeptieren ... aber diese Karte direkt an meine Tabellen. Die SystemObjects Tabelle befindet sich die SystemObjectID, und einen Namen für zukünftige Referenz (eine Lookup-Tabelle).

In diesem Ort habe ich dann eine Kommentare Tabelle erstellen, die die SystemObjectID Bezug hat mir zu sagen, was Tisch zu gehen suchen. Dann habe ich auch die SystemObjectRecordID Haus, das mir sagt, welche PK der referenzierten Tabelle Ich bin an (zusammen mit alle Standard-Kommentardaten).

Ich verwende diesen Begriff der system Tabelle für viele andere generische weitreichende Konzepte in meinen Seiten. Denken Sie über Schlagwörter, Bewertungen, Kommentare und jede andere baumelt Frucht, die auf Ihrer Website und aggregiert nach oben für den schnellen Einsatz angebracht werden könnten.

Lesen Sie mehr dazu in meinem Buch ASP.NET 3.5 Social Networking .

Sie können eine einzelne Kommentare Tabelle mit zwei Fremdschlüssel, ein bis questions.questionID und die andere zu answers.answerId

erstellen

Sie müssen zwei Domänen Tabellen, die die Beziehungen zusammen CommentsForQuestions und CommentsForAnswers bringen. Grundsätzlich sind Sie gehen zu müssen 5 Tabellen für diesen Zweck erstellen:

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

Das einzige Problem, das hat ist, dass es auf die Beiträge Idee minderwertig ist, weil die referentielle Integrität nicht so stark ist. Ich kann garuntee dass CommentsForQuestions auf einen Kommentar verbindet und eine Frage, aber ich kann nicht sowohl eine Frage und eine Antwort von der Verbindung zu dem gleichen Kommentar verhindern.

Eine Fremdschlüssel-Beziehung; Sie können entweder QuestionComments und AnswerComments haben, oder Sie können haben Kommentare haben eine Fremdschlüsselspalte sowohl für Fragen und Antworten (und haben diese Spalten exklusiv).

Persönlich würde ich mit dem Ansatz Beiträge gehen.

Edit: Auf Überlegung, gibt es eine dritte Möglichkeit, die funktionieren könnte; Sie könnten eine Kommentare Tabelle, und dann nur eine Zuordnungstabelle, die die Kommentare entweder mit einer Frage oder Antwort (so würde Kommentare haben eine ID und den Kommentar zuordnet, würde die Join-Tabelle ein CommentID haben, eine answerID und ein QuestionID ). Oder Sie nur eine Kommentar Tabelle haben könnten, dann hat eine Antwort-Kommentar Zuordnungstabelle, und eine separate Frage-Kommentar Zuordnungstabelle.

Es gibt zwei Möglichkeiten, die ich denken kann.

Zuerst eine andere Spalte in der Kommentar-Tabelle verwenden, um anzuzeigen, ob der Kommentar Frage oder Antwort gehört. So ist die PK der Kommentar Tabelle wird wher PostID der Fremdschlüssel auf die Frage oder Antwort und PostType kann some sein wie 1 = Frage und 2 = Antwort.

Zweitens, eine Beziehungstabelle für jede Frage und Antwort verwenden. So haben Sie eine Frage, Antwort, Kommentar, QuestionComment und AnswerComment Tabelle.

Nehmen wir an, den Primärschlüssel Frage, Antwort, Kommentar Tabellen sind QuestionID, answerID und CommentID sind. Dann würden die Spalten von QuestionComment sein [QuestionID, CommentID]. In ähnlicher Weise würden die Spalten von AnswerComment sein [answerID, CommentID].

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top