首页 > 数据库 >mysql 避坑建议(整合网上资料)

mysql 避坑建议(整合网上资料)

时间:2023-08-24 13:22:24浏览次数:37  
标签:00 01 压缩 避坑 主键 整合 mysql 类型 数据库

字段类型的避坑建议

1、数字类型-整型

类型 占用空间 取值范围(有符号) 取值范围(无符号)
TINYINT 1 -128 ~ 127 0 ~ 255
SMALLINT 2 -32758 ~ 32767 0 ~ 65535
MEDIUMINT 3 -8388608 ~ 8388607 0 ~ 16777215
INT 4 -2147483648 ~ 2147483647 0 ~ 4294967295
BIGINT 8 -9223372036854775808 ~ 9223372036854775807 0 ~ 18446744073709551615

 在整型类型中分为无符号有符号,默认的取值范围是有符号的;设计表字段属性时,如非必要,不建议使用无符号的数据类型,因为当字段类型设置为无符号时,如果需要在数据库中进行加减操作时,一旦出现相减的数值为负数的时,就会报错,因为Mysql 中无符号类型的数值进行加减操作后,数值依然是无符号类型,所以当操作后的值为负数时,Mysql 就会报计算结果超出范围的错误;如果需要避免这个错误,就需要设置数据库参数 sql_mode 为 NO_UNSIGNED_SUBTRACTION,允许相减的结果为有符号的,这样最终的结果才是正确的; 

2、数值类型-浮点型

类型 占用空间
float 4
double 8
decimal 每9个数字占用4和字节

float 和double 类型是不建议使用的,因为这两者都会存在一个精度问题,如果是设计到金额的系统,那么一般会选中使用 DECIMAL;但是使用 DECIMAL就一定合适吗?这里有一个问题,DECIMAL是需要指定长度的,那么这个长度为多少合适呢,有没有肯能出现特殊情况呢?这里建议使用bigint 来存储金额数据,这样做的好处有几个:1.bigint的数值能存到千兆级别(1兆 = 1万亿),对于金额系统是完全够用的;2.bigint只占用8个字节,就可以满足日常需要,DECIMAL如果要保存大额数字,就会占用更多的字节;3.使用整型参与计算比DECIMAL效率高(DECIMAL 是通过二进制实现的一种编码方式,所以计算效率没有整形高)。

 3、日期类型

类型 占用字节 格式 范围 插入时默认值 更新时默认值
YEAR 1 YYYY 1901 ~ 2155 0000 NULL
DATE 3 YYYY-MM-DD 1000-01-01 ~ 9999-12-31 当前日期 NULL
TIME 3 HH:MM:SS -838:59:59 ~ 838:59:59 00:00:00 NULL
DATETIME 8 YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 当前日期时间 NULL
TIMESTAMEP 4 YYYY-MM-DD HH:MM:SS 1970-01-01 00:00:01 ~ 2038-01-19 03:14:07 当前日期时间 NULL

设计时间类型时,推荐使用DATETIME:1、5.6版本后DATETIME类型支持毫秒级;2、DATETIME不存在时区问题;3、DATETIME时间能到9999年,比TIMESTAMEP长;4、大规模并发访问时,性能比TIMESTAMEP强

表压缩

在 MySQL 中,一个页的大小默认为 16K,一个个页又组成了每张表的表空间。通常我们认为,如果一个页中存放的记录数越多,数据库的性能越高。这是因为数据库表空间中的页是存放在磁盘上,MySQL 数据库先要将磁盘中的页读取到内存缓冲池,然后以页为单位来读取和管理记录。一个页中存放的记录越多,内存中能存放的记录数也就越多,那么存取效率也就越高;

启用压缩技术,数据库可以根据记录、页、表空间进行压缩,不过在实际工程中,我们普遍使用页压缩技术,这是为什么呢?

  压缩每条记录: 因为每次读写都要压缩和解压,过于依赖 CPU 的计算能力,性能会明显下降;另外,因为单条记录大小不会特别大,一般小于 1K,压缩效率也并不会特别好。

  压缩表空间: 压缩效率非常不错,但要求表空间文件静态不增长,这对基于磁盘的关系型数据库来说,很难实现。

