我有一个网站,里面有一个讨论论坛。所有问题都有唯一ID,答案也有唯一ID,外键引用问题ID。
我有一个用户登录。使用ajax,我可以发送数据(upvote / downvote,QID / AID,用户名)。但是几乎没有问题。
每当用户重新登录时,我希望当他打开一个问题时,应该显示他之前的upvotes和downvotes。
用户无法多次upvote / downvote同一个问题。就像他向+1提出一个问题一样,他只能将其投票,而不是再次投票。
根据我的解决方案。我正在考虑维护一个表,其中username是主键,另一个属性是他所做的所有upvotes和downvotes的列表。例如:
(username, array)
(baqir, up_A001 up_A050 down_Q011 up_Q123)
每当用户登录时,我都会使用此数组并确保用户之前的所有upvotes和downvotes都是原样。如果有新的投票,我将其添加到数组中。
有没有更好的解决方案?
P.S。不是必要的,而是我当前的数据库结构。
class Question(models.Model):
QID = models.CharField( default="",max_length=1000, primary_key=True)
title = models.CharField(max_length=30, default="")
description = models.CharField(max_length=1055, default="")
date = models.DateTimeField(default=datetime.now, blank=True)
username = models.CharField(max_length=6, default="")
votes = models.IntegerField(default=0)
approved = models.BooleanField(default=False)
def __str__(self):
return self.title
class Answer(models.Model):
AID = models.CharField(max_length=1000, default="", primary_key=True)
QID = models.ForeignKey(Question,on_delete=None)
description = models.CharField(max_length=1055, default="")
date = models.DateTimeField(default=datetime.now, blank=True)
username = models.CharField(max_length=6, default="")
votes = models.IntegerField(default=0)
approved = models.BooleanField(default=False)
def __str__(self):
return self.AID
我正在使用Django。而且我基本上想要任何stackoverflow实现他们的问题和答案投票。
答案 0 :(得分:3)
什么阵列人,你在说什么?您为每个Q / A或每个用户创建另一个表,或者您只链接两个内容的表,即用户和Q / A及其可以重复键的投票(此表没有主键)。 任何阵列式的东西都是时间和精力的损失,无论如何都违背了良好的数据库设计规则。
表保持投票的例子:
Table votes:
UID | QID | AID | VOTE
因此,您可以将每个用户与他/她投票的每个问题或答案联系起来。 QID或AID可以为NULL。当你提出一些问题时,你只需检查表格投票是否有任何关于它的说法以及与之相关的答案。如果当前的QID和UID匹配并且您得到结果,那么您只需采取相应的行动。
如果你有很多用户,这有可能会很慢,但基本上会很好用。
第二个解决方案是将你的问题/答案与另一个表格联系起来,只保留在做某事的用户(上/下投票)。这将使DB看起来更加混乱但是当您的用户找到给定的Q及其答案时,您只需检查此表是否有关于访问者的信息。如果我不够清楚,我重复一遍,每个Q和/或A的新表。
您可以反向应用相同的技术,即将用户连接到包含用户投票的所有Q / A的表,这可能是保持秩序和效率的最佳方式。因此,每次用户访问任何Q页面时,您都会检查他/她是否有该Q的历史记录。
没有数组,没有废话。只需一个额外的请求来检查当前查看的Q / A的状态。
答案 1 :(得分:1)
Upvote和Downvote场景可以使用代码处理,如果最后一次投票是upvote用户只有权限downvote,如果用户downvote他有权进行upvote,但为了保持状态,你告诉你可以保留历史记录一个数组。
答案 2 :(得分:1)
Dalen建议的第一种方法似乎最好
制作一个单独的表来存储投票,并在执行任何上/下操作之前,检查用户之前是否做过任何类似的操作。
如果他之前已完成相反的操作,请删除/停用其在表格中的上一个条目并创建一个新条目。 如果他之前已经针对该问题执行了相同的操作,则不执行任何操作,因为他的上/下投票已被计算在内。
强烈建议为这些任务制作表格,因为它不仅可以使您的工作更轻松,而且还可以为您提供更多的灵活性,例如您可以为每个操作添加时间戳来跟踪历史记录,或者您可以计算查询表格以查找对问题执行的总操作
答案 3 :(得分:0)
CREATE TABLE QuestionVotes (
UID ..., -- User id
QID ..., -- Question id
vote ENUM('up', 'down'),
PRIMARY KEY(QID, UID) -- for finding voting status of a question
INDEX(UID, QID) -- if you need the votes by a user
) ENGINE=InnoDB; -- to get benefit of clustered PK
同样为AnswerVotes
。
Upvote / downvote:查看该行是否存在,如果不存在,则创建该行。如果存在行,则删除该行或者抱怨用户上升/下降两次。
不要使用数组。它会变得太痛苦。
如果Django不能让你拥有复合PRIMARY KEY,那就放弃Django。
表中没有1000个字符键。磁盘空间和性能将受到影响。
用户只能是6个字符。缩放规模并不乐观?