Как вы структурируете базу данных, которая позволяет голосовать так же, как это делает stackoverflow? - PullRequest
5 голосов
/ 12 марта 2012

Я новичок в базах данных и веб-разработке, но я стараюсь изо всех сил, чтобы научиться, как сделать свой собственный динамический сайт.Я делаю это шаг за шагом и в настоящее время проектирую модель данных на бумаге.Интересно, как можно структурировать базу данных для веб-сайта, которая позволяет голосовать, например, как это делает stackoverflow?Если есть таблица, содержащая список вопросов, каждый созданный пользователем вопрос добавляется в эту таблицу.В этой таблице просто не может быть поля для подсчета голосов, потому что это позволило бы одному человеку иметь неограниченное количество голосов, верно?Таким образом, должен быть ключ, который подключается к другой таблице, которая подсчитывает голоса и отслеживает пользователей, чтобы они не могли голосовать дважды, правильно?Если это правда, это та часть, где я запутался.За каждый данный ответ также можно проголосовать.Значит ли это, что когда пользователь отправляет ответ, в дополнение к добавлению этого ответа, вероятно, в отдельную таблицу для ответов на каждый вопрос, модель должна также динамически генерировать новую таблицу для каждого ответа во время выполнения, чтобы отслеживать всеэти голоса?

Обратите внимание, что я специально не спрашиваю о том, как работает stackoverflow, а о том, как работает концепция взаимодействия с пользователем.

Одна вещь, которую я также хотел бы сделать, этозапрашивать активность одного пользователя, поэтому, если бы все эти таблицы нужно было создавать динамически для каждого фрагмента представленных данных, создавая дерьмовую нагрузку на таблицы с течением времени, не было бы очень медленно анализировать каждую таблицу, чтобыпроверить, предоставил ли конкретный пользователь какие-либо данные или проголосовал?

Есть ли лучший способ сделать это, что кто-то может объяснить с точки зрения мирян?Нет необходимости в конкретном коде ... Возможно, я это выясню позже, когда придет время.Я просто теоретизирую прямо сейчас и строю бумажную модель для дальнейшей работы.

РЕДАКТИРОВАТЬ: О, я вижу.Я думаю о таблицах в стиле Excel, когда думаю о таблицах базы данных, поэтому поправьте меня, если мое понимание неверно.Таким образом, каждый голос в масштабе всего сайта находится в одной таблице (перечисленной вертикально в электронной таблице), каждая из которых имеет строку данных (по горизонтали), которая связывает голосование с различными владельцами (пользователь и вопрос ИЛИ ответ)?Это верно?Я говорю вопрос ИЛИ ответ, потому что я не понимаю сценарий, в котором было бы целесообразно использовать их как атрибут голосования (не уверен, что это правильная терминология) вместо создания двух отдельных данных голосования за ответ и вопрос, которые обаголосование по.В основном, как я вижу, каждая строка представляет голос, и есть 3 поля: 1. Значение (+1 или -1), 2. От кого (имя пользователя), 3. К чему (вопрос или ответ).

Ответы [ 3 ]

3 голосов
/ 12 марта 2012

Вы должны посмотреть на все элементы. В основном у вас есть

Questions
Users
Answers
Votes

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

tblQuestions
    questid
    question
    userid

тогда

tblAnswer
    Answer
    answerid
    userid
    questid 
    accepted (to flag as accepted answer)

и наконец

tblVote
    vote (up or down)
    questid
    answerid
    userid

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

3 голосов
/ 12 марта 2012
CREATE TABLE "QuestionVote" (
    "Question" INT NOT NULL, -- To identify the question being voted on
    "User" INT NOT NULL, -- To identify the user who is casting their vote
    "Vote" SMALLINT NOT NULL CHECK ("Vote" = 1 OR "Vote" = -1),
    PRIMARY KEY ("Question", "User"),
    CONSTRAINT "Constr_QuestionVote_Question"
        FOREIGN KEY "QuestionVote_Question" ("Question")
        REFERENCES "Question" ("ID"),
    CONSTRAINT "Constr_QuestionVote_User"
        FOREIGN KEY "QuestionVote_User" ("User")
        REFERENCES "User" ("ID")
)

Примечание.Ответом на проблему в дизайне базы данных никогда не является «Создание новой таблицы на лету для каждого нового (пользователь / обсуждение / элемент любого рода)».Если вы считаете хорошей идеей создать новую таблицу для каждого пользователя, вы допустили ошибку!Остановитесь и подумайте, как вы можете делать то, что вы хотите делать с фиксированным набором таблиц.

0 голосов
/ 27 декабря 2016

Используйте подход к документу NOSQL. (CouchDB)

База данных: Stacklike

Документы в базе данных Stacklike :

{
  "type": "question",
  "user": "<userid>"
  ...
}

{
  "type": "answer",
  "user": "<userid>",
  "question": "<questionid>"
  ...
}

{
  "type": "vote",
  "user": "<userid>",
  "question": "<questionid>",
  "weight": "<weight>"
  ...
}

{
  "type": "user",
  ...
}

Просмотров: 1012 * *

К списку голосов, отсортированных по вопросу

map(doc){
  if (doc.type === 'vote'){
    emit(doc.questionid, doc)
}

Просмотр подсчета голосов и итогов (статистика)

map(doc){
  if (doc.type === 'vote'){
    emit(doc.questionid, doc.weight)
}
reduce(keys,values, rereduce){
  _stats
}
...