可以说我有下表:
CREATE TABLE `my_table` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`relationship_status` varchar(48) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
假设这张表有很多记录:100M
我有 2 个可能的值relationship_status
:'following' 或 'not_following'
因为我想减小 DB 的大小(硬盘上的大小),如果我将其更改relationship_status
为 Boolean 而不是 varchar(48) 会有什么影响(如果可以将 0 定义为不跟随,1 定义为跟随)?
您将使用哪种列类型?微小的?
我认为
TINYINT
会是一个不错的选择。我建议根本不要索引relationship_status
。您不应该单独索引relationship_status
,因为索引基数是 2。查询优化器永远不会使用索引。您可以按如下方式进行索引:这样,在最坏的情况下,查询优化器将对如下查询执行索引扫描:
EXPLAIN 计划应该改进,因为排序和临时表的使用将被最小化或消除。
现在关于磁盘空间,让我们计算节省的空间。首先,每个字符串的长度是多少?
每个 VARCHAR 都有一个用于跟踪字符串长度的附加字节。这些值实际上是 10 和 14。由于您将字段缩小到 1 个字节,因此会被忽略。如果你折叠
relationship_status
到 TINYINT,节省如下由于行数约为 100M,因此磁盘空间的节省必须在 900M 和 1.3G 之间。
更新 2012-08-23 13:00 EDT
回答您的评论
首先,a
DATETIME
是8个字节,INT(11)
是4个字节。由于 8 - 4 = 4,您的节省将是每行 4 个字节。对于表,SELECT COUNT(1)*4 FROM my_table;
现在,varchar(255) 字段。正如我之前提到的,varchar 有一个额外的字节用于长度管理。总结所有 varchar 字段的所有长度并添加行数(每行上的额外 from 字段)并减去 4 个字节乘以行数。
将 DATETIME 和 VARCHAR 计算放在一起,你会得到这个
就我个人而言,我会使用 BIT(1) 数据类型并将列名更改为“以下”,这样才合乎逻辑。
您当前设计使用的空间是这样的(使用文本 NOT_FOLLOWING 的长度,即 13 个字节):
使用位字段将使用以下空间:
这将为您节省空间:
我希望这可以帮助你。