• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase
您的位置:首页 > 数据库 >Mysql > MySQL数据类型和存储机制详解

MySQL数据类型和存储机制详解

作者:匿名 字体:[增加 减小] 来源:互联网 时间:2018-12-05

匿名通过本文主要向大家介绍了MariaDB,MySQL,详解等相关知识,希望本文的分享对您有所帮助
CREATE TABLE test3(id INT(2) ZEROFILL NOT NULL);INSERT INTO test3 VALUES(1),(2),(11),(111);SELECT id FROM test3; +-----+ | id | +-----+ | 01 | | 02 | | 11 | | 111 | +-----+ 4 rows in set (0.00 sec)

唯一需要注意的是,显示宽度仅仅影响显示效果,不影响存储、比较、长度计算等等任何操作。

1.2.2 字符类型的存储方式

此处主要说明char和varchar的存储方式以及区别。

char类型是常被称为"定长字符串类型",它严格限定空间长度,但它限定的是字符数,而非字节数,但以前老版本中限定的是字节数。因此char(M)严格存储M个字符,不足部分使用空格补齐,超出M个字符的部分直接截断。

由于char类型有"短了就使用空格补足"的能力,因此为了体现数据的真实性,在从地址空间中检索数据时将自动删除尾随的空格部分。这正是char的一个特殊性,即使是我们手动存储的尾随空格也会被认为是自动补足的,于是在检索时被删除。也就是说在where语句中name='gaoxiaofang '和name='gaoxiaofang'的结果是一样的。

例如:

create table test2(a char(4) charset utf8mb4);insert into test2 values('恭喜你'),('恭喜你成功晋级'),('hello'),('he    ');select concat(a,'x') from test2;+---------------+| concat(a,'x') |
+---------------+| 恭喜你x       |
| 恭喜你成x     |
| hellx         |
| hex           |
+---------------+4 rows in set

从上面的结果可以看到,char(4)只能存储4个字符,并删除尾随空格。

varchar常被称为"变长字符串类型",它存储数据时使用额外的字节的bit位来标记某个字节是否存储了数据。每存储一个字节(不是字符)占用一个bit位进行记录,因此一个额外的字节可以标记共256个字节,2个额外的字节可以标记65536个字节。但MySQL/mariadb限制了最大能存储65536个字节。这表示,如果是单字节的字符,它最多能存储65536个字符,如果是多字节字符,如UTF8的每个字符占用3个字节,它最多能存储65536/3=21845个utf8字符。

因此,varchar(M)存储时除了真实数据占用空间长度,还要额外计算1或2个字节的Bit位长度,即对于单字节字符实际占用的空间为M+1或M+2个字节,对于多字节字符(如3字节)实际占用的空间为M*3+1或M*3+2个字节。

由于varchar存储时需要采用额外的bit位记录每一个字节,短了的数据不会自动使用补齐,因此显式存储的尾随空格也会被存储并在Bit位上进行标记,也就是说不会删除尾随空格。

和char(M)一样,当指定varchar(2)时,只能存储两个字节的字符,如果超出了,则切断。

关于char、varchar以及text字符串类型,它们在比较时不会考虑尾随空格,但做like匹配或正则匹配时会考虑空格,因为匹配时字符是精确的。例如:

create table test4(a char(4),b varchar(5));insert into test4 values('ab ','ab   ');select a='ab   ',b='ab      ',a=b from test4;+-----------+--------------+-----+| a='ab   ' | b='ab      ' | a=b |
+-----------+--------------+-----+|         1 |            1 |   1 |
+-----------+--------------+-----+1 row in setselect a like 'ab      ' from test4;+-------------------+| a like 'ab      ' |
+-------------------+|                 0 |
+-------------------+1 row in set

最后需要说明的是,数值在存储(或调入内存)时,以数值型方式存储比字符型或日期时间类型更节省空间。因为整数值存储时是直接通过bit计算数值的,0-255之间的任意整数都只占一个字节,256-65535之间的任意整数都占2个字节,而占用4个字节时便可以代表几十亿个整数之间的任意一个,这显然比字符型存储时每个字符占用一个字节节省空间的多。例如值"100"存储为字符型时占用三个字节,而存储为数值型将只占用一个字节。因此数据库默认将不使用引号包围的值当作数值型,如果明确要存储为字符型或日期时间型则应该使用引号包围以避免歧义。

1.2.3 日期时间型的存储方式

日期时间性数据存储时需要使用引号包围,避免和数值类型的数据产生歧义。关于日期时间的输入方式是非常宽松的,以下几种方式都是被允许的:任意允许的分隔符,建议使用4位的年份。

20110101
2011-01-01 18:40:20
2011/01/01 18-40-20
20110101184020

1.2.4 ENUM数据类型

ENUM数据类型是枚举型。定义方式为ENUM('value1','value2','value3',...),在向该类型的字段中插入数据时只能插入value中的某一个或NULL,插入其他值或空(即'')时都将截断为空数据。存储时会忽略大小写(将转换为ENUM中的字符),且会截断尾随空格。

