为什么有人会在一对一关系 (OneToOneField) 上设置 primary_key=True?
Why would someone set primary_key=True on an One to one reationship (OneToOneField)?
我正在 django-orm 上观看视频,讲师说:
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
字段只是一个 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,
)
那么,为什么有人会在 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
本质上是 ForeignKey
和 unique=True
[Django-doc]。所以这已经由 OneToOneField
强制执行,不需要 使其成为主键。
上面的建模无法做到的事情是防止 Place
同时是 Restaurant
和 Library
。
我正在 django-orm 上观看视频,讲师说:
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
字段只是一个 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,
)
那么,为什么有人会在 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
本质上是 ForeignKey
和 unique=True
[Django-doc]。所以这已经由 OneToOneField
强制执行,不需要 使其成为主键。
上面的建模无法做到的事情是防止 Place
同时是 Restaurant
和 Library
。