繁体   English   中英

帖子的多重评级系统(如爱,明星)

[英]Multiple rating system for posts (like, love, star)

我需要为帖子开发一个投票系统。 每个用户都可以一个帖子点击拇指图标,点击图标炉爱岗位,今后也许我有一个恒星系统的替代品。

我正在寻找更好的解决方案来实现这个系统,现在,我想到了这两种方式:

  • 1)每个投票系统一个表
tbl like

id
post_id
user_id
value // value even 1

tbl love

id
post_id
user_id
value // value even 1

tbl star

id
post_id
user_id
value // value between 1 and 5

  • 2)所有投票系统的单一表格
tbl rate

id
post_id
user_id
type // 'like' or 'love' or 'star'
value // value between 1 and 5

哪个更好的解决方案?

和其他的事情,当我查询多个帖子不好SELECT和sum(或平均)每次投票, 也许是很好的保存在帖子表中当前喜欢/ love / star的总和(或平均)来加快查询,然后更新每个新/喜欢/爱/明星的帖子?

最后一件事, 让用户看看他是否已经投了一些帖子 ,这是一个很好的解决方案吗? SELECT post_id FROM rate WHERE user_id = <MYUSERID> AND post_id IN (<ARRAYOFPOSTS>)然后将检索到的post_id与主查询的post_id进行比较?

谢谢!

正如埃里克所说,拥有多个表通常不是一个非常好的表现。

对于每个表,MySQL需要维护内部数据结构,数据字典,文件描述等...

使用解决方案2

就未来应用程序的性能和可伸缩性而言,这将是最佳解决方案。 您只需要允许您的应用程序在前端显示新类型的投票,而不必在扩展投票时支持全新的表格。

在获取给定文章的统计信息时,您可以按照说明,每次用户投票时都不需要每次都获取完整计数,但是性能增益根本不会明显,而是制作一些好的索引一旦需要,加快速度。

如果您希望向用户显示他是否已投票给某个帖子,我建议您只需查看您在解决方案2中描述的rate表。如果您希望限制应用程序中的查询数量,您可以按照说明获取所有帖子页面,然后查询那些。 然而,我认为这里的性能提升也很小。

在可预见的未来,一些好的指标可以解决您的大多数性能问题。 通常,您需要分割数据的唯一时间是整个数据库无法处理所有流量。 来自Airbnb团队的这篇文章让我们知道何时可能出现这种情况。

一个小小的提示是不要过度思考应用程序。 通常最好从小开始,以简单的方式做事。 这样您就不会引入超出必要的问题。 一旦应用程序增长,问题就会自然而然,你会在它们到来时解决它们。

您的第二种方法是实体属性值模型的“简单”实现。 但实际上EAV没有什么比这更简单的了。 通常EAV用于用户定义的属性。 这不是这种情况。 我在你的帖子中没有看到任何其他正当理由。 “每次实现新功能时,我都不想创建新的表或列”是一个糟糕的功能。

如果一个表优于多个表,则也没有一般规则。 纯数量的表格没有说明数据库设计的质量。 您需要分析需求,实体和关系。 这让我想到了下一点......

您的前两个表甚至不是实体。 “用户喜欢帖子”和“用户喜欢帖子”是纯粹的关系。 value列没有意义,因为它只能包含1 ,因此不包含任何信息。 所以你的表应该看起来像:

user_post_likes (
    user_id (FK, PK)
    post_id (FK, PK)
)

user_post_loves (
    user_id (FK, PK)
    post_id (FK, PK)
)

user_post_ratings (
    user_id (FK, PK)
    post_id (FK, PK)
    rating [1-5]
)

前两个表与第三个表明显不同。 将它们合并到一个表中将是一个奇怪的想法。 并且前两个表既不应该合并,如果它们实际上是两个不同的关系,即使它们具有相同的签名。 (这类似于将两个函数sum(x,y)diff(x,y)合并为calc(operator, x, y) 。)

下一点取决于要求。 我怀疑你是否曾想要同一个用户同时喜欢和喜爱的帖子。 如果喜欢和爱是独家的,那么它应该是一个实体。 表可能是这样的