mysql> create table test6(id int auto_increment primary key,name char(20),gender enum('Mail','f'));
mysql> insert into test6(name,gender) values('malongshuai','Mail'),('gaoxiaofang','F'),('wugui','x'),('tuner',null),('woniu','');
Query OK, 5 rows affected
Records: 5  Duplicates: 0  Warnings: 2mysql> show warnings;
+---------+------+---------------------------------------------+
| Level   | Code | Message                                     |
+---------+------+---------------------------------------------+
| Warning | 1265 | Data truncated for column 'gender' at row 3 |
| Warning | 1265 | Data truncated for column 'gender' at row 5 |
+---------+------+---------------------------------------------+2 rows in setmysql> select * from test6;
+----+-------------+--------+
| id | name        | gender |
+----+-------------+--------+
|  1 | malongshuai | Mail   |
|  2 | gaoxiaofang | f      |
|  3 | wugui       |        |
|  4 | tuner       | NULL   |
|  5 | woniu       |        |
+----+-------------+--------+5 rows in set

ENUM类型的数据存储时是通过index数值进行存储的,相比于字符串类型,它只需要1或2个字节进行存储即可。理论上,当value的数量少于256个时只需一个字节,超出256个但少于65536个时使用2个字节存储。MySQL/MariaDB限制最多只能存储65536个value。当然,这是理论上的限制,实际存储时要考虑的因素有很多,例如NULL也会占用bit位,所以实际存储时可能250个value就需要2个字节。

ENUM的每个value都通过index号码进行编号,无论是检索还是操作该字段时都会通过index的值来操作。value1的index=1,value2的index=2,依次类推。但需要注意有两个特殊的index值:NULL值的index=NULL,空数据的index=0。

例如ENUM('a','b','c'),向该字段依次插入'','b','a','c',NULL,'xxx'时,由于第一个和最后一个都会截断为空数据,所以它们的index为0,插入的NULL的index为NULL,插入的'b','a','c'的index值分别为2,1,3。所以index号码和值的对应关系为:

indexvalue
NULLNULL
0''
0''
1'a'
2'b'
3'c'

使用ENUM的index进行数据检索:

mysql> select * from test6 where gender=2;
+----+-------------+--------+
| id | name        | gender |
+----+-------------+--------+
|  2 | gaoxiaofang | f      |
+----+-------------+--------+1 row in set

特别建议,不要使用ENUM存储数值,因为无论是排序还是检索或其他操作,都是根据index值作为条件的,这很容易产生误解。例如,下面是用ENUM存储两个数值,然后进行检索和排序操作。

mysql> create table test7(id enum('3','1','2'));
mysql> insert into test7 values('1'),('2'),('3');# 检索时id=2,但结果查出来却为1,因为id=2的2是enum的index值,在
  


 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Mysql 开启Federated引擎的方法
  • MySQL数据类型和存储机制详解
  • MariaDB体验之数据库安装的图文详解
  • 在Linux下修改编码的实例教程
  • 分享使用Mariadb时碰到的两个问题
  • 详细介绍如何在Linux中重置MySQL或者MariaDB的root密码(图)
  • mysql在Centos7下重新启动MariaDB篇详解
  • Mysql的基础使用之MariaDB安装方法详解_MySQL
  • MariaDB(MySQL)创建、删除、选择及数据类型使用详解_MySQL
  • MariaDB(Mysql分支)my.cnf配置文件中文注释版

相关文章

  • 2017-05-11MySQL字段自增自减的SQL语句示例介绍
  • 2018-12-05ORACLE应用经验(1)
  • 2018-12-05MySQL基础教程6 — 函数之控制流程函数
  • 2018-12-05mssql存储过程表名和字段名为变量的实现方法
  • 2018-12-05SQL优化:很简单的一篇提高SQL性能的文章!
  • 2018-12-05MySQL 5.7 学习心得之安全相关特性_MySQL
  • 2017-05-11MySQL创建用户与授权及撤销用户权限方法
  • 2018-12-05总结图形化实例用法
  • 2018-12-05mysql 协议的server状态标识的代码详情
  • 2018-12-05详细介绍Win2008 R2 mysql5.5zip格式mysql安装与配置的图文代码分享

文章分类

  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase

最近更新的内容

    • oracle客户端plsql安装
    • Mysql原先内容不改变并在后面增加内容的sql语句详解
    • MySQL事务、锁以及应用(一)
    • MSSQL数据库迁移之用户名问题
    • oracle下巧用bulk collect实现cursor批量fetch的sql语句
    • mysql查询今天,昨天,近7天,近30天,本月,上一月数据方法
    • mysql数据库导入中文乱码解决问题方案
    • MySQL压缩版安装配置的详情介绍
    • MySQL5.7如何实现双主同步部分表的过程介绍
    • mysql-为什么我项目本地和服务器上,一个数据库的sleep会被释放,一个不会

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有