mysql中关于int(11)和varchar(255)的若干理解

int(11)

在mysql设计表的时候经常会定义字段长度,比如说id int(11)

在这里插入图片描述

对于 int 类型的一些基础知识其实上图已经说的很明白了,在这里想讨论下常用的 int(11) 代表什么意思,11 代表的并不是长度,而是字符的显示宽度,在字段类型为 int 时,无论你显示宽度设置为多少,int 类型能存储的最大值和最小值永远都是固定的。

那么这个显示宽度到底有什么用呢

当 int 字段类型设置为无符号且填充零(UNSIGNED ZEROFILL)时,当数值位数未达到设置的显示宽度时,会在数值前面补充零直到满足设定的显示宽度,为什么会有无符号的限制呢,是因为 ZEROFILL 属性会隐式地将数值转为无符号型,因此不能存储负的数值。

下面举一个int(2)的例子
在这里插入图片描述

INSERT into test VALUES(12345,'666')

在这里插入图片描述

综上所述

  • 如果一个字段设置了无符号和填充零属性,那么无论这个字段存储什么数值,数值的长度都会与设置的显示宽度一致,如上述例子中的字段 b,插入数值
    1 显示为00000000001,左边补了 10 个零直至长度达到 11 位;
  • 设置字段的显示宽度并不限制字段存储值的范围,比如字段 d 设置为 int(5),但是仍然可以存储 1234567890 这个 10
    位数字;
  • 设置的字符宽度只对数值长度不满足宽度时有效,如 d 字段 int(5),插入 1 时,长度不足 5,因此在左边补充 4 个零直到 5
    位,但是插入 1234567890 时超过了 5 位,这时的显示宽度就起不了作用了。

varchar(255)

这里只是解释varchar并不是针对varchar(255)
varchar(255)中的255是字符数,具体的字节数和编码集有关,一般GBK一个字符2个字节UTF-8一个字符3个字节UTF8MB4一般一个字符也是3个字节,但是emoji表情可以占到4个字节

这里上一道题目,激发一下深入了解的动力

假设有个VARCHAR(64) CHARSET utf8mb4列,存储了中国cn这个字符串。
那你猜一猜,MySQL存储时用了多少字节?

在这里插入图片描述

VARCHAR的定义

VARCHAR是变长字符串。MySQL行默认最大65535字节,是所有列共享的,所以VARCHAR的最大值受此限制。长度标识位最大2个字节=16位=2^16 - 1 = 65535 byte.长度标志位是底层存储开销,不占用字段声明的字符长度。比如VARCHAR(1),长度标识位的空间不会在1里扣除,会另外找一个字节存放
这边用CHAR定长类型来对比

  • VARCHAR(4),最多存储4个字符,少于4个字符有几个字符存储几个存储字节数 = 数据值的字节和 + 1字节/2字节(长度标识),长度标识位表示的是字节数。大于255字节后使用两字节,是因为按照可能的数据大小,分为0 - 255(2^8)256 - 65535(2^16),刚好对应1字节2字节,长度标识是根据最大可能存储的字节数来决定的,比如VARCHAR(100),字符集为UTF8那么每个字符为3个字节,可能的字节数为300大于了255长度标识则为2字节
  • CHAR(4),最多存储4个字符,不足4个尾部用空格填满。存储字节数 = 数据值的字节和 + 补位空格数
  • 可空列标识位,在COMPACT、DYNAMIC行格式下,行大小除了数据列长度,还包括可空列标识,即NULL标识位。这个标识位不是放在每列,而是每行共享。假设一张表中存在N个可空字段,NULL标识位需要⌈ N / 8 ⌉ (向上取整)个字节。此时整行可用于数据存储的空间只有65535 − ⌈ N / 8 ⌉ 个字节

在这里插入图片描述

参考了大佬的博文
https://learn.blog.csdn.net/article/details/103341778

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以帮你回答这个问题。以下是实现该功能的步骤: 1. 在 MySQL 数据库创建一个名为 stuMis 的数据库。 2. 在 stuMis 数据库创建一个名为 student 的表,表结构为: ``` CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `sno` varchar(5) NOT NULL, `sname` varchar(20) NOT NULL, `ssex` varchar(3) DEFAULT NULL, `sage` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `sno` (`sno`) ); ``` 3. 向 student 表插入若干条记录,其包含你自己的记录。 ``` INSERT INTO `student` (`sno`, `sname`, `ssex`, `sage`) VALUES ('001', '张三', '男', 20), ('002', '李四', '女', 19), ('003', '王五', '男', 21), ('004', '赵六', '女', 20), ('005', '钱七', '男', 18), ('006', '自己的学号', '自己的姓名', '自己的性别', '自己的年龄'); ``` 4. 编写 Java 程序连接数据库,并查询 student 表的数据。 ``` import java.sql.*; public class Test { public static void main(String[] args) { // 数据库连接参数 String url = "jdbc:mysql://localhost:3306/stuMis?useUnicode=true&characterEncoding=utf-8&useSSL=false"; String username = "root"; String password = "123456"; Connection conn = null; Statement stmt = null; ResultSet rs = null; try { // 加载数据库驱动 Class.forName("com.mysql.jdbc.Driver"); // 获取数据库连接 conn = DriverManager.getConnection(url, username, password); // 创建 Statement 对象 stmt = conn.createStatement(); // 执行 SQL 查询语句 String sql = "SELECT * FROM student"; rs = stmt.executeQuery(sql); // 输出查询结果 while (rs.next()) { int id = rs.getInt("id"); String sno = rs.getString("sno"); String sname = rs.getString("sname"); String ssex = rs.getString("ssex"); int sage = rs.getInt("sage"); System.out.println(id + "\t" + sno + "\t" + sname + "\t" + ssex + "\t" + sage); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); } finally { // 释放资源 try { if (rs != null) { rs.close(); } if (stmt != null) { stmt.close(); } if (conn != null) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } } } ``` 注意,需要先导入 MySQL 的 JDBC 驱动包。执行该程序后,控制台会输出 student 表的所有数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值