Django ManyToManyField是否使用冗余索引创建表?

时间:2015-06-28 03:45:25

标签: python mysql django

如果我的模型 Foo 有一个简单的M2M字段来建模

class Foo(Model):
    bar = ManyToManyField(Bar)

Django似乎创建了一个表 foo_bar ,其中包含以下索引:

index 1: primary, unique (id)
index 2: unique (foo_id, bar_id)
index 3: non_unique (foo_id)
index 4: non_unique (bar_id)

我从SQL的基本知识中回想一下,如果查询需要在foo_id上查找条件,索引2就足够了(因为最左边的列可以用于查找)。索引3似乎是多余的。

我是否正确地假设索引3确实占用了索引空间而没有提供任何好处?我最好使用直通表并在(foo_id,bar_id)上手动创建一个唯一索引,如果需要,还可以选择在(bar_id)上另一个索引?

1 个答案:

答案 0 :(得分:1)

理解如何在数据库中表示多对多关联的关键是要意识到联结表的每一行(在本例中为foo_bar)将左表(foo)中的一行连接到一行从右边的桌子(酒吧)。每个pk的“foo”都可以多次复制到“foo_bar”;每个pk的“bar”也可以多次复制到“foo_bar”。但是“foo_bar”中的同一对fk只能出现一次。

因此,如果你在“foo_bar”中只有一个索引(pk为“foo”或“bar”),那么它只能出现一次......并且它与许多关系不是很多。

例如,我们有两个模型(电子商务):Product,Order。

每个产品可以有多个订单,一个订单可以包含许多产品。

class Product(models.Model):
    ...

class Order(models.Model):
    products = ManyToManyField(Product, through='OrderedProduct')


class OrderedProduct(models.Model):
    # each pair can be only one time, so in one order you can calculate price for each product (considering ordered amount of it).
    # and at the same time you can get somewhere in your template|view all orders which contain same product 

    order = models.ForeignKey(Order)
    product = models.ForeignKey(Product)

    amount = models.PositiveSmallIntegerField()  # amount of ordered products
    price = models.IntegerField()  # just int in this simple example

    def save(self, *args, **kwargs):
        self.price = self.product__price * self.amount

        super(OrderedProduct, self).save(*args, **kwargs)