mysql - 报价数字与否?

Sta*_*ann 45 mysql sql ansi-sql

例如 - 我从cli创建数据库和表并插入一些数据:

CREATE DATABASE testdb CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
USE testdb;
CREATE TABLE test (id INT, str VARCHAR(100)) TYPE=innodb CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
INSERT INTO test VALUES (9, 'some string');
Run Code Online (Sandbox Code Playgroud)

现在我可以这样做,这些例子确实有用(所以 - 引号不会影响它看起来的任何东西):

SELECT * FROM test WHERE id = '9';
INSERT INTO test VALUES ('11', 'some string');
Run Code Online (Sandbox Code Playgroud)

所以 - 在这些例子中,我通过在mysql中实际存储为INT 的字符串选择了一行,然后在一个INT列中插入了一个字符串.

我不太明白为什么它的工作方式与此相同.为什么允许将字符串插入INT列?

我可以将所有Mysql数据类型作为字符串插入吗?

这种行为是否适用于不同的RDBMS?

谢谢!

Mar*_*c B 61

MySQL与PHP非常相似,并且会尽可能地自动转换数据类型.因为你正在使用一个int字段(左侧),所以它会尝试透明地将参数的右侧转换为int,所以'9'就这样了9.

严格来说,引号是不必要的,并强制MySQL进行类型转换/转换,因此浪费了一点CPU时间.实际上,除非您正在运行Google大小的操作,否则这种转换开销在微观上会很小.

  • 我认为引号也可能导致由于转换而未使用索引的情况.所以我也建议你做得好,不要在数字上使用引号.这也将使更容易转换到更符合标准的DBMS. (3认同)

小智 8

你永远不应该在数字上加上引号.这是有正当理由的.

真正的问题归结为打字.当您将数字放在引号内时,它被视为一个字符串,MySQL必须将它转换为一个数字才能执行查询.虽然这可能需要很短的时间,但是当MySQL没有很好地转换你的字符串时,真正的问题就开始发生了.例如,MySQL会将基本字符串(如'123')转换为整数123,但会将一些较大的数字(如'18015376320243459')转换为浮点数.由于浮点可以舍入,因此查询可能会返回不一致的结果.在此处详细了解类型转换.根据您的服务器硬件和软件,这些结果会有所不同.MySQL解释了这个.

如果您担心SQL注入,请始终先检查该值并使用PHP去除任何非数字.您可以使用preg_replace:preg_replace("/[^0-9]/", "", $string)

此外,如果使用引号编写SQL查询,它们将无法在PostgreSQL或Oracle等数据库上运行.


Anu*_*ush 0

你不需要引用这些数字,但如果你这样做的话,它总是一个好习惯,因为它是一致的。

  • 引用**无**有助于防止 sql 注入 (7认同)
  • @wonk0 Anush 关于 **安全** 的论点似乎完全有效。来自 [MySQL 安全指南手册页](http://dev.mysql.com/doc/refman/5.5/en/security-guidelines.html) - “一个常见的错误是仅保护字符串数据值。记住也检查数字数据。如果当用户输入值 234 时应用程序生成诸如 SELECT * FROM table WHERE ID=234 之类的查询,则用户可以输入值 234 OR 1=1 以使应用程序生成查询 SELECT * FROM table WHERE ID=234 OR 1=1。结果,服务器检索表中的每一行。... (4认同)
  • 1 OR 1=1 或类似的内容,如果不加引号,可能会导致服务器上不必要的负载或 SQL 注入。在 sql 查询中引用所有内容已成为一种第二天性,但是如果您很挑剔,然后本应引用为数字的 sql 查询却没有,那么可能会发生 sql 注入(在线检查这一点以及有多少受害者) )。虽然引用数字确实会给服务器带来一点负载,但即使每秒执行大约 100K 查询,对于 100K 查询来说,总共也只能节省 11 秒,这意味着每个查询不到 1 毫秒。 (2认同)