在Django / MySQL中1到1..0

时间:2012-03-13 09:26:05

标签: mysql django django-models innodb django-orm

我想就如何在Django中处理1到1..0关系提出一些建议。

我有一个产品列表,其中有许多属性在很长一段时间内都是空的(高达95%的产品)。我没有把它们放在产品表中,而是将它们放在单独的表中,所以我有以下内容(年龄和权重作为稀疏属性):

products
    id
    colour
    height
    width

product_age
    id
    product_id (FK)
    age

product_weight
    id
    product_id (FK)
    weight

首先,我知道在InnoDB中,nulls不会占用任何空间,所以我想如果我将稀疏属性移动到products表中它可能不会影响性能

其次,如果我确实保留了所有这些1到1..0的关系,我该如何在models.py中处理它。我目前有:

class Product(models.Model):
    colour = models.CharField(max_length=13)
    height = models.CharField(max_length=13)
    width = models.CharField(max_length=13)

class ProductAge(models.Model):
    product_id = models.ForeignKey(Product)
    age = models.CharField(max_length=13)

class ProductWeight(models.Model):
    product_id = models.ForeignKey(Product)
    weight = models.CharField(max_length=13)

将所有这些作为不同的对象是不实用的,这意味着在编码时我必须记住哪些属性是单独的对象。

任何帮助将不胜感激。感谢

更新

继承在这里工作,但它似乎仍然有点凌乱。我需要类似的东西:

class Product(models.Model):
    colour = models.CharField(max_length=13)
    height = models.CharField(max_length=13)
    width = models.CharField(max_length=13)

class ProductWithAge(Product):
    age = models.CharField(max_length=13)

class ProductWithAgeAndWeight(Product):
    weight = models.CharField(max_length=13)

然后我只在我的代码中实际使用ProductWithAgeAndWeight,因为我可以从中访问所有给定字段。数据库将在三个表之间拆分数据。也许我的命名是问题......有什么想法吗?

3 个答案:

答案 0 :(得分:1)

您应该使用OneToOneField

class ProductAge(models.Model):
    age = models.CharField(max_length=13)

class ProductWeight(models.Model):
    weight = models.CharField(max_length=13)

class Product(models.Model):
    colour = models.CharField(max_length=13)
    height = models.CharField(max_length=13)
    width = models.CharField(max_length=13)
    age = models.OneToOneField(ProductAge, null=True, blank=True)
    weight = models.OneToOneField(ProductWeight, null=True, blank=True)

这样,您就可以直接从.age实例直接访问.weightproduct属性。

您使用外键设置的方式,您可以通过.age_set.weight_set获取列表,检查列表是否为空,然后获取第一个元素。繁琐且容易出错。继承根本不是可行的方式。

答案 1 :(得分:0)

我认为你最想要的是模特经理, 和一个产品表,或2个表,一个表“Product”和另一个表“ProductAttribute”,它使用ProductAttributeManager存储{'attribute_name':'age','attribute_value':13,'product_id':3'}等内容

https://docs.djangoproject.com/en/dev/topics/db/managers/

答案 2 :(得分:0)

我不认为你需要在2个额外的表中使用单独的主键。 product_id就足够了:

products
    id
    colour
    height
    width

product_age
    product_id (PK) (FK)
    age

product_weight
    product_id (PK) (FK)
    weight

该模型将是:

class Product(models.Model):
    colour = models.CharField(max_length=13)
    height = models.CharField(max_length=13)
    width = models.CharField(max_length=13)

class ProductAge(models.Model):
    product_id = models.ForeignKey(Product)
    product_id.primary_key=True 
    age = models.CharField(max_length=13)

class ProductWeight(models.Model):
    product_id = models.ForeignKey(Product)
    product_id.primary_key=True 
    weight = models.CharField(max_length=13)

如果您想避免插入/更新产品的复杂性,您应该使用允许2行中的Null的products表。空虚确实占据了空间,但你应该关心的并不是那么大。