Django中的一对一、多对一和多对多之间的区别

21

这是我第一次学习计算机语言。我选择了 Python 和 Django。现在,我已经掌握了许多 Python 和 Django 的基本概念。我可以使用视图和其他工具创建新页面。但是,我仍然对关系(即一对一、多对一和多对多)感到困惑。请有好心人能够解释一下吗?我如何使用它们?我真的需要知道。

谢谢。

2个回答

107

特别是在使用Django时,它可以让复杂的数据库设计变得简单。我认为了解SQL级别上的工作原理对于更好地理解所做的任何事情都非常重要。我认为通过示例来理解是最好的方式。

首先,您应该了解每个SQL表都有一个字段(通常自动递增),称为“主键”。这个字段是每行具有唯一值的列。

例如,在Django中创建表示作者的模型,其中包括三个字段 - 名字,姓氏和可选的电子邮件字段。Django还会自动添加名为pk的主键字段(您也可以决定定义自己的主键字段,但通常不这样做)。因此,使用manage.py syncdb命令将创建一个看起来像这样的表:

+----+------------+-----------+-----------------------+
| pk | first_name | last_name |         email         |
+----+------------+-----------+-----------------------+

当您添加新值(比如'Stephen King')时,它会将其添加到作者表中,如下所示:

+----+------------+-----------+-----------------------+
| pk | first_name | last_name |         email         |
+----+------------+-----------+-----------------------+
|  1 | Stephen    | King      | stephenking@gmail.com |
+----+------------+-----------+-----------------------+

我们再加一个:

+----+------------+-----------+-----------------------+
| pk | first_name | last_name |         email         |
+----+------------+-----------+-----------------------+
|  1 | Stephen    | King      | stephenking@gmail.com |
|  2 | J.D.       | Salinger  |                       |
+----+------------+-----------+-----------------------+

很简单。现在我们添加一个名为“Book”的新模型:

+----+--------------+--------+--------+
| pk |    title     | genre  | author |
+----+--------------+--------+--------+
|  1 | Pet Semetary | Horror |      1 |
+----+--------------+--------+--------+

现在你看到我做什么了吗?在作者字段中,我给“书”赋了Stephen King主键的值——记住,它是唯一的,因此它只会获取Stephen King。这是一个外键——它指向相关表上的pk,并表示一个多对一关系,即各种书可以指向同一个作者的pk,但反过来不行。这样,每个作者都可以有许多相关的书,但每本书只有一个作者。

现在假设我们想添加另一本Stephen King的书。这本书叫做The Talisman:

+----+--------------+---------+--------+
| pk |    title     |  genre  | author |
+----+--------------+---------+--------+
|  1 | Pet Semetary | Horror  |      1 |
|  2 | The Talisman | Fantasy |      1 |
+----+--------------+---------+--------+

但是,糟糕的是,等等——这最后一个实际上是与另一位名为Peter Straub的作者共同创作的。那么我们该怎么办?首先需要将Straub添加到我们的作者表中:

+----+------------+-----------+-----------------------+
| pk | first_name | last_name |         email         |
+----+------------+-----------+-----------------------+
|  1 | Stephen    | King      | stephenking@gmail.com |
|  2 | J.D.       | Salinger  |                       |
|  3 | Peter      | Straub    |                       |
+----+------------+-----------+-----------------------+

现在我们如何告诉表格“护身符”与两行不同的内容有关呢?简单 - 使用第三个表格将它们连接起来。

因此,第一个表格将是作者(如上所示)。第二个表格将是书籍。第三个表格将被称为authors_books并且看起来像这样:

+------------+--------------+
| pk_of_book | pk_of_author |
+------------+--------------+
|          1 |            1 |
|          2 |            1 |
|          2 |            3 |
+------------+--------------+

看到了吗?它告诉你如何在表格之间链接不同的pks。这是一种多对多关系,因为不同的书籍可以与不同的作者相关联,反之亦然。我描述的三个表结构是其基本设计。

一对一关系类似于ForeignKey,但具有unique=True,因此您只能将一个对象链接到另一个对象,仅此而已。当您想要扩展某个模型而不更改原始模型时(例如,您想向内置用户模型添加自己的自定义字段)时,通常会使用它。

Django非常出色,几乎永远不需要使用SQL,但了解背后发生的一些事情仍然有所帮助。网络上有很多关于这些关系的解释,我只给了您一个小的概述,并强烈建议您在网上搜索一下,以便自己扩展您的理解。


4
当我开始学习Django时,一个好朋友与我坐下来画图并解释了所有内容。这对我后来非常有帮助,以至于当我看到你的问题时,我也必须这样做。很高兴我能帮到你! =] - yuvi

2

谢谢提供链接!但是我仍然对“一对一”和“多对多”有些疑问。假设我想在另一个类中扩展一些更多的用户信息。我可以使用ForeignKey代替One-to-One字段吗?您能否请友好地向我解释一下“多对多”关系(我并没有完全理解所有这些配料和成员资格的事情)。 - Aamu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接