【问题标题】:How to properly design a database for rating system with multiple rating criterias如何为具有多个评分标准的评分系统正确设计数据库
【发布时间】:2020-09-12 15:13:04
【问题描述】:

我正在为我当前的 django 项目做评分系统,我需要实施数据库进行评分。数据库会很简单,如果我没有多个评分标准,现在我不得不问:

你会如何设计一个包含这些对象的数据库: 用户 额定对象 评分

当然会有多个用户和对象被评级以及多个评级标准。

现在我目前的想法是为每个对象创建几个单独的表,例如:

USER(pk=id, fk= rating.id)
RATED_OBJECT(pk=id, fk= rating.id, overall_attribute_1, overall_attribute_2, overall_rating)
RATING(pk=user.id, pk=rated_object.id, fk=rated_attribute1, fk=rated_attribute2)
RATED_ATRIBUTE(pk=id, fk=type, value)
TYPE(pk=id, name) - 2 types since we have 2 attributes to be rated

(现在overal_rating将是所有整体属性的平均值,每个整体属性将是评分中一种类型的所有属性的平均值,其中被评分对象的id将相同)

我对进行这种“多 FK 对一 PK”操作有一种不好的感觉。为每个评级属性制作表格会更有意义吗?或者也许说 **** 它并在 RATING 本身中有值并拧 RATED_ATTRIBUTE 和 TYPE 表?大家觉得呢?

编辑:如果我的猜测是正确的——这意味着我可以将 RATING 与 RATED_ATTRIBUTE 连接多次(多个 fk 到 1 pk),我需要设置约束,所以当评级发生时,它都会正确地转到 RATING 字段 (当对属性一进行评级时,在 RATING 中我需要确保 RATED_ATTRIBUTE 中的类型与 RATING 中的类型完全相同)。现在,我无法转过头来,如何使用 Django 的 CheckConstraint,有什么想法吗? sn-p:

class RatedAttribute(models.Model):
    TYPE = (
        ('attribute1', 'attribute1'),
        ('attribute2', 'attribute2'),

    )

    id      = models.IntegerField(primary_key= True, auto_created=True)
    type    = models.CharField(max_length=120, choices=TYPE, default=None)
    value   = models.IntegerField()


class Rating(models.Model):
    user_id           = models.ManyToManyField(User, through='RatingUser')
    rated_object_id   = models.ManyToManyField(RatedObject, through='Rating_Object')

    attribute1  = models.ForeignKey(RatedAttribute, on_delete=models.CASCADE)
    attribute2  = models.ForeignKey(RatedAttribute, on_delete=models.CASCADE)

    class Meta:
        constraints = [
            CheckConstraint(
                *NO IDEA HOW TO FILL THIS CONSTRAINT(s)*, name='something')
        ]

    def __str__(self):
        return self.place

代码正确连接Rating_Object

【问题讨论】:

  • 那么你的问题是你想要有多种类型的评级?
  • 是的,在本例中,用户将能够评价rated_attribute1 和rated_attribute2。到目前为止,我想到了将 RATING 表与 RATED_ATTRIBUTE 多次连接,并限制属性类型,所以它是正确连接的。
  • 你能举个例子吗。因为我脑子里的一切都是这样的:1星,2星,3星,等等。
  • 好的,会尝试 :) :例如,我们可以正确评价对象 FOOD。现在,例如,额定属性 1 可以是味道,额定属性 2 可以是气味。所以用户将能够评价味道和气味。在用户评分发生后(是的,它可能是 1-5 星),另一个 sql 查询发生,我将计算总体评分(所有用户的每种味道和气味的平均值,然后总体评分 = 每个属性的总体评分平均值) 对于某些 FOOD 对象。现在,计算平均评分的查询不是问题,问题是实现数据库,我可以做这些操作:)
  • 所以您当前的问题不是评级而是产品。据我了解,有很多不同类型的产品,一个评级标准并不适用于所有产品?

标签: sql django database sqlite


【解决方案1】:

这是我在阅读了您在 cmets 中放入的内容后得出的结论。

如果对此答案有任何评论。

from django.db import models
from django.contrib.auth.models import User
# Create your models here.
rating_choices = [
        (1, '1 Star'),
        (2, '2 Stars'),
        (3, '3 Stars'),
        (4, '4 Stars'),
        (5, '5 Stars'),
]

class Product(models.Model):
    class Meta:
        verbose_name = "Product"
        verbose_name_plural = "Products"

    name = models.CharField(max_length=50)
    description = models.TextField()

    def __str__(self):
        return self.name

class Rating(models.Model):
    class Meta:
        verbose_name = "rating"
        verbose_name_plural = "ratings"

    user = models.ForeignKey(User, verbose_name=_(""), on_delete=models.CASCADE, related_name="rating")
    product = models.ForeignKey(Product, verbose_name=_(""), on_delete=models.CASCADE, related_name="product_rating")
    taste = models.IntegerField(choices=rating_choices)
    smell = models.IntegerField(choices=rating_choices)    
    def __str__(self):
        return "{self.user.username}'s rating for {self.product.name}"

【讨论】:

  • 这就是我猜不应该这样做的方式,因为当您通过NF规则创建数据库时,您不应该将TASTE和SMELL与RATING放在同一个表中,因为您可以轻松分解它到自己的桌子上,对吧?更好的是,您可以使用提到的味道和气味的可能值以及值 1-5 来制作表 TYPE_OF_RATING。你怎么看?或者从数据库实现的角度来看,表评级中的味道和气味没有问题?
  • @Nuwanda 为味道和气味制作另一个模型只会让您必须查询多个不同的模型才能获得 1 个产品的评级。在我的示例中,由于味道和气味在同一个评级模型中,因此您只需在需要时查询评级模型以及用户和产品
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-28
  • 2011-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-06
  • 1970-01-01
相关资源
最近更新 更多