产品投票系统的数据库设计
我正在制作一个系统,用户可以对产品投赞成票或反对票,我需要能够明确计算出产品的涨跌量,以及最近一段时间的总分。
每个投票都可以选择带有评论,并且用户需要能够回显/增强其他人的评论(有点像转发),这还将根据转发的父投票添加/减去产品的总分。
以下是我当前建议的表格:
产品
ID、名称、category_id
投票
ID、user_id、product_id、parent_id、评论、分数、日期时间
用户
ID、用户名等。
我想我可能需要一个评论表才能有效地做到这一点?根据我在 StackOverflow 上读到的一些建议,投票的分数字段为 1 或 -1,这将允许我收集该列的 SUM()
来计算总票数,另一种可能性是单独的 vote_up 和 vote_down 表...但我只是不确定。
I'm am making a system where a user can vote up or down on a product, I need to be able to explicitly work out the amount of ups and downs a product has, as well as a total score for a recent period.
Each vote can optionally have a comment with it, and users need the ability to echo/boost other peoples comments (kinda like a retweet), and this will also add/subtract the total score of the product depending on the parent vote being retweeted.
Here are my current proposed tables:
Product
ID, name, category_id
Vote
ID, user_id, product_id, parent_id, comment, score, datetime
User
ID, username etc.
I am thinking I will possibly need a comments table to do this effectively? The votes' score field is either 1 or -1 as per some advice I read on StackOverflow which would allow me to gather the SUM()
of that column to calculate total votes, another possibility would be to have separate vote_up and vote_down tables...but I am just not sure.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
根据你想要做什么,这可能是一个非常复杂的问题,但这是我对最简单方法的看法(例如,我可以在下班前 10 分钟内拼凑出什么;-P)
我会尝试 StackOverflow/ HotOrNot 风格的方法,并将其排名存储为无符号整数。
然后在“投票”表中存储投票(向上/向下)。我认为你的“VOTES”表看起来不错(尽管我会使用枚举作为 SCORE 数据类型,或者使用某种策略来确保投票不能通过 XSS 操纵。例如,有人修改了投票,所以他们的投票是+10,000而不是+1,那么这就不酷了)
对于一个有趣的小应用程序,您可能可以通过在用户点击时增加或减少计数来完成,但是如果您正在做任何事情横向扩展,然后您将通过每 10-15 分钟运行一次的批处理过程进行投票计算和排名。
同样在这个级别,您将开始使用算法来加权投票值。例如,如果同一用户每天(或每隔一次)对同一产品多次投票(向上或向下),则第一次之后的投票不应计入计算产品的排名。
例如,Quora 的排名算法是如何工作的
如果用户是“高级用户”或拥有更活跃的帐户,也许他们的投票比新的投票更重要用户投票。我认为在 Yelp 上,如果您的评论不超过一到两条,那么您的评分和评论不会被计算在内,直到您达到最低评论数量。确实,天空是极限。
PS。我还建议您阅读 o'Reilly 的这本书,了解解决此类问题的一些策略
Depending on what you want to do, this can be an incredibly sophisticated problem, but here's my take on the simplest way (eg. what i can throw together in the 10 min before I leave work ;-P)
I would try the StackOverflow/HotOrNot style approach, and Store their ranking as an unsigned integer.
Then in your 'VOTES' table, you store the Vote (up/down). I think the table you have for your 'VOTES' table looks fine( although I would use either an enumeration as the SCORE datatype, or some strategy to ensure that a vote can't be manipulated via XSS. eg. someone modifies the vote so that their vote up is +10,000 instead of +1, then that would not be cool )
For a small fun app, you can probably get by with incrementing or decrementing the count when the user clicks, but if you are doing anything with aspirations of scaling out, then you would do the vote calculation and ranking via some batch process that runs every 10-15 minutes.
Also at this level, you would start using an algorithm to weight the vote values. For example, if the same user votes (up or down) the same product more than once a day(or once every) then the votes after the first should not count towards calculating the rank of the product.
For Example, here is how Quora's Ranking Algorithm works
If the user is a "Power User" or has an account that is more active, maybe their vote is more important than a new users vote. I think on Yelp, if you don't have more than one or two reviews, your rating and reviews don't get counted until you meet some minimum number of reviews. Really, the skies the limit.
PS. I would also recommend checking out this o'Reilly book on some of the strategies for solving these kinds of problems
如果您期望大量用户同时投票,那么您确实需要考虑性能......
一个天真的方法可能看起来像这样(如果我过度简化您的示例,并且如果 T-SQL 不是您的毒药,我很抱歉):
您将在其中通过总结向上/向下投票表来执行产品更新。坏的!
如果有大量用户投票,则不断地对同一张表进行插入/更新/选择肯定会发生死锁。
更好的方法是完全删除“分数”列,仅插入到向上/向下投票表中,然后根据需要进行选择。您没有理由不能在代码(即 PHP、C# 或其他)中计算总和,并且它避免了更新 Products 表(至少在计算分数时)。换句话说,将分数存储在 Products 表上不会给您带来任何好处,而且只是不必要的开销。
当我说更新在大容量系统中“可能”很糟糕时,我是根据经验说的。与最后插入或选择(假设您的表已正确索引)相比,更新的成本很高,并且在这种情况下很容易在不知不觉中取出大量锁。
If you expect a large number of users simultaneously voting, you really need to consider performance....
A naive approach might look something like this (my apologies if i oversimplify your example, and if T-SQL isn't your poison):
where you will be performing updates to Products by summing up/down vote tables. BAD!
If you have a large number of users voting, deadlocks are sure to occur by constantly inserting/updating/selecting against the same table.
A better approach would be to drop the Score column altogether, only insert into the up/down vote tables, and select as needed. There's no reason you can't calculate the sum in code (i.e. PHP, C#, or whatever), and it avoids ever having to update the Products table (at least for calculating the Score). In other words, storing the Score on the Products table buys you nothing, and is just unnecessary overhead.
I speak from experience when I say updates "can" be bad in high volume systems. Updating is expensive when compared to inserting at the end or selects (assuming your table is properly indexed), and it's very easy to unknowingly take out a substantial lock in situations like this.
Beginning CakePHP一书有一个 Ajax 教程,介绍如何实现评论的有效投票(向上/向下)系统。我几年前做过这个教程。我不确定它有多安全,或者它是否会成为您的项目的良好基础,但可能值得一看以获取一些想法。
Book Beginning CakePHP has an Ajax tutorial on implementing a working voting (up/down) system on comments. I did the tutorial a few years ago. I am not sure how secure it is or if it would be a good foundation for your project, but it would probably be worth having a look at for some ideas.