iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >【MySQL】数据类型
  • 120
分享到

【MySQL】数据类型

mysql 2023-09-24 10:09:57 120人浏览 八月长安
摘要

前言 在前一篇文章中,我们介绍了数据库的基本操作,而在插入表时涉及了许多关于表的数据类型,接下来就一起来学习一下Mysql常见的一些文件类型吧。 整形类型 数据类型字节最小值最大值TINYINT1-1

前言

在前一篇文章中,我们介绍了数据库的基本操作,而在插入表时涉及了许多关于表的数据类型,接下来就一起来学习一下Mysql常见的一些文件类型吧。

整形类型

数据类型字节最小值最大值
TINYINT1-128127
UNSIGNED TINYINT10255
SMALLINT2-3276832767
UNSIGNED SMALLINT2065535
MEDIUMINT3-83886088388607
UNSIGNED MEDIUMINT3016777215
INT4-21474836482147483647
UNSIGNED INT404294967295

可以看到,有非常多的整型可以选择,根据其占有的字节数,可以表示更大的数值。在int之上还有更大的 bigint 占 8 个字节。需要我们通过具体的情况,对数据类型进行选择,进而达到节约内存消耗的作用。

数值越界测试

接下来,我们针对数据类型进行一些插入的测试,这里以 tinyint 为例(极值较小,比较好操作)。

mysql> create table t1(    -> id tinyint    -> );Query OK, 0 rows affected (0.05 sec)mysql> desc t1;+-------+------------+------+-----+---------+-------+| Field | Type       | Null | Key | Default | Extra |+-------+------------+------+-----+---------+-------+| id    | tinyint(4) | YES  |     | NULL    |       |+-------+------------+------+-----+---------+-------+1 row in set (0.00 sec)

如上,我们创建了一个表并设定了一个 tinyint 类型的列,接下来我们尝试往表中插入数据。

mysql> insert into t1 values(100);Query OK, 1 row affected (0.01 sec)mysql> insert into t1 values(-100);Query OK, 1 row affected (0.00 sec)mysql> insert into t1 values(127);Query OK, 1 row affected (0.00 sec)mysql> insert into t1 values(128);ERROR 1264 (22003): Out of range value for column 'id' at row 1mysql> select * from t1;+------+| id   |+------+|  100 || -100 ||  127 |+------+3 rows in set (0.00 sec)

可以看到,最后一个数据插入前,我们都成功地将数据插入了表格,通过上面那个数据类型的范围表中,我们可以知道,tinyint 的最大值只有127,若我们插入128便超过了它能够承受的范围便无法插入。

若我们将列属性转换成无符号,便能够插入128这个数字。

mysql> create table t2 (    -> id tinyint unsigned     -> );Query OK, 0 rows affected (0.02 sec)mysql> insert into t2 values(128);Query OK, 1 row affected (0.00 sec)mysql> select * from t2;+------+| id   |+------+|  128 |+------+1 row in set (0.00 sec)

总结

  • 每个数据类型都有其对应的数据范围,无法插入超出数据范围的数。

  • 对于mysql来说一般会直接拦截我们的非法操作,换言之,若我们成功插入了数据,那么这个操作一定是合法的。

  • 一般而言,数据类型本身也是Mysql的约束,为的是倒逼程序员进行正确的插入。

  • 尽量不适用unsigned,放在使用场景中,一般原类型可能存放不下的数据,再加上无符号大概率也是存放不下的,因此不如在一开始就使用更大的数据类型进行存储。

Bit类型

Bit类型的本质就是一种位图结构,其位数为1~64(默认为1)。

bit(位数)

于是我们创建一个表,其中列的数据类型分别为 int 和 8 位的bit。

mysql> create table t1 (    -> id int,    -> b bit(8)    -> );Query OK, 0 rows affected (0.02 sec)mysql> desc t1;+-------+---------+------+-----+---------+-------+| Field | Type    | Null | Key | Default | Extra |+-------+---------+------+-----+---------+-------+| id    | int(11) | YES  |     | NULL    |       || b     | bit(8)  | YES  |     | NULL    |       |+-------+---------+------+-----+---------+-------+2 rows in set (0.00 sec)