user_post_flags (
    user_id (FK, PK)
    post_id (FK, PK)
    flag [like|love]
)

(对不起 - 找到好的标识符是一项艰巨的任务;-))

你可以用12 (或任何你想要的)代码'喜欢'和'爱'。 虽然它现在看起来像评级表,但它们仍然是两个不同的东西,应该有单独的表。

关于性能:这在很大程度上取决于任务/要求。 但我从未听说过因性能原因而选择的EAV模型。 (除了我自己,但不计算:-)。)

从你原来的问题

......将来也许我有一个明星系统作为替代品(原文如此)

你为什么试图解决你还没有的问题? 大概你不想同时运行反应系统( 如|爱 )和评级系统( 星级

我还怀疑一个什么样的爱情反应给你,用户,之上一的值。 我知道facebook做到了,但他们有大量的数据和另外4个反应( 伤心|生气|哇|哈哈

老实说,我会忘记除了喜欢之外的所有事情,并且开始时(来自@ PaulSpiegel的回答)

user_post_like (
  user_id (FK, PK)
  post_id (FK, PK)
)

继续前进!

您可以随时返回并添加到此系统,更改它,在系统需要时迁移数据

不要试图建立一个解决所有问题的超级通用系统,让自己决定疲劳

选项3:

user_id ... NOT NULL,
post_id ... NOT NULL,
like TINYINT NULL,   -- NULL means no action on LIKEing
love TINYINT NULL,
rate TINYINT NULL,
PRIMARY KEY(user_id, post_id),
INDEX(post_id, user_id)

或者以某种方式结合likelove

但是,当您编写查询以设置/更改/查询/汇总值时,会对如何设计模式进行真正的测试。

我的建议是方法2。

您可以在表中组合rate_type和rate_value。 为速率,爱情和明星创建所有可能性(1到5)这是未来原因的优势,当记录数增加时,它在tbl速率中的数据较少。

我没有提供'基于计数'的表格。 这种表在高流量时具有锁定能力。

这种组合的rate_type风格的缺点是,在代码中管理起来会有点困难。

我的建议;

tbl_rate_type

    id tinyint
    name nvarchar(5)  // if you want


tbl_rate_type_kind

    id tinyint,
    rate_type_id tinyint,
    rate_value tinyint,
    name nvarchar(5),   // if you want
    image_id smallint   // Advantage for viewing specific images simply


tbl rate

   id bigint
   post_id bigint 
   user_id int
   rate_type_kind_id  tinyint   // numeric value is better for indexing.

我正在寻找符合我收到的所有建议的解决方案。 我将尝试利用复合索引开发一个单独的列 这是我想要尝试的解决方案:

Table: rating

----------
user_id : bigint
post_id : bigint
rate_type : varchar (like/love/star)
rate : tinyint (0-5) // default 1 (for like/love)
----------

key: INDEX(user_id, post_id)
no PRIMARY // I don't care about duplicate key that may exist (same post like/love)

在此测试表中,我添加了1000行并尝试查询:

SELECT * FROM rating WHERE user_id = 21; //EXPLAIN KEY:rate ROWS:4

SELECT * FROM rating WHERE user_id = 21 AND rate_type = 'like'; //EXPLAIN KEY:rate ROWS:4

SELECT * FROM rating WHERE user_id = 21 AND rate_type = 'like'; //EXPLAIN KEY:rate ROWS:4

SELECT * FROM rating WHERE user_id = 21 AND post_id = 179 AND rate_type = 'like'; //EXPLAIN KEY:rate ROWS:1

你怎么看? 这是一个好的解决方案吗? 使用简单的INDEX而不是PRIMARY可能会产生什么后果? 我不能使用PRIMARY,因为可能会发生我有这三行:

 user_id: 21 - post_id: 173 - rate_type: 'like'
 user_id: 21 - post_id: 173 - rate_type: 'love'
 user_id: 21 - post_id: 173 - rate_type: 'star'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM