数据库设计 - 平面或多面

时间:2013-12-10 19:21:30

标签: database django database-design

我想知道我应该如何为我的城镇,县,省份设计数据库。

我有两个关于如何工作的想法。

创意1 - 简单:

每种类型都应存储为单独的表格。

class Town(models.Model):
    name = models.CharField(max_length=128)
    slug = models.SlugField()
    voivodeship = models.ForeignKey("Voivodeship", null=True, blank=True)
    county = models.ForeignKey("County", null=True, blank=True)
    town_type = models.ForeignKey("TownType", null=True, blank=True)
    population = models.PositiveIntegerField(null=True, blank=True)
    latitude = models.FloatField(null=True, blank=True)
    longitude = models.FloatField(null=True, blank=True)


class County(models.Model):
    name = models.CharField(max_length=128)
    voivodship = models.ForeignKey("Voivodeship", null=True, blank=True)
    type = models.CharField(max_length=64)


class Voivodeship(models.Model):
    name = models.CharField(max_length=128, blank=False, null=True)
    slug = models.SlugField(editable=False)
    date_updated = models.DateField(null=True, blank=False)
    shortcut = models.CharField(max_length=16)

创意2 - 更复杂:

我们的想法是为所有地方创建1个表,并在它们之间创建内部关系。

class Location(MPTTModel):
     name = models.CharField(max_length=256, null=True, blank=False)
     slug = models.SlugField(editable=False)
     shortcut = models.CharField(max_length=16, null=True, blank=True)

     date_added = models.DateTimeField(auto_now_add=True)
     date_updated = models.DateTimeField(auto_now=True)
     source = models.PositiveIntegerField(choices=SOURCE_CHOICES)

     # Geonames metadata
     geoname_id = models.CharField(max_length=256, null=True, blank=False)
     alternatenames = models.TextField()
     feature_class = models.CharField(max_length=2, null=True, blank=True)

     # Teryt metadata

     # first_order_division = models.ForeignKey("self", null=True, blank=True, verbose_name="Województwo")
     # second_order_division = models.ForeignKey("self", null=True, blank=True, verbose_name="Powiat")
     # third_order_division = models.ForeignKey("self", null=True, blank=True, verbose_name="miasto")
     # fourth_order_division = models.ForeignKey("self", null=True, blank=True)

     type = models.PositiveIntegerField(choices=LOCATION_TYPE_CHOICES, null=True, blank=False)
     subtype = models.ForeignKey("self")

     # Location metadata
     lng = models.FloatField(null=True, blank=True)
     lat = models.FloatField(null=True, blank=True)
     population = models.PositiveIntegerField(null=True, blank=True)
     country_code = models.CharField(max_length=2, null=True, blank=True)

在可靠性,速度,添加和更新记录的选项方面,哪一项在长期运行中是最好的?

我应该注意什么?

2 个答案:

答案 0 :(得分:0)

这完全取决于你想要做什么,但我认为使用多个表会更好。将所有内容放在一个表中可以使您的业务逻辑变得更加复杂。以下是一些例子:

  • 如果Location的类型为foo,则__str__应返回一项内容,bar类型应返回其他内容。从本质上讲,你可以在if方法中得到一大堆Location语句,我认为这些语句不是很干净。
  • 为不同的位置类型制作模型表格变得令人头疼。
  • 代码可能变得难以维护,或者数据库迁移可能会在以后咬你。

同时在一个表中包含所有内容不会增加任何性能优势,因为它仍然有自己的外键,因此仍然必须执行表连接。

答案 1 :(得分:0)

我使用了上面描述的平面设计。它具有许多优于表分离的优点,例如在url模式中 - 它更容易维护它们,因为你可以在1个模式中适应所有位置,而不必进行额外的视图查询。

使用django-mptt构建结构非常容易,因此您可以使用平面数据库设计更快地对解决方案进行原型设计。以这种方式生成结构和面包屑非常容易。