哪种型号设计更好?

时间:2011-06-11 03:34:42

标签: django database-design django-models

我们现在正在使用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模型中。如果有人用西班牙语写一篇文章,我们首先创建一个Post实例,然后创建一个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,...)

但我们大多数人认为这两种方法没有区别。他的模型设计会产生一个非常糟糕的表格。

那么你觉得哪一个更好?

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

通常,语言存储方式如此(伪代码):

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

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

我的首选替代方法是以上都不是 - 并为每种语言使用不同的架构(或DB或表前缀):

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

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

我更喜欢它的原因是网站经常出现未翻译的网页,或者网页存在于一个网站而不是另一个网站。不过,您的内容通常不会在国家与下一个国家/地区相同 - 您不会以同样的方式与您的受众进行沟通。