而基于页的压缩,既能提升压缩效率,又能在性能之间取得一种平衡。

COMPRESS 页压缩

  COMPRESS 页压缩是 MySQL 5.7 版本之前提供的页压缩功能;在创建表时指定ROW_FORMAT=COMPRESS,并设置通过选项 KEY_BLOCK_SIZE 设置压缩的比例即可;COMPRESS 页压缩就是将一个页压缩到指定大小,但是当16K的页无法压缩到指定大小时,会产生多个压缩后的页;

这里需要注意虽然 COMPRESS 压缩可以有效减小存储空间,但 COMPRESS 页压缩的实现对性能的开销是巨大的,性能会有明显退化。主要原因是一个压缩页在内存缓冲池中,存在压缩和解压两个页;

TPC 压缩

TPC(Transparent Page Compression)是 5.7 版本推出的一种新的页压缩功能,其利用文件系统的空洞(Punch Hole)特性进行压缩;在创建时设置 COMPERSSION=ZLIB即可,通过ALTER 进行设置时,需要执行OPTIMIZE TABLE命令才可生效;由于空洞是文件系统的一个特性,利用空洞压缩只能压缩到文件系统的最小单位 4K,且其页压缩是 4K 对齐的;空洞压缩的另一个好处是,它对数据库性能的侵入几乎是无影响的(小于 20%),甚至可能还能有性能的提升;

这里需要注意:文件系统的最小单位 4K,且其页压缩是 4K 对齐的。比如一个 16K 的页,压缩后为 7K,则实际占用空间 8K;压缩后为 3K,则实际占用空间是 4K;若压缩后是 13K,则占用空间依然为 16K。

数据库设计上的避坑建议

1、自增主键

在设置自增主键时如果使用int类型,那么会存在一个问题,一个int的最大值是2147483647,对于互联网项目来说,如果每日产生的数据条数按千万计算,几百天就能将表数据装满,当然这里不考虑分表的问题;自增主键在8.0版本之前是不持久化的,这样会存在回溯现象(删除数据后,AUTO_INCREMENT字段会在数据库重启之后回到未使用的数字,这里有个问题就是如果其他表存在这个自增键的引用,如果发生回溯,那么就会发生数据错乱的问题)

2、字符集

在设计数据库是,最好将mysql的默认字符集设置为UTF8MB4;utf8 是 MySQL 中最早支持的 Unicode 字符集,它使用 1 到 3 个字节来编码每个字符,当存储的数据是 Emoji 表情、部分罕用汉字、新增的 Unicode 字符等这些字符需要 4 个字节的数据时,会出现报错或者乱码;

3、核心表新增last_modify_time字段

 核心表新增一个last_modify_time字段,并且设置修改自动更新机制(CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)),用于保存用户的上一次修改时间,这样在电商的订单表中,可以方便对支付超时的订单做处理;在金融业务中,可以根据用户资金最后的修改时间做相应的资金核对等。

 4、业务自定义生产主键

使用自增字段做主键时,自增存在回溯问题(5.6以前版本);自增主键在当前实例中能保证唯一,却不能保证全局唯一,在分布式架构设计时存在问题,分表功能实现麻烦;

使用UUID做主键,虽然能保证全局唯一标识,但是UUID是根据时间位逆序存储,前 4 个字节会随着时间的变化而不断“随机”变化,并非单调递增。而非随机值在插入时会产生离散 IO,从而产生性能瓶颈;8.0版本可以通过UUID_TO_BIN函数解决排序问题;

INSERT INTO User VALUES UUID_TO_BIN(UUID(),TRUE)

虽然8.0解决了UUID排序问题,但是在面对分布式数据库架构时,仅仅使用UUID做主键依然不够;

使用业务自定义生成主键,可以通过规则保证全局唯一,并且可以再主键中加入额外的信息,来保证后续耳机索引的查询效率,推荐设计如下:

PK = 时间字段 + 随机码(可选) + 业务信息1 + 业务信息2....

 

标签:00,01,压缩,避坑,主键,整合,mysql,类型,数据库
From: https://www.cnblogs.com/caixiaozi/p/17639844.html

