mysql - 具有相似可翻译字段的多语言数据库设计
问题描述
我没有为我正在从事的新项目设计数据库模式。
因此,挑战如下:
- 这里有张桌子
Items
- 每个
Item
都有一个可翻译description_60
的description_180
文本(后缀数字代表存储的描述类型,例如 60 表示 60 个字符长)以及与每个字段相关联的一些字段,例如apiSourceName
etc。
我看到有两个选项:
1
descriptions_translations
Id
description_60
description_180
description_300
apiSourceName_60
apiSourceName_180
....
...
这看起来不太好,因为我们最终可能会得到很多 NULL 字段和
2
descriptions_60_translations
Id
description_60
apiSourceName
languageId
...
...
3 其他?
我完全愿意接受其他建议!
另外,另一个挑战是我想在主Item
表中存储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 个字符长的文本使用相同的列类型有什么缺点吗?
解决方案
这样做并避免向用户显示垃圾的好方法:
在您的 Items 表中放置一个实际的描述字段。例如,美国(我们在度量衡方面落后)可能是:
Bread, brown, 1 pound loaf
然后构建一个包含三列的翻译表:lang
, original
, translate`。
例如:
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)中的本地化是值得的。
编辑关于使用文本匹配而不是 ids 的效率。
假设您的翻译表中有一千万个项目。这将是平均每个项目 200 字节。使用索引,假设每个项目 400 字节。那是 4 GB 的表。在高质量的云机器中,这将花费大约 0.11 到 0.14 美元/月。使用 ID 会比它的一半少一点。说 1.5 GB。因此,差异约为每月 0.06 美元。此外,云机器具有最小的存储大小。
查找:如果您正确索引表,文本匹配不会比 id 匹配慢很多。而且,它不会大量发生,而是在人们查找信息时发生。
推荐阅读
- apache-spark - Spark 数据集写入之间的区别
- angular - 如何使用 Angular 6 在函数中传递动态模板引用变量
- json - 使用 axios 将 json 数据发布到我的数据库(使用我的后端 api)
- excel - 在“文本”格式的单元格中查看 Excel(科学记数法)中的大数字时出现问题
- r - 在 Rmarkdown 文件上使用闪亮的小部件:闪亮输出中的错误:不允许从闪亮输出对象中读取对象
- fortran - 寻找构造 simto VB 的 WITH 语句
- java - 在 focframework 中,隐藏打印布局选择中的“文字打印”和“电子邮件发送”按钮
- c# - 在 RDLC 报告中获取多个数据集时出错
- php - MySql 和 Android 应用程序出错
- c# - 如何在表单中加载网站并更改加载的页面,仅通过一个按钮加载另一个页面