MySQL数据类型-选择标志符(identifier)
为标识列fdenier clum选择合适的数据类型⾮常重要。般来说更有可能⽤标识列与其他值进⾏⽐较(例如, 在关联操作中),成者通过标识列寻其他列,标识列也可能在另外的表中作为外键使⽤,所以为标识列选择数据类型时,应该选择限关联表中的对应列样的类型 (正如我们在本在早些时候所论述的样, 在相关的表中使⽤相同的数据类型是个好主意,因为这些列很可能在关联中使⽤)。
当选择标识列的类型时,不仅仅需要考虑存储类型,还需要考虑MySOL对这种类型怎么执⾏计算和⽐较。例如,MySQL在内部使⽤整数存储ENUM和SET类型,然后在做⽐较操作时转换为字符串。
⼀旦选定了⼀ 种类型, 要确保在所有关联表中都使⽤同样的类型。类型之间需要精确匹配,包括像UNSIGNED这样的属性"。混⽤不同数据类型可能导致性能问题,即使没有性能影响,在⽐较操作时隐式类型转换也可能导致很难发现的错误。这种错误可能会很久以后才突然出现,那时候可能都已经忘记是在⽐较不同的数据类型。
在可以满⾜值的范围的需求,并且预留未来增长空间的前提下,应该选择最⼩的数据类型。例如有⼀个state id列存储美国各州的名字,就不需要⼏千或⼏百万个值,所以不需要使⽤INT。TINYINT ⾜够存储,⽽且⽐INT少了3个字节。如果⽤这个值作为其他表的外键,3个字节可能导致很⼤的性能差异。下⾯是⼀些⼩技巧。
整数类型
整数通常是标识列最好的选择,因为它们很快并且可以使⽤AUTO INCREMENT。
ENUM和SET类型
对于标识列来说,EMUM 和SET类型通常是⼀个糟糕的选择, 尽管对某些只包含固定状态或者类型的静态“定义表"来说可能是没有问题的。ENUM和SET列适合存储固定信息,例如有序的状态、产品类型、⼈的性别。
举个例⼦,如果使⽤枚举字段来定义产品类型,也许会设计-张以这个枚举字段为主键的查表(可以在查表中增加⼀些列来保 存描述性质的⽂本,这样就能够⽣成⼀个术语表,或者为⽹站的下拉菜单提供有意义的标签)。这时,使⽤枚举类型作为标识列是可⾏的,但是⼤部分情况下都要避免这么做。
字符串类型
如果可能,应该避免使⽤字符串类型作为标识列,因为它们很消耗空间,并且通常⽐数字类型慢,尤其是在MyIsAM表⾥使⽤字容市作为标识列时要特别⼩⼼。MyISAM默认对字符事使⽤压缩索引,这合导致在询慢得名。在我们的测试中,我们注意到最多有6倍的性能下降。
mysql下载32位对于完全“随机”的字符串也需要注意,例如MD5. SHA(1)或者 UUID产⽣的字符串,这些函数⽣成的新值会任意分布在很⼤的空间内,这会导致INSERT以及⼀些SELECT语句变得很慢。
因为插⼈值会随机地写到素引的不同位置,所以使得INSERT请句更慢。这么导致页分裂、磁盘随机访问,以及对于聚族存储引擎产⽣聚族索引碎⽚。
SELECT语句会变得更慢,因为逻辑上相邻的⾏会分布在磁盘和内存的不同地⽅。
随机值导致缓存对所有类型的查询语句效果都很差,因为会使得缓存赖以⼯作的访问局部性原理失效。如果整个数据集都⼀样
的“热”, 那么缓存任何部分特定数据到内存都没有好处:如果⼯作集⽐内存⼤,缓存将会有很多刷新和不命中。
如果存储UUID值,则应该移除“.”符号↓或者更好的做法是,⽤UNHEX()函数转换UUID值为16字节的数字,井且存储在⼀个
BINARY(16)列中。检索时可以通过HeX()函数来格式化为⼗六进制格式。
UUID()⽣成的值与加密敢列函数例如SHA1()⽣成的值有不同的特征: UUID值虽然分布也不均匀,但还是有⼀-定顺序的。 尽管如此,但还是不如递增的整数好⽤。
特殊类型的数据:
某些类型的数据并不直接与内置类型⼀致,低于 秒级精度的时间戳的例⼦
IPV4地址,通常⽤varchar(15)列来存储IP地址,但实际上它是32位⽆符号整数,不是字符串;⽤⼩数点将地址分成4段的表⽰⽅法只是为了让我们容易阅读,所以我们应该⽤⽆符号整数存储IP地址,MySQL提供了INET_ATON()和INET_NTOA函数在这两种⽅法之间切换
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论