MySQL中需要注意的字段长度问题

在MySQL的表结构设计中,突然想起来几个地方碰到的问题比较多,大体来说一个就是字符集,一个就是数据类型。

而字符集和数据类型结合起来,就有一个蛮有意思的细节,那就是行长度的问题。

比如我们创建一个表使用了varchar的类型,如果指定为gbk,表里含有一个字段,可以指定为32766字节,如果再长一些就不行了。

其中的计算方式就需要理解了,因为varhcar类型长度大于255,所以需要2个字节存储值的长度,而MySQL里面的页的单位是16k,使用了IOT的方式来存储。所以如果超过了这个长度,那就会有溢出的情况,和Oracle的overflow很类似。

所以对于gbk类型,行长度最大为65535,则varchar列的最大长度算法就是 (65535-2)/2 =32766.5,所以此处就是32766了。

> create table test_char(v varchar(32766)) charset=gbk;
Query OK, 0 rows affected (0.00 sec)
> create table test_char1(v varchar(32767)) charset=gbk;
ERROR
1118 (42000): Row size too large. The maximum row size for the used
table type, not counting BLOBs, is 65535. You have to change some
columns to TEXT or BLOBs而另外一种字符集,也是默认的字符集latin1,有些系统支持火星文的还是会喜欢用这种字符集。

它的长度就不一样了,对应是1字节,所以varchar(32767)是没有任何问题的,而最大长度就是65532了。
> create table test_char1(v varchar(32767)) charset=latin1;
Query OK, 0 rows affected (0.01 sec)
> create table test_char2(v varchar(65535)) charset=latin1;
ERROR
1118 (42000): Row size too large. The maximum row size for the used
table type, not counting BLOBs, is 65535. You have to change some
columns to TEXT or BLOBs而对于utf8还是有很大的差别,对应的是3个字节,所以需要除以3,按照(65535-2)/3,最大值就是21844了。
> create table test_char2(v varchar(21844)) charset=utf8;    
Query OK, 0 rows affected (0.00 sec)
> create table test_char3(v varchar(21845)) charset=utf8;
ERROR
1118 (42000): Row size too large. The maximum row size for the used
table type, not counting BLOBs, is 65535. You have to change some
columns to TEXT or BLOBs上面的场景相对来说会有一些局限性,那么我们引入表结构的设计。

如果是gbk字符集,含有下面的几个字段,则memo字段的varchar类型最大长度是多少?

> create table test_char3(id int,name varchar(20),memo varchar(32766)) charset=gbk;
ERROR
1118 (42000): Row size too large. The maximum row size for the used
table type, not counting BLOBs, is 65535. You have to change some
columns to TEXT or BLOBs

这个问题还是如法炮制,应用之前的计算方式,数值型是4个字节,字符型乘以2,含有字符型的长度小于255,所以减去1即可,这样下来就是(65535-1-4-20*2-2)约等于32743

> create table test_char3(id int,name varchar(20),memo varchar(32744)) charset=gbk;
ERROR
1118 (42000): Row size too large. The maximum row size for the used
table type, not counting BLOBs, is 65535. You have to change some
columns to TEXT or BLOB两种测试结果可以简单对比一下。
> create table test_char3(id int,name varchar(20),memo varchar(32743)) charset=gbk;
Query OK, 0 rows affected (0.01 sec)
select (65535-1-4-20*2-2)/2;
+----------------------+
| (65535-1-4-20*2-2)/2 |
+----------------------+
|           32744.0000 |
+----------------------+
1 row in set (0.00 sec)

整个过程还是需要考虑到这些点的,否则前期不够重视,在后面去做扩展的时候就会有很大的限制。

时间: 2024-09-15 08:12:59

MySQL中需要注意的字段长度问题的相关文章

MySQL 中查找含有目标字段的表的方法_Mysql

复制代码 代码如下: SELECT TABLE_SCHEMA,TABLE_NAME FROM information_schema.`COLUMNS` WHERE COLUMN_NAME='字段名字' 参考:MySQL中,一个字段在多张表都存在,怎么用sql语句一次性查询这些表呢

MySQL中使用表别名与字段别名的基本教程_Mysql

