Django 数据库设计 - 空外键

发布于 2024-10-14 22:29:20 字数 1163 浏览 2 评论 0原文

我有一个带有 Person 模型的 Django 模型:

class Person(models.Model):
  # Personal details
  first_name = models.CharField(max_length=50)
  middle_name = models.CharField(max_length=50, blank=True, null=True)
  last_name = models.CharField(max_length=50)
  gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
  date_of_birth = models.DateField()

  # Address
  street_address = models.CharField(max_length=50)
  suburb = models.CharField(max_length=30)
  postcode = models.CharField(max_length=4)
  state = models.CharField(max_length=3, choices=STATE_CHOICES)

  #Contact Details
  email = models.EmailField()

  # Family
  spouse = models.ForeignKey('self', null=True, blank=True)
  children = models.ManyToManyField('self', null=True, blank=True)

  home_church = models.ForeignKey('Church', null=True, blank=True)

“middle_name”字段可以为空,我认为没有任何方法可以避免这种情况,是吗?

但是,我还有一个用于配偶的可为空的外键,一个用于其孩子的递归多对多字段,以及一个用于教堂的可为空的外键(如果相关)。

我的问题 - 首先,目前对于可为空外键的共识是什么?我应该允许它在这里,还是应该创建某种“无人”或“未指定”模型来代表没有配偶/家庭教会?

或者是否有其他方法可以在 Django 中重新设计此设计以适应这种情况?

如果我确实继续使用 null FK,那么 Django 中是否有我需要注意的警告? (左连接?)

干杯, 胜利者

I have a Django model with a Person model:

class Person(models.Model):
  # Personal details
  first_name = models.CharField(max_length=50)
  middle_name = models.CharField(max_length=50, blank=True, null=True)
  last_name = models.CharField(max_length=50)
  gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
  date_of_birth = models.DateField()

  # Address
  street_address = models.CharField(max_length=50)
  suburb = models.CharField(max_length=30)
  postcode = models.CharField(max_length=4)
  state = models.CharField(max_length=3, choices=STATE_CHOICES)

  #Contact Details
  email = models.EmailField()

  # Family
  spouse = models.ForeignKey('self', null=True, blank=True)
  children = models.ManyToManyField('self', null=True, blank=True)

  home_church = models.ForeignKey('Church', null=True, blank=True)

The "middle_name" field is nullable, I don't think there's any way to avoid that, is there?

However, I also have a nullable ForeignKey for Spouse, a recursive ManyToManyField for their children, and a nullable ForeignKey for church (if relevant).

My question - firstly, what is the current consensus on nullable foreign keys? Should I be allowing it here, or should I be creating some kind of "nobody", or "unassigned" model to represent not having a spouse/home church?

Or is there some other way that I can rework this design in Django to accommodate for this?

And if I do go ahead with null FK's, are there any caveats in Django I need to be aware of? (left join?)

Cheers,
Victor

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

药祭#氼 2024-10-21 22:29:20

空是完全没问题的。在Python代码中,None将代表Null

你应该知道的一件重要的事情是,如果你删除教堂,django 会执行级联,并且你从该教堂中的人也将被删除。因此,在删除教堂之前,您需要为该教堂中的每个人在教堂字段上设置 Null。

Django 1.3 引入了 on_delete 参数,这使得这个问题变得很多简单点。

Null is perfectly fine. In python code None will represent Null.

One important thing you should know is that if you delete church, django performs cascading and your Persons from that church will be deleted too. So before deleting church you need to set Null on church field for every person in that church.

Django 1.3 introduces on_delete argument which makes this a lot simper.

清风夜微凉 2024-10-21 22:29:20

大多数 DBMS 实现的可为空外键没有多大逻辑意义。不同的 DBMS 处理它们的方式也存在一些不一致。因此,可为空的外键很可能会导致错误的结果。只需将有问题的属性移动到新表中,并且仅在有要填充的值时才填充该表,就可以轻松避免它们。

Nullable foreign keys as implemented by most DBMSs don't make much logical sense. There are also some inconsistencies between the ways that different DBMSs handle them. As a result, nullable foreign keys are very likely to lead to incorrect results. They are easily avoided simply by moving the attribute(s) in question to a new table and only populating that table when you have a value to populate it with.

清旖 2024-10-21 22:29:20

当外键标记为 null = True 时,Django 将使用 LEFT OUTER JOIN 处理 JOIN,至少在 Oracle 数据库中如此,所以没有问题。

When the foreign key is marked null = True, Django will process the JOINs with LEFT OUTER JOIN, at least with an Oracle database AFAIK, so no problem there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文