赞
踩
推荐链接:
总结——》【Java】
总结——》【Mysql】
总结——》【Redis】
总结——》【Kafka】
总结——》【Spring】
总结——》【SpringBoot】
总结——》【MyBatis、MyBatis-Plus】
总结——》【Linux】
总结——》【MongoDB】
总结——》【Elasticsearch】
数据类型原则:为每一列选择合适的字段类型,使用可以正确存储数据的最小数据类型。
不同类型的最大存储范围是不一样的。
类型 | 单位(字节) | 有符号取值范围 | 无符号取值范围 |
---|---|---|---|
tinyint | 1 | -128 ~ 127 | 0 ~ 255 |
smallint | 2 | -32768 ~ 32767 | 0 ~ 65535 |
mediumint | 3 | -8388608 ~ 8388607 | 0 ~ 16777215 |
int | 4 | -2147483648 ~ 2147483647 | 0 ~ 4294967295 |
integer | 4 | -2147483648 ~ 2147483647 | 0 ~ 4294967295 |
bigint | 8 | -9223372036854775808 ~ 9223372036854775807 | 0 ~ 18446744073709551615 |
表示不允许负值。
Q:有符号 VS 无符号?
A:
- 相同的存储空间
- 相同的性能
- 不同的存储范围
有符号:-128 ~ 127
无符号:0 ~ 255
如果数据宽度小于指定长度,则在数字前面填充零’0’。
当使用zerofill 时,默认会自动加unsigned(无符号)属性。
数值类型设置的长度并不影响该数值字段的取值范围,只是规定了用来显示字符的个数。
长度只有在设置 ZEROFILL 即 “填充零” 后才有所意义。
比如 int(3) 存储 1 ,填充零时会填充为 001。
CREATE TABLE `test` (
`num` int(3) DEFAULT NULL,
`num_zerofill` int(3) unsigned zerofill DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='测试';
INSERT INTO `test` (`num`, `num_zerofill`) VALUES (1, 1);
INSERT INTO `test` (`num`, `num_zerofill`) VALUES (2, 2);
INSERT INTO `test` (`num`, `num_zerofill`) VALUES (3, 3);
INSERT INTO `test` (`num`, `num_zerofill`) VALUES (4, 4);
INSERT INTO `test` (`num`, `num_zerofill`) VALUES (5, 5);
实数是带有小数部分的数字。
浮点类型在存储同样范围的值时,通常比DECIMAL使用更少的空间。
存储 | 类型 | 单位(字节) | 描述 |
---|---|---|---|
精确类型 | decimal | ||
精确的小数 | |||
浮点类型 | float | 4 | 不精确的小数 |
浮点类型 | double | 8 | 不精确的小数,比 FLOAT有更高的精度和更大的范围 |
Q:mysql里记录货币用什么字段类型好?
A:
1、场景 :精度不敏感 && 需要快速运算
选择:FLOAT和 DOUBLE
原因:CPU直接支持原生浮点计算,所以浮点运算明显更快
2、场景:精度计算 && 需要快速运算
选择:DECIMAL
原因:支持对小数进行精确
缺点:以字符串形式存放的,CPU不支持对DECIMAL的直接计算,性能会有影响。
3、场景:精度计算 && 需要快速运算 && 数据量大
选择:BIGINT
实现:将需要存储的货币单位根据小数的位数乘以相应的倍数
优点:避免浮点存储计算不精确且运算效率高
参考链接:Mysql——》varchar
速度:char>varchar>text
类型 | 长度 | 最大 | 特性 | 应用场景 |
---|---|---|---|---|
char | 固定 | 255个字符 | 1.会自动删除末尾的空格 2.检索效率、写效率会比varchar高 3.以空间换时间 | 1.身份证号 2.手机号 3.MD5摘要 4.短字符串 5.经常更新的字符串 |
varchar | 可变 | 65535个字节 | 1.使用最小的符合需求的长度。 2.varchar(n) n<=255使用额外一个字节保存长度,n>255使用额外两个字节保存长度。 3.varchar(5)与varchar(255)保存同样的内容,硬盘存储空间相同,但内存空间占用不同,是指定的大小 。 4.varchar在mysql5.6之前变更长度,或者从255一下变更到255以上时时,都会导致锁表。 5.每次更新后都会重算并使用额外存储空间保存长度 6.根据实际内容长度保存数据 | 1.文章内容 2.特殊字符 3.不经常更新的字符串 |
text | 不设置 | 不设置 | 字符串 | 超长文本 |
blob | 不设置 | 不设置 | 二进制 | 1.超长文本 2.音频文件 |
Q:使用BLOB和TEXT要慎重?
A:
- 一般把 BLOB或TEXT 列分离到单独的表中
- 在不必要的时候避免检索大型的 BLOB或TEXT值
- 使用合成的(Synthetic)索引来提高大文本字段(BLOB或TEXT)的查询性能
合成索引就是根据大文本字段的内容建立一个散列值,并把这个值存储在单独的数据列中,接下来就可以通过检索散列值找到数据行了。但是,要注意这种技术只能用于精确匹配的查询(散列值对于类似“<”或“>=”等范围搜索操作符是没有用处的)。可以使用MD5函数生成散列值,也可以使用SHA1(或CRC32),或者使用自己的应用程序逻辑来计算散列值。
类型 | 占用字节 | 范围 | 时区 | 精确 |
---|---|---|---|---|
date | 3 | 1000-01-01到9999-12-31 | ||
datetime | 8 | 1001~9999 | 与时区无关,数据库底层时区配置 | 毫秒 |
timestamp | 4 | 1970-01-01到2038-01-19 整形存储 | 与时区有关,依赖数据库设置的时区,可自动更新 | 秒 |
Q:如何存储秒级别的时间截?
A:
- 使用bigint类型
- 使用double存储秒之后的小数部分
mysql存储枚举类型会非常紧凑,会根据列表值的数据压缩到一个或两个字节中,mysql在内部会将每个值在列表中的位置保存为整数,并且在表的.frm文件中保存“数字-字符串”映射关系的查找表
create table enum_test(e enum('fish','apple','dog') not null);
insert into enum_test(e) values('fish'),('dog'),('apple');
select e+0 from enum_test;
Q:注意
A:
- 枚举列实际存储为整数,而不是字符串
所以不要使用数字作为ENUM枚举常量,这种双重性很容易导致混乱,例如ENUM( ‘1’,‘2’,‘3’)。- 枚举列是按照内部存储的整数而不是定义的字符串进行排序的
所以尽量按照需要的顺序来定义枚举列。
存储IP地址(本质是32位无符号整数不是字符串)方式:
-- IP 地址转换为 32 位整型数值
select inet_aton('1.1.1.1')
-- 32 位整型数值类型表示的 IP 地址转换为点分十进制格式的字符串
select inet_ntoa(16843009);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。