我不是在为我正在工作的新项目设计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个字符长的文本使用相同的列类型有什么反对意见吗?
3条答案
按热度按时间a6b3iqyw1#
避免向用户展示垃圾的好方法:
在items表中输入实际描述字段。例如,美国(我们在度量衡方面落后)可能是:
然后构建一个包含三列的翻译表:
lang
,original
,已翻译。例如:
然后执行如下查询以获取翻译:
这样,您的瑞典客户将获得原始商品名称(直到您提供瑞典语翻译),而您的墨西哥客户将获得适当的翻译。诀窍在于
COALESCE ... LEFT JOIN
查询模式。您可能希望匹配名称id值的翻译,而不是名称本身。但是,像我建议的那样,在像wordpress这样的通用系统中,在名字的文本上进行匹配是值得的。
编辑关于使用文本匹配而不是ID的效率。
假设你的翻译表中有一千万个项目。这将是,平均每项200字节。对于索引,假设每项400字节。这个表是4G字节。在一台高质量的云计算机器上,每月大约要花费0.11到0.14美元。使用一个身份证就不到一半了。比如说1.5G。所以每月的差价大约是0.06美元。另外,云计算机器的存储空间最小。
查找:如果正确索引表,文本匹配不会比id匹配慢很多。而且,这种情况不会大量发生,而是在人们查找信息时发生。
qyswt5oh2#
你需要一个
Languages
table
,就像语言(id、名称)
另外,你还需要一个
ItemDescriptions
table
,就像itemdescriptions(id、itemid、languageid、content)
你会
insert
values
进入Languages
table
,就像记录到items表中,如
并记录到itemdescriptions表中,如
所以你会有一个单一的记录
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
oninsert
orupdate
.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个字符的字符串”这一功能。如果您确实需要这样做,那么应用程序可能需要做的比数据库模式所能做的更多。