您的位置:首页 > 数据库

数据库原理课本中模糊匹配 like 下划线匹配多字符问题

2015-04-17 12:59 253 查看
在数据库系统概论第四版第三章96页的字符匹配当中指出,_(下划线)代表任意单个字符。根据书中前面的sql语句建立表格,并插入数据,执行查找姓刘的同学的记录

USE school

GO

SELECT *

FROM Student

WHERE Sname LIKE '刘_';

结果如下:



现在没有任何问题,是我们想要的结果,但是如果多打一个_(下划线)结果会是什么样呢?



原本应该只匹配三个字的Sname 的记录才输出,然而两个字的Sname的记录也输出了。

这结果让人感觉很蛋疼,为什么会是这个结果呢?我觉得这是这本的bug。那么问题究竟出来哪呢?

我们看一下建表的语句以及定义的数据类型:

CREATE TABLE Student --create student table

( Sno CHAR(9) PRIMARY KEY,

Sname
CHAR(20)
NOT NULL UNIQUE,

Ssex CHAR(2),

Sage SMALLINT,

Sdept CHAR(20)

);

我们可以看到Sname的数据类型是CHAR类型,问题就出在这里。我们首先看一下CHAR和VARCHAR的区别(参考网友解释):

1. char类型:

对英文(ASCII)字符占用1个字节,对一个汉字占用2个字节,CHAR存储定长数据很方便,CHAR字段上的索引效率极高,比如定义char(10),那么不论你存储的数据是否达  到了10个字节,都要占去10个字节的空间。因为是固定长度,所以速度效率高。比如定义char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间。因为是固定长度,所以速度效率高。

2. VARCHAR存储变长数据

如果一个字段可能的值是不固定长度的,我们只知道它不可能超过10个字符,把它定义为 VARCHAR(10)是最合算的。VARCHAR类型的实际长度是它的值的实际长度+1。为什么“+1”呢?这一个字节用于保存实际使用了多大的长度。

   Varchar类型:Varchar 的类型不以空格填满,而Char则会填充满为止,如varchar(100),但它的值只是"qian",所以它在数据库中存的值就是"qian",而char 不一样,如char(100),它的  值是"qian",而实际上它在数据库中是"qian "(qian后共有96个空格,就是把它填满为100个字节)。

注:由于char是以固定长度的,所以它的速度会比varchar快得多!但程序处理起来要麻烦一点,要用trim之类的函数把两边的空格去掉!

我们可以看到,根据书中定义的Sname是定长CHAR型,长度为20,那么当存入一条记录,其中Sname是“刘晨”时,在数据库中“刘晨”的存储形式是前四个字节存姓名,后面18字节用空格补齐,而空格也是字符,_(下划线)也匹配它,所以执行sql语句进行模糊查询时将字符串长度小于3的也匹配出来。

那么如何解决这问题呢,我们重新建一个表,Sname定义为VARCHAR(20)类型,看一下结果:







我们可以看到,定义为VARCHAR类型后,由于字符串的长度就是存储长度,不存在用空格补全问题,所以输出结果正常。可以看出数据的定义还要是非常小心的,那么我们怎么可以避免这个问题我,我认为:

首先,要选择合适的数据类型。其次用先对安全的方法得到自己想要结果。

比如,我们可以用

SELECT *

FROM Student

WHERE Sname LIKE '刘%' AND LEN(Sname)=2;

语句,同样是在课本定义的数据库中得到我们想要的结果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: