我没有为我正在处理的新项目设计数据库架构。
因此,挑战如下:
Items
Item
都有可翻译的 description_60
,description_180
文字,(后缀编号代表存储的描述类型,例如60表示60 char long)以及与apiSourceName
等我看到有两个选项:
descriptions_translations
Id
description_60
description_180
description_300
apiSourceName_60
apiSourceName_180
....
...
看起来不太好,因为我们可能会得到很多NULL字段 和
descriptions_60_translations
Id
description_60
apiSourceName
languageId
...
...
我完全接受其他建议!
另外,另一个挑战是我想在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个字符长的文本使用相同列类型的任何缺点?
答案 0 :(得分:2)
这是一种很好的方法,可以避免向用户显示垃圾:
在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的效率。
假设您的翻译表中有1000万件商品。平均而言,每个项目200个字节。对于索引,我们说每个项目有400个字节。这个表的4千兆字节。在高质量的云计算机上,这将花费每月0.11到0.14美元。使用ID将略低于一半。说1.5千兆字节。所以差价大约是每月0.06美元。此外,云计算机的存储容量最小。
查找:如果正确索引表,文本匹配不会比id匹配慢得多。并且,当人们查找信息时,它不是大量发生的。
答案 1 :(得分:1)
您需要Languages
table
,例如
语言(身份证,姓名)
此外,您需要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
个。{/ p>
修改
事实证明,每种语言都有多种语言和多种描述。因此,我们需要将ItemDescriptions
的定义更改为
ItemDescriptions(id,itemId,languageID,content60,content180, content300)
所以每条记录都会包含所有相应的描述。
EDIT2
由于您描述了每个描述都需要额外的数据,因此很明显,给定的描述将不再是属性,而是记录。这意味着我们有两种可能的解决方案(对于这两种解决方案,我都避免因缺少信息而定义其他数据,但您可以定义各自的列):
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
执行此操作。
答案 2 :(得分:0)
决定列的最大尺寸,然后选择
对于“短”固定长度字符串(zipcode,country_code,UUID等),请使用CHAR(..) CHARACTER SET ascii
。
对于总是为“短”的“短”字符串,请使用VARCHAR(...)
,其限制永远不会超过。你选择的限制无关紧要 - 60对80是无关紧要的。
对于中等大小的字符串,请考虑VARCHAR(255)
。 (如果您使用的是5.5或5.6和utf8mb4,请使用191。)
对于较长的字符串,请使用TEXT
(64K限制)或MEDIUMTEXT
(16M限制)。
这些选择涉及实施细节,对大多数用户来说没有区别。
几乎没有人需要“以60个字符砍掉我的字符串”的功能。如果确实需要,那么应用程序可能需要做的比数据库模式更多。