mysql中整数数组的最小存储空间?

时间:2016-04-21 23:38:12

标签: mysql arrays storage diskspace

我有一个用户条目表,对于每个条目,我都有一个(2字节)整数数组来存储(15-25,零星甚至更多)。数组元素将同时被写入和读取,永远不需要更新或单独访问它们。他们的订单很重要将其视为数组对象是有道理的。

我有数百万这些用户条目,并希望以尽可能少的磁盘空间存储它。然而,我正在努力解决MySQL缺少Array数据类型的问题。

我一直在考虑以下选项。

  • 以MySQL的方式做。使用my_datauser_iddata_id列创建一个表data_int。为了提高效率,需要user_id上的索引,每个整数总共超过10个字节。
  • 以文本格式存储数组。这需要每个整数大约6.5个字节。
  • 制作35-40列(“足够”)并使-32768为“空”(因为此值不会出现在我的数据中)。这需要每个整数3.5-4个字节,但有点难看(因为我必须对数组中的元素数量施加严格的限制)。

在MySQL中有更好的方法吗?我知道MySQL有一个高效的varchar类型,所以理想情况下我将我的2字节整数存储为varchar中的2字节字符(或与blob类似的方法),但是我不知道该怎么做。这可能吗?该怎么做?

2 个答案:

答案 0 :(得分:0)

您可以将它们存储为单独的SMALLINT NULL列。

在MyISAM中,这对每个值使用2个字节的数据+ 1个空指示符。

在InnoDB中,空指示符被编码到列的字段起始偏移中,因此它们不占用任何额外空间,并且空值实际上不存储在行数据中。如果行足够小,所有偏移量都是1个字节,则每个现有值使用3个字节(1个字节偏移量,2个字节数据),每个不存在的值使用1个字节。

这些中的任何一个都比使用INT具有特殊值来表示它不存在更好,因为对于每个值,这将是4个字节的数据。

请参阅NULL in MySQL (Performance & Storage)

答案 1 :(得分:0)

评论中给出了最佳答案,因此我将在此处重新发布一些使用准备好的代码,以供进一步参考。

MySQL有一个varbinary类型可以很好地解决这个问题:你可以简单地使用PHP的pack / unpack函数将它们转换成二进制形式,以及使用varbinary将二进制表单存储在数据库中。转换的示例代码如下。

function pack24bit($n) { //input: 24-bit integer, output: binary string of length 3 bytes
    $b3 = $n%256;
    $b2 = $n/256;
    $b1 = $b2/256;
    $b2 = $b2%256;
    return pack('CCC',$b1,$b2,$b3);
}

function unpack24bit($packed) { //input: binary string of 3 bytes long, output: 24-bit int
    $arr = unpack('C3b',$packed);
    return 256*(256*$arr['b1']+$arr['b2'])+$arr['b3'];
}