为什么有人会在一对一关系 (OneToOneField) 上设置 primary_key=True?

Why would someone set primary_key=True on an One to one reationship (OneToOneField)?

我正在 上观看视频,讲师说:

We should set primary_key=True to prevent a Model from having duplicate rows in a OneToOne relationship (Ex: Prevent a user from having multiple profiles).

我知道这个说法是错误的! AFAIK,OneToOne 字段只是一个 ForeignKeyunique 参数设置为 True。但我很好奇并查阅了 Django 文档,果然他们在示例中使用 primary=True

class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)

class Restaurant(models.Model):
    place = models.OneToOneField(
        Place,
        on_delete=models.CASCADE,
        primary_key=True,
    )

那么,为什么有人会在 OneToOne 关系上设置 primary_key=True? 我的猜测是,将该字段作为主键是合理的,并且背后没有任何技术背景。

这是在关系数据库中实现面向对象继承的模式,例如article of Oracle discusses

确实,这意味着可以定义一个 Place,并为此 Place 创建一个 Restaurant 模型。它有一个 OneToOneField(…) 到“父”模型。 OneToOneField 防止可以为相同的 Place.

定义两个(或更多)Restaurant

通常它被定义为一个主键,从那时起它共享相同的“主代码space”,并且它删除了一个用于映射的列,从而使数据库更大.

Django 将以同样的方式实现这一点。如果我们将其定义为:

class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)

class Restaurant(<strong>Place</strong>):
    pass

则执行为:

mysql> describe place;
+---------+-------------+------+-----+---------+----------------+
| Field   | Type        | Null | Key | Default | Extra          |
+---------+-------------+------+-----+---------+----------------+
| id      | int         | NO   | PRI | NULL    | auto_increment |
| name    | varchar(50) | NO   |     | NULL    |                |
| address | varchar(80) | NO   |     | NULL    |                |
+---------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

mysql> describe restaurant;
+--------------+------+------+-----+---------+-------+
| Field        | Type | Null | Key | Default | Extra |
+--------------+------+------+-----+---------+-------+
| place_ptr_id | int  | NO   | PRI | NULL    |       |
+--------------+------+------+-----+---------+-------+

因此它将添加一个名为 place_ptr_id 的主键,该主键引用 place table。这源于 Django 添加到名为 place_ptr.

Restaurant 模型的 OneToOneField

We should set primary_key=True to prevent a Model from having duplicate rows in a OneToOne relationship (Ex: Prevent a user from having multiple profiles)

这没有意义,因为 OneToOneField 本质上是 ForeignKeyunique=True [Django-doc]。所以这已经由 OneToOneField 强制执行,不需要 使其成为主键。

上面的建模无法做到的事情是防止 Place 同时是 RestaurantLibrary