具有类似可翻译字段的多语言数据库设计

qaxu7uf2  于 2021-06-21  发布在  Mysql
关注(0)|答案(3)|浏览(377)

我不是在为我正在工作的新项目设计db模式的过程中。
因此,挑战如下:
有一张table Items 每个 Item 具有可翻译的 description_60 , description_180 文本(后缀数字表示存储的描述类型,例如60表示60个字符长)以及与其中每个字段相关联的一些字段,例如 apiSourceName 等。
我看到两种选择:

1

descriptions_translations

  Id
description_60
description_180
description_300
apiSourceName_60
apiSourceName_180
....
...

这看起来不太好,因为我们可能会有很多空字段和

2

descriptions_60_translations
  Id
description_60
apiSourceName
languageId
...
...

3其他?

我完全愿意接受其他建议!
另外,另一个挑战是,我想存储在主 Item table description_60 文本。在不复制数据的情况下这是可能的吗?
根据答案更新更倾向于此:

descriptions_translations
=========================
  id
itemId
description_type =>60, 120, 180 etc
`description` => 'This video is ...'
apiSourceName => youtube, dailymotion etc
languageId => en, es etc
...
...

对60个字符和1000个字符长的文本使用相同的列类型有什么反对意见吗?

a6b3iqyw

a6b3iqyw1#

避免向用户展示垃圾的好方法:
在items表中输入实际描述字段。例如,美国(我们在度量衡方面落后)可能是:

Bread, brown, 1 pound loaf

然后构建一个包含三列的翻译表: lang , original ,已翻译。
例如:

lang   original                     translated
 es    Bread, brown, 1 pound loaf   Hogaza de pan integral, 450g
 fr    Bread, brown, 1 pound loaf   Miche de pain brun, 450g
 de    Bread, brown, 1 pound loaf   Laib Schwarzbrot, 450g

然后执行如下查询以获取翻译:

SELECT COALESCE(t.translated, i.name) as name
  FROM Items
  LEFT JOIN Translation t ON t.lang = 'se' AND i.name = t.translated

这样,您的瑞典客户将获得原始商品名称(直到您提供瑞典语翻译),而您的墨西哥客户将获得适当的翻译。诀窍在于 COALESCE ... LEFT JOIN 查询模式。
您可能希望匹配名称id值的翻译,而不是名称本身。但是,像我建议的那样,在像wordpress这样的通用系统中,在名字的文本上进行匹配是值得的。
编辑关于使用文本匹配而不是ID的效率。
假设你的翻译表中有一千万个项目。这将是,平均每项200字节。对于索引,假设每项400字节。这个表是4G字节。在一台高质量的云计算机器上,每月大约要花费0.11到0.14美元。使用一个身份证就不到一半了。比如说1.5G。所以每月的差价大约是0.06美元。另外,云计算机器的存储空间最小。
查找:如果正确索引表,文本匹配不会比id匹配慢很多。而且,这种情况不会大量发生,而是在人们查找信息时发生。

qyswt5oh

qyswt5oh2#

你需要一个
Languages table ,就像
语言(id、名称)
另外,你还需要一个
ItemDescriptions table ,就像
itemdescriptions(id、itemid、languageid、content)
你会
insert values 进入
Languages table ,就像

60, 'English' 
180, 'Hungarian'

记录到items表中,如

1, 'Toothpaste'

并记录到itemdescriptions表中,如

1, 1, 60, 'Best Toothpaste'
2, 1, 180, 'Legjobb Fogkrém'

所以你会有一个单一的记录
Items table 对于每个项目,在
Languages table 对于每种语言和尽可能多的记录
ItemDescriptions table 尽可能多 Languages 它们被翻译成。
编辑
事实证明,有多种语言和多种描述每种语言。所以,我们需要改变 ItemDescriptions
itemdescriptions(id、itemid、languageid、content60、content180、content300)
因此,每条记录都将保存所有相应的描述。
编辑2
因为您描述了每个描述都需要额外的数据,所以很明显给定的描述将不再是属性,而是记录。这意味着我们有两种可能的解决方案(对于这两种解决方案,由于缺少信息,我避免定义额外的数据,但是您可以定义它们各自的列):

第一个解决方案

itemdescriptions(id、itemid、languageid、content、maxlength)
哪里 maxLength 分别可以是60、180、300。您的附加值将是
ItemDescriptions table . 如果你使用 varchar(300) 为了 content ,则不必使用不必要的字节来存储值 content .

第二种解决方案

itemdescriptions80(id、itemid、languageid、content)
itemdescriptions180(id、itemid、languageid、content)
itemdescriptions300(id、itemid、languageid、content)
这些单独的表将存储单独的值,在这种情况下,您将需要在每个表中包含附加数据的单独列。

比较

如果你使用 varchar 作为一种类型 content ,那么第一种方法似乎优于第二种方法,但是,在处理的简单性方面 insert 或者 update 一个值,您需要确保 maxLength 有效(分别等于60、180或300),并且 content 不长于 maxLength . 您可以从应用程序或通过记录级别执行此操作 trigger on insert or update .

rxztt3cl

rxztt3cl3#

决定列的最大大小,然后从
对于“短”固定长度字符串(zipcode、country\u code、uuid等),使用 CHAR(..) CHARACTER SET ascii .
对于总是“short”的“short”字符串,使用 VARCHAR(...) 有一个永远不会超过的极限。你选择的限制并不重要——60比80无关紧要。
对于中等大小的字符串,请考虑 VARCHAR(255) . (如果使用的是5.5或5.6以及utf8mb4,请使用191。)
对于较长的字符串,请使用 TEXT (64k限制)或 MEDIUMTEXT (16m限制)。
这些选择涉及到实现细节,对于大多数用户来说,这些细节没有区别。
几乎没有人需要“切掉我60个字符的字符串”这一功能。如果您确实需要这样做,那么应用程序可能需要做的比数据库模式所能做的更多。

相关问题