现在我们开始往其中插入数据。

mysql> insert into t1 value(1,10);Query OK, 1 row affected (0.00 sec)mysql> insert into t1 value(2,66);Query OK, 1 row affected (0.00 sec)mysql> insert into t1 value(3,67);Query OK, 1 row affected (0.00 sec)

可以看到,虽然插入的是 66 和 67,但实际上打印出来的却是 B 和 C,我们便可以推测,打印 bit 类型的数据时默认情况下是使用 ASCII 码的匹配模式进行打印的。

mysql> select * from t1;+------+------+| id   | b    |+------+------+|    1 |     ||    2 | B    ||    3 | C    |+------+------+3 rows in set (0.01 sec)

若我们想要将 bit 类型的数据以十六进制的形式进行打印,只需在select时指明要转换的进制即可。

mysql> select id,hex(b) from t1;+------+--------+| id   | hex(b) |+------+--------+|    1 | A      ||    2 | 42     ||    3 | 43     |+------+--------+3 rows in set (0.00 sec)

若插入的数据超过了该列能承受的范围,MySQL同样会阻止这个行为。

mysql> insert into t1 value(6,256);ERROR 1406 (22001): Data too long for column 'b' at row 1

浮点数类型

有了整型自然也会有浮点型的数据类型,其中当属这两个数据类型最为常用。

float

定义浮点数类型时需要进行如下操作,其中 m 表示整个浮点数的显示长度,而 d 表示小数的位数。且这个数据将占用 4 个字节。

float(m,d)

例如,现在我们有一个表,其中float后面跟着的是4和2,不难得知,这个浮点数的数据范围为 -99.99~99.99。

mysql> desc t3;+-------+------------+------+-----+---------+-------+| Field | Type       | Null | Key | Default | Extra |+-------+------------+------+-----+---------+-------+| id    | int(11)    | YES  |     | NULL    |       || score | float(4,2) | YES  |     | NULL    |       |+-------+------------+------+-----+---------+-------+2 rows in set (0.00 sec)

同样,接下来尝试插入几个数据。

mysql> insert into t3 value(1,1.1);Query OK, 1 row affected (0.04 sec)mysql> insert into t3 value(2,1.115);Query OK, 1 row affected (0.01 sec)mysql> insert into t3 value(3,1.112);Query OK, 1 row affected (0.00 sec)mysql> insert into t3 value(4,99.99);Query OK, 1 row affected (0.00 sec)mysql> insert into t3 value(5,99.999);ERROR 1264 (22003): Out of range value for column 'score' at row 1

在我们平时的使用中,大概率插入的都是第一个数据这种数值,而当小数位数不足时,则会默认补0。

若插入的数据的小数位数超过了限定的长度,则会进行四舍(数据3)五入(数据2)。

例如数据四,此时刚好就是当前能存储的最大数值,此时若再进行进位的话便会出现错误(数据5)。

mysql> select * from t3;+------+-------+| id   | score |+------+-------+|    1 |  1.10 ||    2 |  1.12 ||    3 |  1.11 ||    4 | 99.99 |+------+-------+4 rows in set (0.00 sec)

若是定义成 unsigned 类型,便仅仅失去负数部分的数据。

decimal

decimal(m,d)  m最大为65默认为10,d最大值为30默认为0

decimal使用起来跟float很像但又有些区别。

我们将float和decimal放在同一个表中,插入相同的数据。

mysql> insert into t4 values(12.24141251511,12.24141251511);Query OK, 1 row affected, 1 warning (0.00 sec)mysql> select * from t4;+---------+-------------+| s1      | s2          |+---------+-------------+| 12.2414 | 12.24141252 |+---------+-------------+1 row in set (0.00 sec)

可以看到,虽然插入了同样的数据,但decimal对于精度的保存明显强于float。

因此对于小数的精度有要求时,便推荐使用decimal。

字符串类型

之前我们就已经使用过了字符串类型,而其又分成char和varchar两种字符串类型,分别是定长字符串和可变长度字符串。