相关文章

  • mysql use index
    MySQLUSEINDEX简介索引为你提供了优化查询性能的好方法,它就像一本书的目录,让你能快速找到所需内容,mysql在选择最佳查询方式时,需要考虑很多因素,其中基数是重要的因素之一。基数意味着可以插入列中数值的唯一性。但是,由于多次插入、更新和删除操作,基数可能会发生变化。您可以定......
  • mysql基操小记
    MYSQLA.概述1.关系型数据库​ MySQL是一个关系型数据库管理系统,由瑞典[MySQLAB](https://baike.baidu.com/item/MySQLAB/2620844?fromModule=lemma_inlink)公司开发,属于Oracle旗下产品。MySQL是最流行的关系型数据库管理系统之一,在WEB应用方面,MySQL是最好的RDBMS(Re......
  • mysql优化军规20条
    一.优化军规20条:1.where查询条件,类型要一致,避免类型转换,非常慢2.查询条件包含函数,负向查找,导致大表,多表联合查询奇慢3.in子查询超时,将子查询in改造为临时表或表值参数后join4.尽量不在数据库做运算,复杂运算转移到程序端CPU计算,尽量简单使用mysql5.控制单表数据量,int型不超......
  • 【问题解决】容器部署MySQL的数据在docker commit导出的镜像中丢失
    问题起因最近公司有个甲方项目参加竞赛,要求在(基于kubeflow/arena)平台上部置应用,可以将MySQL打包在应用一起,也可以分开部署,没有提供volume相关的支持。大意是可以把初始好的数据直接拿到平台上。经过本人在Linux虚机中启动MySQL容器导入数据再dockercommit出镜像部署到平台......
  • mysql 主从复制原理
    mysqlmaster主库启动binlog日志,每次执行的数据库操纵语句写入binlog,从库定期启动一个i/o线程去binlog日志,将binlog日志写入从库的relaylog(中继日志),再启动sql线程去将relaylog日志将数据重放,其他都是顺序读写,这个步骤是可能造成延迟的主要原因解决办法:1、从库配置比主库好,2......
  • Mysql 定时备份数据库脚本
    Mysql定时备份数据库;并且删除X天前的备份数据;1.  创建数据目录mkdirdatacd/data2.  编写脚本文件    vim  backup.sh#!/bin/bash#日期dd=`date+%Y-%m-%d-%H-%M-%S`#保存备份个数,备份2天数据backup_clean_day=2#用户名username=root#密......
  • MySQL相关
    mysql-悲观锁使用select...forupdate,就实现了。zhelyao注意,mysql的select...forupdate语句,会把所有扫描的行都锁上,所以在mysql中使用悲观锁,我们必须要确定走了索引,不然可能会全表扫描,锁住整个表。mysql-乐观锁在我们要修改前,先查询一个这个值和一个自己维护的版本号,记录下来......
  • Python-PyMySQL的一些使用注意事项
    一、关于groupby的使用在部分mysql版本(5.7.xx及以上)中,若select的列中,包含了未被groupby的字段,会报以下错误:[Err]1055-Expression#1ofORDERBYclauseisnotinGROUPBYclauseandcontainsnonaggregatedcolumn'xxxx'whichisnotfunctionallydependentoncolu......
  • springBoot 整合 poi 导出带有复杂表格(合并表格)的word文件
    1.Maven依赖见上一篇文章直接贴源码如下:packagecom.mingx.pms.web.system.file;importcn.hutool.core.date.DateUtil;importcom.mingx.pms.constant.SystemInfo;importcom.mingx.pms.entities.workplan.plan.vo.WorkPlanDetailExportVO;importcom.mingx.pms.entities......
  • 数仓数据导出mysql保留换行符踩坑
    记录一个导数的小坑,数仓里面的数据需要导出到mysql,然后报表展示,并且需要把一段文字里面的换行功能体现出来;数仓里面的原始数据采用的是$符号进行分割每一行数据,直接把$符号替换为\n然后导出到mysql,发现没有生效,反而在页面上把\n展示出来了。那么注意了,经过反复尝试写成\\\n,然......