【问题标题】:Which model design is better?哪个模型设计更好?
【发布时间】:2011-06-11 03:34:42
【问题描述】:

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

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


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

因此,我们对所有英语内容使用 Post,对西班牙语内容使用 PostEpanish。 如果有人用英语写了一篇文章,我们只是把它放在 Post 模型中,我们把翻译后的帖子放在 PostEspanish 模型中。如果有人用西班牙语写了一篇文章,我们首先创建一个 Post 实例,然后创建一个 PostEspanish 实例并将内容放入 PostEspanish 中,如果有人翻译了这篇西班牙语文章,我们将翻译后的文章放入其引用的 Post 中。

在不同的模型上存储不同的语言内容是因为搜索者想要这样。他说这对搜索有好处。

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

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,...)

但我们大多数人认为这两种方法没有区别。而且他的模型设计会多生成一张表,这真的很糟糕。

那你觉得哪个更好?

【问题讨论】:

    标签: django database-design django-models


    【解决方案1】:

    他提出的模型似乎更明智;对待语言对我来说,同样的比对待它们更有意义,而且更恰当地规范化了。

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

    【讨论】:

    • 在不同的模型上存储不同的语言内容是因为搜索者想要这样。他说这对搜索有好处。
    • 如果他说有一张英语表和一张西班牙语表有助于提高表现,那他就错了。对内容使用单个表格,并用一列指示语言。
    【解决方案2】:

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

    posts (
      id       serial pkey,
      pubdate  datetime
    )
    
    posts_lang (
      id       int fkey posts (id),
      lang     char(2),
      title    varchar,
      content  text,
      pkey (id, lang)
    )
    

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

    posts (
      id       serial pkey,
      parent   int fkey posts (id),
      lang     char(2),
      pubdate  datetime
      title    varchar,
      content  text
    )
    

    它的好处是它允许处理特定于语言环境的属性(例如,英语标签/元与西班牙语标签/元)。但它很快变成了树木处理的噩梦。所以不推荐。

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

    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)
    )
    

    我可以看到将默认语言直接放入表格的理由。但根据我的经验,它引入了代码重复——即你不断地以两种方式做事——从而导致错误/怪癖。所以也不能真正推荐。

    我首选的替代方案不是上述任何一种——并且为每种语言使用不同的架构(或数据库或表前缀):

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

    我更喜欢它的原因是,一个网站经常有未翻译的页面等,或者页面存在于一个站点上但不存在于另一个站点上。而且通常情况下,您的内容不应该在一个国家/地区与另一个国家/地区完全相同——您与受众的交流方式不同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-21
      • 2012-11-20
      • 2013-10-07
      • 2018-06-11
      • 2013-02-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多