【问题标题】:Many foreign keys in one lookup table. Bad idea?一个查找表中有许多外键。馊主意?
【发布时间】:2015-04-01 00:33:20
【问题描述】:

我正在使用 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')

ProductAttributeRelationship 中使用3 个ForeignKeys 和在Price 中使用ForeignKey 是不是一个坏主意,因为ProductAttributeRelationship 可能有很多价格?我在这方面的知识不多,并且一直在阅读有关 5 种规范化表格的信息,但不确定我应该或可以在哪里适合推荐的 3rd 表格。

【问题讨论】:

    标签: django database database-design orm relational-database


    【解决方案1】:

    当一个表中子行的值必须作为另一个表中子行的值出现时,我们声明外键。这就是你所拥有的,所以声明它们。

    外键与规范化本身无关。正常形式是表存在或不存在的东西。规范化是将表替换为始终连接到该表的多个表。当两个表必须按照上述一致时,外键约束成立。可能会发生新的外键在规范化的新表之间保留,但如果是这样,您只需声明它们。它们不会影响表格的正常形式或规范化。

    (虽然ProductAttributeRelationship产品、值、属性和关系是唯一的,但大概是因为产品和价格是唯一的,产品只有一个价格,一个属性只有一个值。所以你应该说产品和价格是唯一的; 那么所有四个都必须是。同样,虽然 Price regular、sale、on_sale 和 sale_percentage 是唯一的,但如果 regular、sale 和 on_sale 是唯一的并且 sale_percentage 是它们的函数,那么您应该声明这三个唯一。)

    (PS:1.主要问题是完整性:如果对子集没有约束,则允许无效更新。2.如果子集是唯一的,则超集是唯一的。因此,如果 DBMS 强制执行子集唯一性,那么它 强制执行超集唯一性。3. 此外,CK 的 每个 超集都是唯一的,因此您选择的特定额外列没有什么特别之处。4. SQL DBMS UNIQUE/PK 通常带有一个需要空间和时间来管理的索引。为了完整性和基本效率/优化,浪费在非 CK 列上。但是索引总是有其他特殊情况的原因。5a.声明非 CK 超键的一个原因是 SQL 迫使您这样做以将其用作 FK 目标。(您可以将这种冗余视为有用的检查或乏味的迟钝。) 5b. 另一个原因是有时这允许声明性(与过程/触发)表达式通过 FK 检查的完整性约束。)

    【讨论】:

    • 这是有道理的。如果有的话,我可以期望从消除不必要的独特约束中获得什么样的效率提升?
    猜你喜欢
    • 2018-08-04
    • 1970-01-01
    • 2011-11-21
    • 1970-01-01
    • 2012-05-24
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    • 2021-08-15
    相关资源
    最近更新 更多