MySQL 表别名(Alias)SQL 表别名 在 SQL 语句中,可以为表名称及字段(列)名称指定别名(Alias),别名是 SQL 标准语法,几乎所有的数据库系统都支持.通过关键字 AS 来指定. 表别名语法: SELECT column FROM table AS table_alias 上述 SQL 执行后的效果,给人感觉是对 table_alias 表进行查询,但实际上对单表做简单的别名查询通常是无意义的.一般是对一个表要当作多个表来操作,或者是对多个表进行操作时,才设置表别名. 表别

mysql中合并两个字段的方法分享_Mysql

例如:select (a+b) as c from 表 类型也一致都是varchar型的,可就是显示不正确. 直到concat() MySQL中concat函数 下面通过一个例子介绍MySQL中的concat函数的使用方法,比如select concat('11','22','33'). MySQL中concat函数 使用方法: CONCAT(str1,str2,-) 返回结果为连接参数产生的字符串.如有任何一个参数为NULL ,则返回值为 NULL. 注意: 如果所有参数均为非二进制字符串,则

mysql中删除字符串或字段中空格函数

在mysql中提供了ltrim,rtrim函数来删除字符的首毛空格那么如果我要删除字符如"abc fdsa"应该如何做来,下面我们来看教程 ltrim 函数 代码如下  mysql> select concat('.', ltrim(' ddd '), '.'); rtrim函数 代码如下  mysql> select concat('.', rtrim(' ddd '), '.'); trim 字符串函数,实在是强大.它不仅能消除字符串首尾部的空格,还可以消除我们指定的任

mysql 中如何取得汉字字段的各汉字首字母_Mysql

DROP FUNCTION IF EXISTS `getPY`; DELIMITER ;; CREATE FUNCTION `getPY`(in_string VARCHAR(65534)) RETURNS mediumtext CHARSET utf8 BEGIN DECLARE tmp_str VARCHAR(65534) charset gbk DEFAULT '' ; #截取字符串,每次做截取后的字符串存放在该变量中,初始为函数参数in_string值 DECLARE tmp_len S

mysql中varchar和text字段类型理解

最近有几个同学问我varchar和text有啥别吗,这个问题,以前说真的也没太多的整理,以前遇到text在设计中就是尽可能的拆到另一个表中,保持主表尽量的瘦小,可以让innodb bp缓存更多的数据. 今天借次机会系统整理一下,主要从存储上,最大值,默认值几个方面进行比较. BTW: 从ISO SQL:2003上讲VARCHAR是一个标准型,但TEXT不是(包括tinytext).varchar在MySQL 5.0.3之前只支持0-255byte, 在5.0.3之后才支持到0-65535byte

mysql中int和varchar的长度详解

int 从 -2^31 (-2,147,483,648) 到 2^31 – 1 (2,147,483,647) 的整型数据(所有数字).存储大小为 4 个字节.int 的 SQL-92 同义字为 integer varchar 长度是0-255个字符哦 mysql 字段中int后面所跟数字有何意义? varchar后的数字又有何意义?  代码如下 复制代码 mysql> create table t(a int(1)); Query OK, 0 rows affected (0.10 sec)

MySQL中给自定义的字段查询结果添加排名的方法_Mysql

 我正在用 MySQL 客户端的时候,突然想到如果可以给查询结果添加排名该多好啊,然后就找到了一个简单的解决办法. 下面是一个示例表的数据:  然后我们要根据 Roll_No 字段进行排序并给出排名,我们首先必须定义一个初始值为0的变量,然后在查询结果中使用这个变量. 如下面的代码:   SET @counter=0; SELECT @counter:=@counter+1 AS Rank,LastName,Roll_no as Roll FROM Students ORDER BY Roll_

mysql中时间日期 datetime字段保存日期出现0000-00-00

正确的php sql语句写法应该是:     代码如下 复制代码 $sql = "insert into table(datetime) values('".date("Y-m-d h:i:s",time())."')"; //datetime字段的类型为"datetime", 注意后面要插入的数据是字符串要加"单引号". 这样就没错了,时间日期类型插入数据库之前要格式化,否则就出现插入的全是0000-00