MySQL decimal unsigned更新负数转化为0

 更新时间:2020年12月07日 10:11:29   作者:林锅  
这篇文章主要介绍了MySQL decimal unsigned更新负数转化为0,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

今天在验证接口的并发问题时,把之前通过 redis 解决的并发压力转移到 mysql 上(redis 在 set 保存数据和数据过期需要去向数据库获取时存在时延,会存在空挡造成大并发多插入数据的风险;由于有负载均衡,PHP 的信号量也无法用上,只好利用 mysql 的update 来解决并发,设置索引后速度也不慢,只是会承受压力)。发现在 update 一个字段(属性为 decimal unsigned),填入负值不会报错,会自动转化为 0。搜索了很久,是 my.cnf 中 STRICT_TRANS_TABLES 搞的鬼。

这时需要先了解 sql_mode

MySQL服务器可以以不同的SQL模式来操作,并且可以为不同客户端应用不同模式。这样每个应用程序可以根据自己的需求来定制服务器的操作模式。模式定义MySQL应支持哪些SQL语法,以及应执行哪种数据验证检查。这样可以更容易地在不同的环境中使用MySQL,并结合其它数据库服务器使用MySQL。你可以用--sql-mode="modes"选项启动 mysqld 来设置默认SQL模式。如果你想要重设,该值还可以为空(--sql-mode ="")。你还可以在启动后用SET [SESSION|GLOBAL] sql_mode='modes' 语句设置sql_mode变量来更改SQL模式。设置 GLOBAL变量时需要拥有SUPER权限,并且会影响从那时起连接的所有客户端的操作。设置SESSION变量只影响当前的客户端。任何客户端可以随时更改自己的会话 sql_mode值。

sql_mode 是用逗号(',')间隔开的一系列不同的模式。你可以用SELECT @@sql_mode语句查询当前的模式。默认值是空(没有设置任何模式)。

