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这个类型~