在MySQL中,字符串既可以用 ’ ’ 圈定,同时也可以使用 " "。

char

char(L)   L表示能存储的字符数,最大长度可以达到255

这里的字符指的就是,表选择的字符集对应的字符,就是实实在在的符号。

若设定的大小超过了最大长度,系统则会提示我们可以换成一个更大的类型进行存储。

mysql> create table t2(str char(256));ERROR 1074 (42000): Column length too big for column 'str' (max = 255); use BLOB or TEXT instead

如下列 L 为 3 的 char,前几次无论我们插入的是字母还是汉字都能成功插入,而一旦长度超出了限制,便会报错。

mysql> insert into t1 value('a');Query OK, 1 row affected (0.01 sec)mysql> insert into t1 value('aaa');Query OK, 1 row affected (0.02 sec)mysql> insert into t1 value('我我我');Query OK, 1 row affected (0.00 sec)mysql> insert into t1 value('aaaa');ERROR 1406 (22001): Data too long for column 'str' at row 1

之所以叫做定长字符串,正因为它就像数组一样,若插入的数据的大小比申请的空间小,那么这些多出来的空间就被浪费掉了。

varchar

而 varchar 则是可变长度字符串,并非当类型长度不够时会自动变长。

varchar(L)varchar最大长度为65535个字节

而是在分配空间时只会分配足够使用的空间,L则是决定了可分配空间的上限。

具体细节就和char一样,需要注意插入字符的长度不能超过设定的L。

最大值的计算

在上面的介绍中只说了 varchar 允许的最大长度为 65535 个字节,那么 L 的最大值该怎么计算呢?

首先在空间的开头有 1~3 个字节用于记录数据的大小,极限情况下的最大可用字节为 65532 个。

接下来取决与此张表选择的字符集:

例如表使用的是 utf8,在 utf8 中一个字符的大小为 3 个字节,因此 L 最大值为 65532 / 3 = 21844 .

再大 1 的 21845 便无法容纳了,系统便建议我们换一个数据类型。

mysql> create table t1(    -> str varchar(21844)    -> );Query OK, 0 rows affected (0.03 sec)mysql> create table t2( str varchar(21845) );ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs

若使用 gbk 编码时,一个字符占 2 个字节,则 L 最大值为 65532 / 2 = 32766 .

如何选择char和varchar

  • 若数据确定长度都一样就使用char (如: 身份证)。
  • 若数据长度有变化就使用varchar (如: 姓名,地址)。
  • 定长字符串占用的磁盘空间相对浪费,但访问的效率较高,而变长反之。

日期和时间类型

date

日期类型,只包含日期,格式为 ‘yyyy-mm-dd’ ,占用三个字节。

datetime

时间日期类型,从年一直到秒,格式为 'yyyy-mm-dd HH:ii:ss ’ ,占用八个字节。

timestamp

时间戳,从1970年开始,格式与 datetime 一致, 占用四个字节。


前两种类型的数据需要程序员自己插入,而时间戳在每次更新数据时便会自动更新。

mysql> desc t2;+-------+-----------+------+-----+-------------------+-----------------------------+| Field | Type      | Null | Key | Default           | Extra                       |+-------+-----------+------+-----+-------------------+-----------------------------+| d1    | date      | YES  |     | NULL              | || d2    | datetime  | YES  |     | NULL              | || d3    | timestamp | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |+-------+-----------+------+-----+-------------------+-----------------------------+3 rows in set (0.00 sec)

如上表,我们开始往表中插入数据。

值得注意的一点是,插入时需要按类型规定的格式插入,才能被准确识别。

mysql> insert into t2(d1,d2) values('2023-9-21','2023-9-21 21:13:50');Query OK, 1 row affected (0.02 sec)mysql> select * from t2;+------------+---------------------+---------------------+| d1         | d2                  | d3                  |+------------+---------------------+---------------------+| 2023-09-21 | 2023-09-21 21:13:50 | 2023-09-21 21:13:42 |+------------+---------------------+---------------------+1 row in set (0.00 sec)

enum和set类型

enum

