Django 哪种型号的设计更好?

Django 哪种型号的设计更好?,django,database-design,django-models,Django,Database Design,Django Models,我们现在正在使用Django开发一个多语言网站。我们网站上的内容有不同的语言版本。例如,对于一篇文章,我们有英文版和西班牙文版。 目前,我们正在使用此模型: class Post(models.Model): user title detail count_follower ... orginal_language date class PostEspanish(models.Model): post = models.Fore

我们现在正在使用Django开发一个多语言网站。我们网站上的内容有不同的语言版本。例如,对于一篇文章,我们有英文版和西班牙文版。 目前,我们正在使用此模型:

class Post(models.Model):
    user
    title
    detail
    count_follower
    ...
    orginal_language
    date


class PostEspanish(models.Model):
    post = models.ForeignKey(Post)
    title
    detail
因此,我们对所有英语内容使用Post,对西班牙语内容使用PostEspanish。 如果有人用英语写了一篇文章,我们就把它放在post模型中,然后把翻译后的文章放在PostEspanish模型中。如果有人用西班牙语写了一篇文章,我们首先创建一个帖子实例,然后创建一个PostEspanish实例,并将内容放在PostEspanish中,如果有人翻译这篇西班牙语文章,我们将翻译后的文章放在它的引用文章中


在不同的模型上存储不同的语言内容是因为搜索人员希望这样做。他说这对搜索有好处

为了更清楚,例如,一些用户写了一篇文章,我们将执行以下操作:

if language == 'English':
    post = Post.objects.create(..., orginal_language='english')
else:
    post = Post.objects.create(..., original_language='espanish')
    PostEspanish.objects.create(post=post, ...)
并翻译为:

post = Post.objects.get(id=id)
if post.orginal_language == 'english':
    post = post.postespanish
    #update post
    post.save()
else:
    #update post
    post.save()
今天有人说这个模型设计很差。他说当前的模型没有很好的面向对象。他们的做法如下:

class Post(models.Model):
    user
    count_follower
    ...
    orginal_language
    date

class PostContentEnglish(models.Model):
    post = models.ForeignKey(Post)
    title
    detail

class PostContentEspanish(models.Model):
    post = models.ForeignKey(Post)
    title
    detail
因此,代码如下所示:

if language == 'English':
    post = Post.objects.create(..., orginal_language='english')
    PostContentEnglish.objects.create(post=post,...)
else:
    post = Post.objects.create(..., orginal_language='espanish')
    PostContentEspanish.objects.create(post=post,...)
但我们大多数人认为这两种方法没有区别。他的模型设计会再生成一张表,这真的很糟糕


那么你认为哪一个更好呢?

他提出的模式似乎更合理;对我来说,用同样的方式对待语言比用不同的方式对待语言更有意义,而且更适合规范化


但是,与其为每种语言创建一个表,不如为内容创建一个表,并添加一列以指示该语言

通常,语言是这样存储的(伪代码):

我见过几次的另一种方法是:

posts (
  id       serial pkey,
  parent   int fkey posts (id),
  lang     char(2),
  pubdate  datetime
  title    varchar,
  content  text
)
它的好处是允许处理特定于语言环境的属性(例如,英语标记/meta与西班牙语标记/meta)。但这很快就变成了树木管理的噩梦。所以不推荐

当然,还有一个是您正在使用的,默认语言直接在表中:

posts (
  id       serial pkey,
  pubdate  datetime
  title    varchar,
  content  text,
)

posts_lang (
  id       int fkey posts (id),
  lang     char(2),
  title    varchar,
  content  text,
  pkey (id, lang)
)
我可以看到希望将默认语言直接放入表中的理性。但以我的经验来看,它引入了代码复制——也就是说,你经常以两种方式做事情——从而产生bug/怪癖。所以也不能真的推荐

我的首选方案不是上述任何一种,而是对每种语言使用不同的模式(或DB或表前缀):

en.posts (
  id       serial pkey,
  pubdate  datetime
  title    varchar,
  content  text
)

es.posts (
  id       serial pkey,
  pubdate  datetime
  title    varchar,
  content  text
)

我之所以喜欢它,是因为一个站点经常会有未翻译的页面,或者一个站点上存在但另一个站点上没有的页面。而且通常情况下,你的内容在不同的国家之间不应该完全相同——你与观众的沟通方式不同。

在不同的模式上存储不同语言的内容是因为搜索人员希望这样做。他说这对搜索有好处。如果他说有一张英语桌子和一张西班牙语桌子有助于提高性能,那他就错了。为内容使用一个表,并用一列指示语言。
en.posts (
  id       serial pkey,
  pubdate  datetime
  title    varchar,
  content  text
)

es.posts (
  id       serial pkey,
  pubdate  datetime
  title    varchar,
  content  text
)