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

Rav*_*ina 6 django database-design django-orm

上的视频,教练说:

我们应该设置primary_key=True为防止模型在一对一关系中具有重复行(例如:防止用户拥有多个配置文件)。

我知道这个说法是错误的!AFAIK,一个OneToOne字段只是一个参数ForeignKey设置unique为 的字段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,
    )
Run Code Online (Sandbox Code Playgroud)

那么,为什么有人会建立primary_key=True关系呢OneToOne?我的猜测是,将该字段作为主键是合理的,并且其背后没有技术背景。

Wil*_*sem 8

这是一种在关系数据库中实现面向对象继承的模式,例如Oracle的这篇文章所讨论的

\n

事实上,这意味着人们可以定义Place,并为此Place创建一个Restaurant模型。它有一个OneToOneField(\xe2\x80\xa6)“父”模型。这可以防止为同OneToOneField一个 定义两个(或多个)。RestaurantPlace

\n

通常它被定义为主键,因为它共享相同的“主代码空间”,并且它删除了原本用于进行映射的列,从而使数据库变得更大。

\n

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

\n
class Place(models.Model):\n    name = models.CharField(max_length=50)\n    address = models.CharField(max_length=80)\n\nclass Restaurant(Place):\n    pass
Run Code Online (Sandbox Code Playgroud)\n

那么它将被实现为:

\n
mysql> describe place;\n+---------+-------------+------+-----+---------+----------------+\n| Field   | Type        | Null | Key | Default | Extra          |\n+---------+-------------+------+-----+---------+----------------+\n| id      | int         | NO   | PRI | NULL    | auto_increment |\n| name    | varchar(50) | NO   |     | NULL    |                |\n| address | varchar(80) | NO   |     | NULL    |                |\n+---------+-------------+------+-----+---------+----------------+\n3 rows in set (0.00 sec)\n\nmysql> describe restaurant;\n+--------------+------+------+-----+---------+-------+\n| Field        | Type | Null | Key | Default | Extra |\n+--------------+------+------+-----+---------+-------+\n| place_ptr_id | int  | NO   | PRI | NULL    |       |\n+--------------+------+------+-----+---------+-------+\n
Run Code Online (Sandbox Code Playgroud)\n

因此,它将添加一个名为place_ptr_id引用该place表的主键。这源自OneToOneFieldDjango 添加到Restaurant名为 的模型中的一个place_ptr

\n
\n

我们应该设置primary_key=True为防止模型在一对一关系中具有重复行(例如:防止用户拥有多个配置文件)

\n
\n

这是没有意义的,因为 aOneToOneField本质上是 aForeignKeyunique=True\xc2\xa0 [Django-doc]。所以这已经由 强制执行OneToOneField,没有必要将其设为主键。

\n

上述建模无法做到的事情是防止 an同时Place是 aRestaurant和。Library

\n