MySQL学习之弱类型

it2022-05-09  36

这篇文章主要讨论一下MySQL中弱类型可能导致的一些问题

首先创建一个表:

CREATE TABLE `user` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `nick` varchar(50) CHARACTER SET utf8 NOT NULL DEFAULT '', `score` int(10) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

插入数据:

INSERT INTO `user` (`nick`,`score`) VALUES ('张三', '100'); INSERT INTO `user` (`nick`,`score`) VALUES ('1张三', '99分'); INSERT INTO `user` (`nick`,`score`) VALUES ('2张三', '分数'); INSERT INTO `user` (`nick`,`score`) VALUES ('3张三', 97);

在score列我们尝试了多种类型,有数字有汉字,数字有带引号的,也有不带引号的,但无一例外,它们都执行成功了,看下结果:

mysql> select * from user; +----+-------+-------+ | id | nick | score | +----+-------+-------+ | 1 | 张三 | 100 | | 2 | 1张三 | 99 | | 3 | 2张三 | 0 | | 4 | 3张三 | 97 | +----+-------+-------+ 4 rows in set

在第二行和第三行发生了隐式的数据转换,这点和PHP非常相似:

<?php echo 1 + '2a'; //结果输出为3,这里会有一个警告出现

再来插入一条数据:

INSERT INTO `user` (`nick`,`score`) VALUES (1, '95');

同样成功了,所以:在插入MySQL数据的时候,字符型数据和整数型数据可以发生隐式的转换。(其他数据类型暂时不做测试)

这种数据转换往往带给我们很多困扰,如下:

1、查找时忘加引号导致结果和想要的结果不同。

比如我们想要查找nick为1的结果,我们忽略了字段类型,结果写出了下面的SQL:

mysql> select * from user where nick=1; +----+-------+-------+ | id | nick | score | +----+-------+-------+ | 2 | 1张三 | 99 | | 5 | 1 | 95 | +----+-------+-------+ 2 rows in set

这和我们想要的结果就不一样,这样写还有一个后果,我们来看一下,把nick设置为索引:

ALTER TABLE `user` ADD INDEX `nikc` (`nick`) USING BTREE ;

用explain来看一下查询效果:

mysql> explain select * from user where nick=1; +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ | 1 | SIMPLE | user | ALL | nikc | NULL | NULL | NULL | 5 | Using where | +----+-------------+-------+------+---------------+------+---------+------+------+-------------+ 1 row in set mysql> explain select * from user where nick='1'; +----+-------------+-------+------+---------------+------+---------+-------+------+-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+-------+------+-----------------------+ | 1 | SIMPLE | user | ref | nikc | nikc | 152 | const | 1 | Using index condition | +----+-------------+-------+------+---------------+------+---------+-------+------+-----------------------+ 1 row in set

如果字段类型是varchar,而查找条件为整数,就会全表查找,不会用到索引。

2、删除数据时如果把=写成了-会造成严重的后果

比如我想删除张三这条记录:

delete from user where nick="张三";

由于手残,我们把=号打成了-号

mysql> delete from user where nick-"张三";Query OK, 4 rows affected

发生了什么情况?4条语句被删除了,我们查看一下:

mysql> select * from user; +----+------+-------+ | id | nick | score | +----+------+-------+ | 1 | 张三 | 100 | +----+------+-------+ 1 row in set

居然只剩下一个我们真正想要删除的张三,分析我们的数据,发现了一条规律,nick字段中以数字开头的记录全部被删除了,这也是在执行的过程中发生了隐式的数据类型转换。

 

转载于:https://www.cnblogs.com/shamohai/p/8290487.html

相关资源:各显卡算力对照表!

最新回复(0)