相信枚举类型对于学习 C/C++ 的同学而言并不陌生,该类型中的值必须是先前设定好的,一旦试图插入其他数据就会报错。

enum (选项1,选项2,...)
mysql> create table t3(    -> 科目 enum('语文','数学','英语')    -> );Query OK, 0 rows affected (0.02 sec)mysql> desc t3;+--------+----------------------------------+------+-----+---------+-------+| Field  | Type | Null | Key | Default | Extra |+--------+----------------------------------+------+-----+---------+-------+| 科目   | enum('语文','数学','英语')       | YES  |     | NULL    |       |+--------+----------------------------------+------+-----+---------+-------+1 row in set (0.01 sec)

因此,我们只能在这三个选项中选择一个插入,若出现了系统不认识的选项,便会被拦截起来。

mysql> insert into t3 values('语文');Query OK, 1 row affected (0.01 sec)mysql> insert into t3 values('数学');Query OK, 1 row affected (0.01 sec)mysql> insert into t3 values('英语');Query OK, 1 row affected (0.00 sec)mysql> insert into t3 values('体育');ERROR 1265 (01000): Data truncated for column '科目' at row 1mysql> select * from t3;+--------+| 科目   |+--------+| 语文   || 数学   || 英语   |+--------+3 rows in set (0.00 sec)

不仅如此,我们还可以根据声明的顺序使用下标(从1开始)选择选项进行插入。

mysql> insert into t3 values(1);Query OK, 1 row affected (0.01 sec)mysql> insert into t3 values(2);Query OK, 1 row affected (0.01 sec)mysql> insert into t3 values(3);Query OK, 1 row affected (0.00 sec)mysql> select * from t3;+--------+| 科目   |+--------+| 语文   || 数学   || 英语   || 语文   || 数学   || 英语   |+--------+6 rows in set (0.00 sec)

若插入时什么都不写则为 NULL,代表无,而插入 0 代表这里有东西,但是只是进行占位,没有实际意义。

set

set 表示的是一个集合,每次插入只能插入它的子集。

set(选项1,选项2...)
mysql> create table t4(    -> 爱好 set('唱','跳','rap','篮球')    -> );Query OK, 0 rows affected (0.03 sec)mysql> desc t4;+--------+---------------------------------+------+-----+---------+-------+| Field  | Type| Null | Key | Default | Extra |+--------+---------------------------------+------+-----+---------+-------+| 爱好   | set('唱','跳','rap','篮球')     | YES  |     | NULL    |       |+--------+---------------------------------+------+-----+---------+-------+1 row in set (0.00 sec)

同样,若想选择不存在的选项则会被制止。

mysql> insert into t4 values('唱,跳,篮球');Query OK, 1 row affected (0.01 sec)mysql> insert into t4 values('唱,rap,篮球');Query OK, 1 row affected (0.00 sec)mysql> insert into t4 values('唱,篮球');Query OK, 1 row affected (0.00 sec)mysql> insert into t4 values('sing,dance');ERROR 1265 (01000): Data truncated for column '爱好' at row 1mysql> select * from t4;+----------------+| 爱好           |+----------------+| 唱,跳,篮球     || 唱,rap,篮球    || 唱,篮球        |+----------------+3 rows in set (0.00 sec)

那么 set 也有像 enum 那样以数字的形式作进行插入吗?

当然有了,但是由于 set 是以子集的形式插入,自然不能直接使用下标作为依据。

而是需要先将数字转换成对应的位图,以位图的状态决定某选项选择与否。

例如 3 转换成二进制就是 0011,第一位和第二位为 1,因此下标为 1 和 2 的被选中,所以就选中了唱和跳。

mysql> insert into t4 values(3);Query OK, 1 row affected (0.00 sec)mysql> select * from t4;+---------+| 爱好    |+---------+| 唱,跳   |+---------+1 row in set (0.00 sec)

enum和set类型的查找

对于 enum 来说,直接进行严格匹配即可完成查找。

select * from 表名 where 列名 = ...;

指定列名后加上要查找的选项即可完成查找。

