我对此有一般性质疑。我们有很多次想要在之前插入大量数据时更改字段或排序规则的数据类型。考虑以下情况:
将varchar
归类从utf8_general_ci
转换为latin1_swedish_ci
:因为我知道第一个具有多字节字符,而第二个字节具有多字节字符。此转换是否正确操作存储的记录?这种转换是否会导致现有数据量减少(可能为50%)?
将int(10)
转换为smallint(5)
:数据量是否正确减少到50%?
例如:int(10)
至unsigned int(10)
- text
至varchar(1000)
- varchar(20)
至char(10)
,... < / p>
很明显,可以采取这些措施来提高效率,减少数据量......
考虑我有一张包含1,000,000条记录的表格。我想知道执行此类操作是否会对存储的数据产生不良影响,或者是否会导致将来插入和选择涉及此表的性能低下。
更新:
当我谈到将utf8编码字符集更改为拉丁语时,我的字段的值当然是英语(如果有日语则很明显,它们会丢失)。有了这个假设,我就会问到结果表的大小和性能。
答案 0 :(得分:4)
将
varchar
归类从utf8_general_ci
转换为latin1_swedish_ci
:我知道第一个具有多字节字符,第二个字节为字节。此转换是否正确操作存储的记录?这种转换是否会导致现有数据量减少(可能为50%)?
排序仅仅是用于字符串比较的排序 - 它(几乎)与用于数据存储的字符编码无关。我说几乎因为排序规则只能用于某些字符集,所以更改排序规则可能会强制更改字符编码。
如果修改字符编码,MySQL将正确地将值重新编码为新字符集,无论是从单字节还是多字节,反之亦然。请注意,任何对列过大的值都将被截断。
如果新的字符类型是可变长度的,并且在新编码中使用比以前更少的字节编码值,那么表格的大小当然会减少。
无论显示宽度如何,将
int(10)
转换为smallint(5)
:数据量是否正确降低到50%?
INT
和SMALLINT
分别占用4个和2个字节:所以是的,表格的大小会相应减少。
或者例如:
int(10)
到unsigned int(10)
-text
到varchar(1000)
-varchar(20)
到char(10)
,...
INT
占用4个字节,无论是否签名,都不会有任何变化;
TEXT
和VARCHAR(1000)
都占用 L +2个字节(其中 L 是值的长度,以字节为单位),所以有将不会有任何变化;
VARCHAR(20)
占用 L +1个字节(其中 L 是值的字节长度),而CHAR(10)
占用10×< em> w 字节(其中 w 是字符集中最大长度字符所需的字节数),因此可能会有变化,但它取决于实际存储的值和使用的字符编码。
请注意,根据存储引擎的不同,表大小的减少可能不会立即释放到文件系统。
答案 1 :(得分:1)
A1。整理不会改变您的数据。它会更改查询中的排序顺序,并可能更改索引(?)。
A2。列中数据的长度将减少,但是每个表行总是有一些开销,并且您无法更改它。此外,如果您的数据不是唯一的,您将看不到索引大小的大幅减少,因为您的索引如下所示:33-&gt; {row1,row2,row3 ...},67-&gt; {row9,row0, row7}并且每个行指针都比int大得多。
换句话说,如果你有一个包含100个int行的表,没有很多索引,并且将所有这些列都改为tinyint,你会看到一个显着的改进。如果它只是一列,请不要打扰。
http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html http://dev.mysql.com/doc/refman/5.0/en/innodb-physical-record.html
A3。请阅读文字vs varchar。较早存储数据与表行分开存储,后者存储在行中。每个都有自己的含义。
P.S。行和索引开销很大程度上取决于您使用的数据库引擎。通常你应该使用innodb。但是对于只读任务,例如数据挖掘,myisam效率更高。
答案 2 :(得分:0)
varchar
归类从utf8_general_ci
转换为latin1_swedish_ci
:它可以减少表(文件)大小,但是您可以丢失拉丁符号,只会正确存储英文单词。int(10)
转换为smallint(5)
- 这会减少数据量。将int(10)
转换为unsigned int(10)
- 它不会减少。在这些情况下,你应该关心这些值,你可以得到一个错误 - 超出范围值。varchar(20)
转换为char(10)
:CHAR用于始终具有相同长度的字符串(例如-10),如果字符串长度不同,则使用VARCHAR数据类型。