mysql 的varchar类型小记

Posted jiafeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql 的varchar类型小记相关的知识,希望对你有一定的参考价值。

参考链接:MySQL的varchar长度问题

今天用mysql做一个demo,创建了个表:

-- 借款表
CREATE  TABLE jk (    
    id int(5) NOT NULL auto_increment, -- 自增ID
    amount int not null, -- 借款本金
    remark varchar(255), -- 备注/摘要
    PRIMARY KEY  (`id`)
)    ;

insert into jk(amount,remark) values(20000,\'付张三借款\');
insert into jk(amount,remark) values(10000,\'付王小五借款\');
insert into jk(amount,remark) values(80000,\'付宇文小四借款\'); 
insert into jk(amount,remark) values(20000,\'付张三12ab借款\');

由于这个表没有人的姓名做主键(暂不考虑人名重复),想取出来人名,就只能对remark字段做拆解了。

当然拆解的办法不止一种,我的思路是通过length、left、right三个函数,拆解得出借款人的姓名。

具体思路就是,通过left先取出不含“借款”的字符串str_l,再通过right函数对str_l去除"付"字。那么就得到了中间的名字了。

然后我写的代码是:

-- 注意:这是错误写法!!!
SELECT jk.id,jk.amount,jk.remark,
        LEFT(jk.remark,LENGTH(jk.remark)-2) AS \'左边\',# 去掉“借款”2字
        RIGHT(jk.remark,LENGTH(jk.remark)-1) AS \'右边\',# 去掉“付”字
        RIGHT(
                   LEFT(jk.remark,LENGTH(jk.remark)-2),
            LENGTH(LEFT(jk.remark,LENGTH(jk.remark)-2))-1
        ) AS NAME
FROM jk;

 

看上去好像没毛病,先取长度,“借款”是两个字,所以减2;“付”是一个字,所以减1。菜鸟如我啊~。

然后结果却是吃了一鲸~:

 

 为什么呢?第一反应是长度计算有问题,我就把length函数计算的结果单独列出来:

果然啊,mysql的水比较深啊~查了一下资料,恍然大悟:当格式默认为utf-8时,varchar存储的汉字占3个字节,而length函数计算的长度其实就是字节个数

varchar(n)的这个n指的是字符数,而不是字节数,也就是当你定义varchar(255)时,不管中文 还是英文 都是存255个字符的,只不过length函数计算的是字节数而非字符数。

 于是我改成了这样:

select jk.id,jk.amount,jk.remark,
        length(jk.remark),#长度 
        left(jk.remark,length(jk.remark)/3-2) as \'左边\',
        right(jk.remark,length(jk.remark)/3-1) as \'右边\',
        right(
                   left(jk.remark,length(jk.remark)/3-2),
            length(left(jk.remark,length(jk.remark)/3-2))/3-1
        ) as name
from jk;

结果是:

 

除了第四个,其他的都成功解析出了姓名。至于最后一条记录的姓名还是有问题,我觉得得换种思路了,以后再写吧。今天主要是想说一下varchar这个类型~

 

以上是关于mysql 的varchar类型小记的主要内容,如果未能解决你的问题,请参考以下文章

mysql类型转换函数使用小记

mysql类型转换函数使用小记

mysql 字段类型VARCHAR转换成DECIMAL

如何将数据类型varchar转换为时间戳mysql?

记 MySQL varchar类型查询一个小问题

MySQL中怎么对varchar类型排序问题