mysql> select * from t3 where 科目 = '语文';+--------+| 科目   |+--------+| 语文   || 语文   |+--------+2 rows in set (0.00 sec)

若是通过这个方式对set类型进行查找便只会进行严格的匹配。

mysql> select * from t4 where 爱好='跳';+--------+| 爱好   |+--------+| 跳     || 跳     |+--------+2 rows in set (0.00 sec)

哪天我们想要找爱好有跳即可的人该怎么办?

我们便可使用 find_in_set(a,b) 这个函数。

该函数会在 b 中查找是否存在 a,并返回真假。

于是我们的查找操作便可以这样写。

mysql> select * from t4 where find_in_set('跳',爱好);+-------------+| 爱好        |+-------------+| 唱,跳       || 跳          || 跳,rap      || 唱,跳,rap   || 跳          |+-------------+5 rows in set (0.00 sec)

这下只要爱好有跳的人就都被筛选出来了。

好了,今天【MySQL】数据类型 的相关内容到这里就结束了,如果这篇文章对你有用的话还请留下你的三连加关注。

来源地址:https://blog.csdn.net/Lin_Alpaca/article/details/133150958

您可能感兴趣的文档:

--结束END--

本文标题: 【MySQL】数据类型

本文链接: https://www.lsjlt.com/news/416825.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • oracle怎么查询当前用户所有的表
    要查询当前用户拥有的所有表,可以使用以下 sql 命令:select * from user_tables; 如何查询当前用户拥有的所有表 要查询当前用户拥有的所有表,可以使...
    99+
    2024-05-14
    oracle
  • oracle怎么备份表中数据
    oracle 表数据备份的方法包括:导出数据 (exp):将表数据导出到外部文件。导入数据 (imp):将导出文件中的数据导入表中。用户管理的备份 (umr):允许用户控制备份和恢复过程...
    99+
    2024-05-14
    oracle
  • oracle怎么做到数据实时备份
    oracle 实时备份通过持续保持数据库和事务日志的副本来实现数据保护,提供快速恢复。实现机制主要包括归档重做日志和 asm 卷管理系统。它最小化数据丢失、加快恢复时间、消除手动备份任务...
    99+
    2024-05-14
    oracle 数据丢失
  • oracle怎么查询所有的表空间
    要查询 oracle 中的所有表空间,可以使用 sql 语句 "select tablespace_name from dba_tablespaces",其中 dba_tabl...
    99+
    2024-05-14
    oracle
  • oracle怎么创建新用户并赋予权限设置
    答案:要创建 oracle 新用户,请执行以下步骤:以具有 create user 权限的用户身份登录;在 sql*plus 窗口中输入 create user identified ...
    99+
    2024-05-14
    oracle
  • oracle怎么建立新用户
    在 oracle 数据库中创建用户的方法:使用 sql*plus 连接数据库;使用 create user 语法创建新用户;根据用户需要授予权限;注销并重新登录以使更改生效。 如何在 ...
    99+
    2024-05-14
    oracle
  • oracle怎么创建新用户并赋予权限密码
    本教程详细介绍了如何使用 oracle 创建一个新用户并授予其权限:创建新用户并设置密码。授予对特定表的读写权限。授予创建序列的权限。根据需要授予其他权限。 如何使用 Oracle 创...
    99+
    2024-05-14
    oracle
  • oracle怎么查询时间段内的数据记录表
    在 oracle 数据库中查询指定时间段内的数据记录表,可以使用 between 操作符,用于比较日期或时间的范围。语法:select * from table_name wh...
    99+
    2024-05-14
    oracle
  • oracle怎么查看表的分区
    问题:如何查看 oracle 表的分区?步骤:查询数据字典视图 all_tab_partitions,指定表名。结果显示分区名称、上边界值和下边界值。 如何查看 Oracle 表的分区...
    99+
    2024-05-14
    oracle
  • oracle怎么导入dump文件
    要导入 dump 文件,请先停止 oracle 服务,然后使用 impdp 命令。步骤包括:停止 oracle 数据库服务。导航到 oracle 数据泵工具目录。使用 impdp 命令导...
    99+
    2024-05-14
    oracle
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作