【问题标题】:What validation does MySQL do when strict mode is enabled?启用严格模式时 MySQL 会进行哪些验证?
【发布时间】:2012-11-28 10:24:34
【问题描述】:

当 MySQL 允许我将 NULL 插入到使用 NOT NULL 创建的字段中时,我感到非常惊讶。我做了一些研究,发现了如何启用严格模式。但是,我不太确定启用 STRICT_ALL_TABLES 时 MySQL 会做什么验证。

手册说:

严格模式控制 MySQL 如何处理无效或丢失的输入值。 一个值可能因多种原因无效。(强调我的)例如,它可能具有错误的列数据类型,或者它可能超出范围。

我了解它认为缺少什么以及如何处理它。我不清楚它认为什么是无效。我做了一些测试并发现了以下内容:

  • 过长的字符串无效
  • 超出范围的数字无效
  • NULL 列的NULLs 无效
  • TRUEFALSE 似乎总是有效的(它们分别变成 1 和 0)
  • 无效日期无效
  • 零日期有效(可以启用其他模式来更改此行为)
  • 整数字段中的浮点数有效(四舍五入)
  • 数字字段中的字母无效

除了上述之外,MySQL 是否进行任何其他验证检查?

手册说“列的数据类型错误”,但我看到的唯一实际发挥作用的情况是数字字段中的字母。还有其他数据类型错误的例子吗?

是否有一份关于 MySQL 执行的检查的列表?

编辑: 作为记录,我的应用程序已经进行了广泛的验证。我使用严格模式作为最后的机会,以防万一。如果我忘记检查某些内容,我希望它快速失败,而不是“默默地破坏我的数据”。

【问题讨论】:

  • 我感觉您希望数据库为您进行数据验证。如果是这样的话,那就不好走下去了。
  • @siride:DBMS is 在那里进行验证(外键、主键、检查约束、类型验证)。 MySQL 允许您存储February, 31st 的事实在我看来是一个错误。或者换句话说:如果 DBMS 不做任何验证,这是一条非常糟糕的路。
  • 我已经在应用程序中进行了验证。我使用严格模式作为良好编程的替代,而是确保良好编程的一种方式.
  • 刚刚看到你的最新评论。听起来不错。不过,我会在此处留下我的评论,以供将来查看仅 Db 验证解决方案的人使用。
  • 天哪。一个高质量的研究问题。

标签: mysql validation strict


【解决方案1】:

我对 MySQL 5.5.28(社区服务器版)的源代码进行了 grep,以查找正在使用的 STRICT_ALL_TABLES 的实例。

从我看到的情况来看,您的列表看起来已经很完整了,但下面是我学到的关于使用 STRICT_ALL_TABLES 的更多信息。第一个是另一个验证,其余的都是处理错误和警告。

  • 几何列不能有默认值。 (sql/field.cc:9394)
  • 如果表注释超过 2048 个字符,MySQL 会产生错误而不是截断注释并发出警告。 (sql/unireg.cc:231)
  • 如果字段注释超过 1024 个字符,MySQL 会产生错误而不是截断注释并发出警告。 (sql/unireg.cc:739)
  • 在插入或更新时,如果 SET 或 ENUM 中存在重复值,MySQL 会产生错误而不是警告。 (sql/sql_table.cc:2503)
  • 有很多操作会在收到 STRICT_ALL_TABLES 警告时中止,而不是继续发出警告。这些对我来说太多了,并且 abort_on_warning 标志的设置与创建警告的代码相去甚远,以至于我无法轻松记录(甚至理解)所有这些警告。但是,如果有人想亲身体验源代码,可以从 sql/sql_update.cc:630sql/sql_insert.cc:841 开始。

【讨论】:

    【解决方案2】:

    一个很好的资源是检查 MySQL 源代码,并阅读 mysql-test/t/strict.test 以查看他们在设置 STRICT 模式或 TRADITIONAL 模式(这是 STRICT 的超集)后测试的所有案例。

    您进行了出色的研究和测试,但还有一些案例,例如:

    • 试图插入未定义的 ENUM 值。
    • 尝试为未定义 DEFAULT 的 NOT NULL 列插入默认值。
    • 尝试使用 CAST() 将字符串转换为整数等。
    • 如果您提供的长度大于 65536,则将 VARCHAR 转换为 MEDIUMTEXT 或 LONGTEXT。
    • 截断表和列的 COMMENT 字符串。
    • 字符串到 YEAR 类型的转换。
    • 定义包含重复条目的 SET 或 ENUM 列。

    还有mysql-test/include/strict_autoinc.inc,因为它会在 auto-inc 值增长过大时测试溢出。

    还有一些其他测试文件使用 STRICT 模式进行特定测试,但我没有检查它们。

    【讨论】:

    • 另一种情况是尝试将负数插入 UNSIGNED 列。
    • dev.mysql.com/downloads/mysql/#downloads,选择“源代码”作为平台。
    • 是的,无符号列中的负数是测试涵盖的另一种情况,但我认为这是超出列范围的数字的情况。
    • '无符号列中的负数超出范围' - 你当然是对的,但很多人就是不明白。
    猜你喜欢
    • 2011-08-15
    • 2019-04-22
    • 2023-03-22
    • 1970-01-01
    • 2010-11-28
    • 2014-01-01
    • 1970-01-01
    • 2011-12-21
    • 1970-01-01
    相关资源
    最近更新 更多