我正在使用Django,我的表格看起来像
class Product(models.Model):
category = models.CharField(max_length=50)
title = models.CharField(max_length=200)
class Value(models.Model):
name = models.CharField(max_length=200, unique=True)
class Attribute(models.Model):
name = models.CharField(max_length=200)
parent = models.ForeignKey('self', related_name='children')
values = models.ManyToManyField(Value, through='ProductAttributeRelationship', related_name='values')
class Meta:
unique_together = ('name', 'parent')
class ProductAttributeRelationship(models.Model):
product = models.ForeignKey(Product, related_name='products')
value = models.ForeignKey(Value, related_name='values')
attribute = models.ForeignKey(Attribute, related_name='attributes')
class Meta:
unique_together = ('product', 'value', 'attribute', 'price')
class Price(models.Model):
regular = models.IntegerField(blank=True, null=True)
sale = models.IntegerField(blank=True, null=True)
on_sale = models.NullBooleanField(blank=True)
created = models.DateTimeField(auto_now=True)
relation = models.ForeignKey(ProductAttributeRelationship)
class Meta:
unique_together = ('regular', 'sale', 'on_sale', 'sale_percentage')
将ForeignKeys
中的3 ProductAttributeRelationship
和ForeignKey
中的Price
置于ProductAttributeRelationship
是不是一个坏主意,因为3rd
可能有很多价格?我在这个领域没有太多的知识,并且一直在阅读有关5种规范化形式的内容,但我不确定我应该在哪里,或者可以适合推荐的{{1}}形式。
答案 0 :(得分:1)
当一个表中的子行的值必须作为另一个表中的子行的值出现时,我们声明一个外键。这就是你所拥有的,所以宣告它们。
外键本身与规范化无关。普通表单是表格或不是表格。规范化是指将表格替换为始终加入表格的多个表格。当两个表必须按上述方式达成一致时,外键约束成立。可能会发生新的外键在规范化的新表之间保持,但如果是这样,你只会声明它们。它们不会影响表格的正常形式或正常化。
(虽然ProductAttributeRelationship产品,价值,属性和关系是独一无二的,可能是因为产品和价格是独一无二的,产品只有一个价格而且一个属性只有一个价值。所以你应该说产品和价格是唯一的那么所有四个都必须是。同样,虽然Price regular,sale,on_sale和sale_percentage是唯一的,如果regular,sale和on_sale是唯一的,sales_percentage是它们的函数,那么你应该声明这三个唯一的。)
(PS:1。主要问题是完整性:如果子集没有约束,则允许无效更新.2。如果子集是唯一的,则超集是唯一的。因此,如果DBMS强制执行子集唯一性,那么 强制执行超集唯一性.3。此外, CK的每个超集都是唯一的,因此您选择的特定额外列没有什么特别之处.4。SQL DBMS UNIQUE / PK通常带有一个占用空间和时间来管理的索引。为了在非CK列上浪费的完整性和基本效率/优化。但是索引总是有其他特殊原因.5a。一个声明非CK超级密钥的原因是SQL强制您将其用作FK目标。(您可以将此冗余视为有用的检查或繁琐的钝角。)5b。另一个原因是有时这允许通过FK检查声明(vs过程/触发)完整性约束的表达。)