在数字数据类型上向 MySQL 数据库写入查询的正确方法是什么:
SELECT * FROM accounts WHERE id = 5;
或者
SELECT * FROM accounts WHERE id = '5';
主要是我更喜欢最后一个,'
因为它更符合文本数据类型。
会影响性能吗?
在数字数据类型上向 MySQL 数据库写入查询的正确方法是什么:
SELECT * FROM accounts WHERE id = 5;
或者
SELECT * FROM accounts WHERE id = '5';
主要是我更喜欢最后一个,'
因为它更符合文本数据类型。
会影响性能吗?
引号用于字符串,MySQL 将读取这些引号,然后将其转换为整数,这比仅将 int 开始时要慢。
老实说,性能差异很小,但这就像编写一个程序,将数字存储在字符串中,然后在需要进行一些数学运算时转换为 int。这是不好的做法。
我怀疑您是否可以衡量两个查询速度之间的任何显着差异。如果您关心性能,则应确保在id
列上有索引。如果这样做,两个查询都会非常快。
但是有安全方面的考虑。
MySQL官方意见
MySQL 客户端安全指南建议您使用引号。
一个常见的错误是只保护字符串数据值。记住也要检查数字数据。如果应用程序在用户输入值 234 时生成诸如 SELECT * FROM table WHERE ID=234 之类的查询,则用户可以输入该值
234 OR 1=1
以使应用程序生成查询SELECT * FROM table WHERE ID=234 OR 1=1
。结果,服务器检索表中的每一行。这会暴露每一行并导致过多的服务器负载。防止此类攻击的最简单方法是在数字常量周围使用单引号:SELECT * FROM table WHERE ID='234'
.
强调我的。
我的意见
尽管文档建议使用引号,但它既没有必要也不足以防止它描述的攻击。例如,将攻击者的字符串更改为234' OR '1'='1
会破坏他们的方法。
在我看来,使您的应用程序安全的更好方法是使用参数化查询,而不是将用户值直接放入字符串中。
如果由于某种原因您不能使用参数化查询,则不要使用引号,而是通过使用intval
函数确保变量确实包含整数。
当数据库中的字段类型是字符串时,请使用引号。否则,如果它是数字,则不要使用引号。如果您对数字字段类型使用引号,它确实会减慢查询速度,因为 mysql 必须将字符串与数字匹配。
根据 id 的类型,您可以使用“5”或 5。通常 id 是主键并且是 int 类型,因此您应该使用 5
对类型被定义为数字的列使用带引号的数字有一点点与使用不带引号的值相比,性能会受到影响,因为服务器必须在查询编译期间将字符串转换为正确的类型。除此之外,它没有任何效果,而且您可能根本难以测量命中率。(请注意,由于“0”和 0 都作为字符串发送到服务器,因此无论如何都必须在使用之前将它们转换为字段的内部类型,因此发送“0”只会强制执行一个额外的步骤。首先解析器解析出“0”然后优化器注意到列类型是数字并相应地转换它。OTOH,使用 0 解析器将其解析为数字 [存储为 long int iirc],然后注意字段的类型,并转换如有必要,将数字转换为适当的字段类型。因此差异确实是微不足道的)。
但是,对类型定义为文本的列使用不带引号的数字是一个非常非常糟糕的主意,因为这意味着服务器不能使用列上的任何索引来解析查询。
重要的是要理解,尽管任何给定的字符串都可以精确地数字化为一个数值,但有一组几乎无限的字符串可以数字化为给定的数字值。考虑“0”、“0E0”、“0.0”等。这解释了为什么在字段为数字时引用约束并不是很糟糕,只有要执行的操作,它解释了为什么在字段中不引用约束是不好的不是数字,因为这意味着服务器必须在进行比较之前将表中的每个字符串转换为一个数字,从而强制进行表扫描。