主要重要sql_mode值为:

  ANSI

  更改语法和行为,使其更符合标准SQL。

  STRICT_TRANS_TABLES

  如果不能将给定的值插入到事务表中,则放弃该语句。对于非事务表,如果值出现在单行语句或多行语句的第1行,则放弃该语句。

  TRADITIONAL

  Make MySQL的行为象“传统”SQL数据库系统。该模式的简单描述是当在列中插入不正确的值时“给出错误而不是警告”。注释:一旦发现错误立即放弃INSERT/UPDATE。如果你使用非事务存储引擎,这种方式不是你想要的,因为出现错误前进行的数据更改不会“滚动”,结果是更新“只进行了一部分”。

  本手册指“严格模式”,表示至少STRICT _TRANS_TABLES或STRICT _ALL_TABLES被启用的模式。

  以下是 STRICT_TRANS_TABLES 和 STRICT_ALL_TABLES 两种模式的区别:

  对于事务表,当启用STRICT_ALL_TABLES或STRICT_TRANS_TABLES模式时,如果语句中有非法或丢失值,则会出现错误。语句被放弃并滚动。

  对于非事务表,如果插入或更新的第1行出现坏值,两种模式的行为相同。语句被放弃,表保持不变。如果语句插入或修改多行,并且坏值出现在第2或后面的行,结果取决于启用了哪个严格选项:

  对于STRICT_ALL_TABLES,MySQL返回错误并忽视剩余的行。但是,在这种情况下,前面的行已经被插入或更新。这说明你可以部分更新,这可能不是你想要的。要避免这点,最好使用单行语句,因为这样可以不更改表即可以放弃。对于STRICT_TRANS_TABLES,MySQL将非法值转换为最接近该列的合法值并插入调整后的值。如果值丢失,MySQL在列中插入隐式 默认值。在任何情况下,MySQL都会生成警告而不是给出错误并继续执行语句。

  其他模式还有:

  ALLOW_INVALID_DATES:不完全对日期合法性作检查,只检查月份是否在1~12,日期是否在1~31之间;仅对DATE和DATETIME有效,而对TIMESTAMP无效,因为TIMESTAMP总要求一个合法的输入。

  ANSI_QUOTES:启用后,不能用双引号来引用字符串,因为"(双引号)将被解释为标识符

  ERROR_FOR_DIVISION_BY_ZERO:启用后,在insert或update过程中,若数据被零除(或MOD(x,0),则产生错误,若未启用,则产生警告,数据被零除时系统返回NULL。

  HIGH_NOT_PRECEDENCE:启用后,可获得以前旧版本的优先级:

  NO_AUTO_CREATE_USER:禁止GRANT创建密码为空的用户。

  NO_AUTO_VALUE_ON_ZERO:在自增长的列中插入0或NULL将不会是下一个自增长值。

  NO_BACKSLASH_ESCAPES:反斜杠"\"作为普通字符而非转义字符

  NO_DIR_IN_CREATE:在创建表时忽略所有index directory和data directory的选项。

  NO_ENGINE_SUBSTITUTION:启用后,若需要的存储引擎被禁用或未编译,则抛出错误;未启用时将用默认的存储引擎代替,并抛出一个异常。

  NO_UNSIGNED_SUBSTRACTION:启用后,两个UNSIGNED类型相减返回SIGNED类型。

  NO_ZERO_DATE:启用后,不允许插入“0000-00-00 00:00:00”形如此类的零日期,这将抛出一个错误,若未启用,则可插入但仅会抛出一个警告。

  NO_ZERO_IN_DATE:启用后,不允许月份和日期为零,和 NO_ZERO_DATE一起启用,如“1999-01-00”将抛出错误而非警告。若单独启用本项,则会抛出warning,然后插入如“0000-00-00 00:00:00”。

  ONLY_FULL_GROUP_BY:对于GROUP BY聚合操作,若select中的列没有在group by中出现,那么这句SQL是不合法的。

  PAD_CHAR_TO_FULL_LENGTH:启用后,对于CHAR类型将不会截断空洞数据;

  PIPES_AS_CONCAT:将"||"视为连接操作符而非“或运算符”。

  REAL_AS_FLOAT:将REAL视为FLOAT的同义词而非DOUBLE的同义词。

  组合选项:

  ·ANSI:

  REAL_AS_FLOAT、PIPES_AS_CONCAT、ANSI_QUOTES、IGNORE_SPACE、ANSI

  ·ORACLE:

  PIPES_AS_CONCAT、ANSI_QUOTES、IGNORE_SPACE、NO_KEY_OPTIONS、NO_TABLE_OPTIONS、NO_FIELD_OPTIONS、NO_AUTO_CREATE_USER、ORACLE

  ·TRADITIONAL:

  STRICT_TRANS_TABLES、STRICT_ALL_TABLES、NO_ZERO_IN_DATE、NO_ZERO_DATE、ERROR_FOR_DIVISION_BY_ZERO、NO_AUTO_CREATE_USER、NO_ENGINE_SUBSTITUTION、TRADITIONAL

  ·MSSQL:

  PIPES_AS_CONCAT、ANSI_QUOTES、IGNORE_SPACE、MSSQL、NO_KEY_OPTIONS、NO_TABLE_OPTIONS、NO_FIELD_OPTIONS、MSSQL

  ·DB2:

  PIPES_AS_CONCAT、ANSI_QUOTES、IGNORE_SPACE、NO_KEY_OPTIONS、NO_TABLE_OPTIONS、NO_FIELD_OPTIONS、DB2

  ·MYSQL323:

  HIGH_NOT_PRECEDENCE、MYSQL323

  ·MYSQL40:

  HIGH_NOT_PRECEDENCE、MYSQL40

  ·MAXDB:

  PIPES_AS_CONCAT、ANSI_QUOTES、IGNORE_SPACE、NO_KEY_OPTIONS、NO_TABLE_OPTIONS、NO_FIELD_OPTIONS、NO_AUTO_CREATE_USER、MAXDB

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 解决Mysql5.7中文乱码的问题

    解决Mysql5.7中文乱码的问题

    在使用mysql5.7时,会发现通过web端向数据库中写入中文后会出现乱码,但是在数据库中直接操作SQL语句插入数据后中文就显示正常,这个问题怎么解决呢,下面小编给大家分享下解决方案
    2017-03-03
  • 详解MySQL的内连接和外连接

    详解MySQL的内连接和外连接

    这篇文章主要介绍了详解MySQL的内连接和外连接,mySQL包含两种联接,分别是内连接(inner join)和外连接(out join),但我们又同时听说过左连接,交叉连接等术语,本文就带大家来了解一下,需要的朋友可以参考下
    2023-05-05
  • 解决MySQL启动报错:ERROR 2003 (HY000): Can''t connect to MySQL server on ''localhost'' (10061)

    解决MySQL启动报错:ERROR 2003 (HY000): Can''t connect to MySQL serv

    这篇文章主要介绍了解决MySQL启动报错:ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061),本文解释了如何解决该问题,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • MySQL实现字段的自定义排序的方法

    MySQL实现字段的自定义排序的方法

    一般情况下,我们排序都是直接利用 order by 字段 asc/desc;但是如果要排序的字段数据格式并不能直接实现,或者说我们需要指定的顺序且没有什么规律,简单的order by字段就实现不了,所以本文给大家介绍了MySQL实现字段的自定义排序的方法,需要的朋友可以参考下
    2024-04-04
  • mysql忘记root密码的解决办法(针对不同mysql版本)

    mysql忘记root密码的解决办法(针对不同mysql版本)

    这篇文章主要介绍了mysql忘记root密码的解决办法(针对不同mysql版本),文章通过代码示例和图文结合的方式给大家讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-06-06
  • K8s 如何部署 MySQL 8.0.20 主从复制结构

    K8s 如何部署 MySQL 8.0.20 主从复制结构

    这篇文章主要介绍了K8s 如何部署 MySQL 8.0.20 主从复制结构,本次使用 OpenEBS 来作为存储引擎,OpenEBS 是一个开源的、可扩展的存储平台,它提供了一种简单的方式来创建和管理持久化存储卷,需要的朋友可以参考下
    2024-04-04
  • Mysql数据库按时间点恢复实战记录

    Mysql数据库按时间点恢复实战记录

    如果客户在某时间节点由于误操作,导致数据丢失,RDS管控服务是如何进行恢复的呢?通过Mysql数据库按时间点恢复该如何操作呢,感兴趣的朋友跟随小编一起看看吧
    2021-06-06
  • 详解mysql数据库如何开启慢查询日志

    详解mysql数据库如何开启慢查询日志

    这篇文章主要介绍了详解mysql数据库如何开启慢查询日志的相关资料,需要的朋友可以参考下
    2017-03-03
  • MySQL如何获取当前时间与日期间隔

    MySQL如何获取当前时间与日期间隔

    这篇文章主要介绍了MySQL如何获取当前时间与日期间隔问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • PHP之Mysql常用SQL语句示例的深入分析

    PHP之Mysql常用SQL语句示例的深入分析

    本篇文章是对Mysql常用SQL语句进行了详细的分析介绍,需要的朋友参考下
    2013-06-06

最新评论