为标识列(identifier column)选择合适的数据类型非常重要。
当选择标识符的类型时,不仅仅需要考虑存储类型,还要考虑MySQL对这种类型怎么执行计算和比较。例如,MySQL在内部使用证书存储enum和set类型,然后在做比较时转换为字符串。
在可以满足值范围的需求,并且预留未来增长空间的前提下,应该选择最小的数据类型。比如可以用tinyint存储中国的省,不需要很大的数字,所以不需要int。tinyint比int少了三个字节,如果用这个值作为其他表的外键,3个字节可能导致很大的性能差异。
1.整数类型通常是标识列最好的选择
2.避免使用enum和set。enum和set适合存储固定信息,例如有序的状态,产品类型,人的性别等。
3.如果可能,尽量避免使用字符串作为标识列,消耗空间且效率低。
4.如果存储UUID值,则应该移除'-'符号,或者应该unhex()函数转换uuid值为16字节的数字,
并且存储在一个binary(16)列中。检索时可以通过hex()函数来格式化为16进制格式。
特殊数据类型
某些数据类型的数据并不与内置类型一致。比如IPv4地址,人们常用vhachar(15)来存储IP地址。然而,它们实际上是32位无符号整数,不是字符串。用小数点分成四段的表示方法只是为了容易阅读。所以应该用无符号整数存储IP地址。
MySQL提供inet_aton()和inet_ntoa()函数在这两种表示方法之间转换。
例:在mysql中新建一个表:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for ip_table
-- ----------------------------
DROP TABLE IF EXISTS `ip_table`;
CREATE TABLE `ip_table` (
`id` int(0) UNSIGNED NOT NULL AUTO_INCREMENT,
`ipv4` int(0) UNSIGNED NOT NULL COMMENT 'ipv4地址',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
执行insert操作时,直接把例如“111.231.221.33”的IP地址插入,会报错,应为:
INSERT INTO ip_table (ipv4) VALUES (INET_ATON('111.231.221.33'))
在数据库中显示为:1877466401
用以下语句能查询出常见的ip地址格式
SELECT INET_NTOA(ipv4) AS ip_address FROM ip_table
用int存储IP地址会占用更少的空间,但是由于可读性差,无法直接在数据库中修改,而且对比varchar存储,查询效率是否有提升存疑。
网友评论