ForeignKey vs CharField

时间:2016-02-28 04:37:56

标签: python django postgresql django-models

我对django中的数据模型有一个想法,我想知道是否有人可以指出这两种设置的优缺点。

设置1 :这将是一个显而易见的问题。为每个对象的每个字段使用CharFields

class Person(models.Model):
    name = models.CharField(max_length=255)
    surname = models.CharField(max_length=255)
    city = models.CharField(max_length=255)

设置2 :这是我正在考虑的问题。将ForeignKey用于包含当前Object应具有的值的对象。

class Person(models.Model):
    name = models.ForeignKey('Name')
    surname = models.ForeignKey('Surname')
    city = models.ForeignKey('City')

class Chars(models.Model):
    value = models.CharField(max_length=255)

    def __str__(self):
        return self.value

    class Meta:
        abstract = True

class Name(Chars):pass
class Surname(Chars):pass
class City(Chars):pass

所以在设置1 中,我会创建一个对象:

Person.objects.create(name='Name', surname='Surname', city='City')

每个对象都有自己的数据。在设置2 中,我必须这样做:

_name = Name.objects.get_or_create(value='Name')[0]
_surname = Surname.objects.get_or_create(value='Surname')[0]
_city = City.objects.get_or_create(value='City')[0]
Person.objects.create(name=_name, surname=_surname, city=_city)

问题:这样做的主要目的是重用多个对象的现有值,但是当你考虑到你需要在数据库上多次点击来创建一个对象时,这是值得做的吗?

2 个答案:

答案 0 :(得分:0)

为您的应用选择正确的设计模式是一个非常广泛的领域,受到许多因素的影响,甚至可能超出Stack Overflow问题的范围。所以从某种意义上说,你的问题可能有点主观和过于宽泛。

尽管如此,我会说为名字分配一个单独的模型(类),为姓氏分配另一个模型(类)是一种矫枉过正。您可能最终会过度使用您的应用程序。

上述建议背后的主要原因是您可能不希望将名称视为单独的实体,并可能附加其他属性。除非你真的需要这样的功能,否则名称通常是一些普通的字符串,有些用户恰好相同。

答案 1 :(得分:0)

将名称和姓氏保持为单独的对象/模型/ db表没有任何好处。在您的设置中,如果您没有将名称和姓氏设置为唯一,那么将它们放在单独的模型中没有任何意义。更糟糕的是,它会导致额外的数据库工作并降低性能。现在,如果您将它们设置为唯一,那么您必须解决这种情况,例如一些用户更改了他的名字,默认情况下会为具有该名称的所有用户更改。

另一方面,城市 - 没有那么多城市,最好将它作为单独的对象保存,并通过用户的外键来引用它。这将节省磁盘空间,允许轻松获取来自同一城市的所有用户。更好的是,您可以预先填充城市数据库,并为进入该城市的用户提供自动填充功能。虽然对于性能,您可能仍希望将city作为字符串保留在用户模型上。

另外,要提及“性别”字段,由于此数据的选择可能不多,因此在代码中使用枚举并在DB中存储值是值得的,即使用choices代替{{ 1}}到一个单独的数据库表。