MySQL中的数据类型及一些应用场景

news2024/11/25 8:21:29

1.6. 数据类型

MySQL的数据分为以下几个大类:
1. String Types 字符串类型
2. Numeric Types 数字类型
3. Date and Time Types 日期和时间类型
4. Blog Types 存放二进制的数据类型
5. Spatial Types 存放地理数据的类型

1.6.1. 字符串类型

最常用的两个字符串类型:

  1. CHAR () 固定长度(0-255)的字符串,默认长度是1,如果写入的字符串长度小于指定的长度,多余部分会补空格,读取时会删掉多余空格。
  2. VARCHAR () 可变长度字符串,按照实际存放的数据计算长度,在存储长度不确定的字符串数据时非常有用,可以节省存储空间。

VARCHAR最前面的1个或2个字节会存储实际字符串内容的长度,值少于 255 个字节,则长度前缀为 1 个字节,否则为 2 个字节。也就是说VARCHAR 最多长度为 65535 个字节。超出部分如果是空格会截断,不是空格会报错。

储存较大文本的两个类型

  1. MEDIUMTEXT 最大储存16MB(约16百万的英文字符),适合储存JSON对象,CS视图字符串,中短长度的书籍
  2. LONGTEXT 最大储存4GB,适合储存书籍和以年记的日志。

还有两个用的少一些的

  1. TINYTEXT 最大储存 255 Bytes
  2. TEXT 最大储存 64KB,最大储存长度和 VARCHAR 一样,但最好用 VARCHAR,因为 VARCHAR 可以使用索引。
  3. 所有这些字符串类型都支持国际字符,其中:
  • 英文字符占1个字节
  • 欧洲和中东语言字符占2个字节
  • 像中日这样的亚洲语言的字符占3个字节

所以,如果一列数据的类型为 CHAR(10),MySQL会预留30字节给那一列的值.

1.6.2. 整数类型

MySQL里共有5种常用的整数类型,它们的区别在于占用的空间和能记录的数字范围

整数类型

占用储存

记录的数字范围

TINYINT

1B

[-128,127]

SMALLINT

2B

[-32K,32K]

MEDIUMINT

3B

[-8M,8M]

INT

4B

[-2B,2B]

BIGINT

8B

[-9Z,9Z]

属性1. 不带符号 UNSIGNED

这些整数可以选择不带符号,加上 UNSIGNED 则只储存非负数。
如最常用的 UNSIGNED TINYINT,占用空间和 TINYINT 一样也是1B,但表示的数字范围不是 [-128-127] 而是 [0-255],适合储存像年龄这样的数据,可以防止意外输入负数。

最佳实践

使用能满足你需求的最小整数类型,如储存人的年龄用 UNSIGNED TINYINT 就足够了,至少可见的未来内没人能活过255岁,因为数据需要在磁盘和内存间传输,虽然不同类型间只有几个字节的差异,但数据量大了以后对空间和查询效率的影响就很大了,所以在数据量较大时,有意识地分配每一字节,保持数据最小化是很有必要的。

1.6.3. 定点数类型和浮点数类型

Fixedpoint Types 定点数类型

DECIMAL(最大数字位数,小数点后位数) ;
DECIMAL(9, 2) => 1234567.89 最多9位,小数点后两位,整数部分最多7位

DECIMAL 还有几个别名:DEC / NUMERIC / FIXED,最好就使用 DECIMAL 以保持一致性,其它几个混个眼熟

Floatingpoint Types 浮点数类型

进行科学计算,要计算特别大或特别小的数时,会用到浮点数类型,浮点数不是精确值而是近似值,所以它能表示更大范围数值。
具体有两个类型:

    • FLOAT 浮点数类型,占用4B
    • DOUBLE 双精度浮点数,占用8B

如果需要记录精确的数字,比如货币金额,用 DECIMAL 类型。
如果要进行科学计算,要处理很大或很小的数据,而且精确值不重要的话,就用 FLOAT 或 DOUBLE

1.6.4. 布尔类型

MySQL里有个数据类型叫 BOOL / BOOLEAN,储存 是/否 型数据,用布尔值来表示真或假,适用于存储仅具有两种状态的数据。

案例

UPDATE posts 
SET is_published = TRUE / FALSE
或
SET is_published = 1 / 0

注意:布尔值其实本质上就是 微整数 TINYINT 的另一种表现形式,TRUE / FALSE 实质上就是 1 / 0。

1.6.5. 枚举和集合类型

需要某个字段从固定的值中取值,可以用到 ENUM() 和 SET() 类型,前者是取一个值,后者是取多个值。

ENUM():从固定一系列值中取一个值

案例

希望 sql_store.products(产品表)里多一个size(尺码)字段,取值为 small/medium/large 中的一个,打开产品表的设计模式,添加size列,数据类型设置为 ENUM('small','medium','large'),产品表会增加一个尺码列,可将其中的值设为small/medium/large(大小写无所谓),但若设为其他值会报错。

SET():ENUM类似,区别是,SET是从固定一系列值中取多个值

注意:知道就行,最好不要用这两个数据类型,问题很多:

1. 修改可选的值(如想增加一个'extra large')会重建整个表,耗费资源
2. 想查询可选值的列表或者想用可选值当作一个下拉列表都会比较麻烦
3. 难以在其它表里复用,其它地方要用只有重建相同的列,之后想修改就要多处修改,又会很麻烦

1.6.6. 日期和时间类型

MySQL 有5种储存日期事件的类型:
1. DATE 有日期没时间
2. TIME 有时间没日期
3. DATETIME 包含日期和时间
4. TIMESTAMP 时间戳,常用来记录一行数据的的插入或最后更新时间

5. YEAR 只存放年份

最后两个的区别是:

    • TIMESTAMP 占4B,最晚记录2038年,被称为“2038年问题”
    • DATETIME 占8B,如果要储存超过2038年的日期时间,就要用 DATETIME

MySQL 提供了许多有用的日期函数。以下列出了常用的日期函数:

  • NOW(): 获取当前日期和时间
  • CURDATE(): 获取当前日期
  • DATE(): 获取日期部分
  • DATE_FORMAT(): 格式化输出日期
  • DATEDIFF(): 计算两个日期之间的天数
  • DATE_ADD(): 在给定日期上增加给定的时间间隔
  • DATE_SUB(): 在给定日期上减少给定的时间间隔
  • DAY(): 返回日期中天
  • MONTH(): 返回月份
  • QUARTER(): 返回季节
  • YEAR(): 返回年份
  • WEEK(): 函数返回给定日期是一年周的第几周
  • WEEKDAY(): 函数返回工作日索引
  • WEEKOFYEAR(): 函数返回日历周

1.6.7. 二进制大对象类型

用 Blob 类型来储存大的二进制数据,包括PDF,图像,视频等等几乎所有的二进制的文件,具体来说,MySQL里共有4种 Blob 类型,它们的区别在于可储存的最大文件大小:

占用储存

最大可储存

TINYBOLB

255B

BLOB

65KB

MEDIUM BLOB

16MB

LONG BLOB

4GB

注意

通常应该将二进制文件存放在数据库之外,关系型数据库是设计来专门处理结构化关系型数据而非二进制文件。如果将文件储存在数据库内,会有如下问题:

  1. 数据库的大小将迅速增长
  2. 备份会很慢
  3. 性能问题,因为从数据库中读取图片永远比直接从文件系统读取慢
  4. 需要额外的读写图像的代码

1.6.8. JSON类型

背景:关于JSON

  • MySQL可以储存 JSON 文件,JSON 是 JavaScript Object Notation(JavaScript 对象标记法)的简称
  • JSON 是一种在互联网上储存和传播数据的简便格式。
  • JSON 在网络和移动应用中被大量使用,多数时候手机应用向后端传输数据都是使用 JSON 格式

语法结构:

{
    "key1": value1,
    "key2": value2,
    ……
}
  • JSON 用大括号{}表示一个对象,里面有多对键值对
  • 键 key 必须用引号包裹
  • 值 value 可以是数值,布尔值,数组,文本, 甚至另一个对象(形成嵌套 JSON 对象)

1.6.9. 关于数据类型的一些业务场景

1.6.9.1. 整型的取值范围

例如,在存储销售订单时,为了避免存入负数会选择使用unsigned 属性,当我们想要计算每个月销售数量变化时,一个小的数量减去大的数量时会产生负数,MySQL会报错提示计算结果超出范围,解决这个问题需要对数据库参数 sql_mode 设置为 NO_UNSIGNED_SUBTRACTION,允许相减的结果为 signed,这样才能得到最终想要的结果。

1.6.9.2. 自增主键使用什么类型更好?

整型类型在业务中最常见的就是统计物品的数量,还有一个常用的就是作为表的主键,通过auto_increment属性能够实现自增功能

推荐使用BIGINT作为主键而不是INT,INT 的范围最大在 42 亿的级别,在正式业务中例如一些流水表、日志表,每天 1000W 数据量,420 天后,INT 类型的上限即可达到,当INT达到上限后再进行自增插入就会报重复错误。

另一个问题就是MySQL 8.0 版本前,自增不持久化,自增值可能会存在回溯问题。例如,删除表中自增为 3 的一条记录后,下一个自增值依然为 4(AUTO_INCREMENT=4),自增并不会进行回溯。但若这时数据库发生重启,数据库启动后,自增起始值将再次变为 3,即自增值发生回溯。解决办法就是升级数据库版本,另一个就是不在核心业务表使用自增数据类型做主键。

1.6.9.3. 关于资金的字段使用什么类型存储?

在设计账户余额,零钱等资金字段时,大部分使用的时是DECIMAL 类型,因为能精确到分。在海量互联网业务的设计标准中,并不推荐用 DECIMAL 类型,而是更推荐将 DECIMAL 转化为 整型类型。也就是以分为单位进行存储,例如,1元在数据库中用整型100存储。

使用DECIMAL作为取值范围,金额字段定义为 DECIMAL(8,2) ,只能表示存储最大值为 999999.99,百万级的资金存储。一个统计局的 GDP 金额字段则可能达到数十万亿级别,用类型 DECIMAL 定义,不好统一。

DECIMAL 是通过二进制实现的一种编码方式,计算效率远不如整型高效。使用BIGINT即使用分为单位存储,也能存储千兆(1兆 = 1万亿)级别的金额。而且所有金额相关字段都是定长字段,占用 8 个字节,存储高效。

使用定长存储的好处:

例如,当前数据库记录存储的长度不一致,当记录4更新后数据长度增加了,原先的空间无法容纳更新后的记录了,会将记录4删除再寻找新的空间给记录4使用。原记录4的空间变成碎片空间,无法继续使用,除非人为地进行表空间的碎片整理。

小数点怎么表示:

使用 BIG INT 存储金额字段的时候金额是存储的整数,小数点完全可以由前端进行处理并展示。

1.6.9.4. 用户性别,状态等有限定值的字段

当使用INT型存储,存在两个问题:表达不清晰和容易出现脏数据。MySQL 8.0.16 版本开始,数据库原生提供 CHECK 约束功能,可以方便地进行有限状态列类型的设计。

 CONSTRAINT `user_chk_1` CHECK (((`sex` = _utf8mb4'M') or (`sex` = _utf8mb4'F')))

这样就约束了性别,确保在插入或更新数据时,sex 列的值只能是 'M'(男性)或 'F'(女性)。

1.6.9.5. 账户密码的存储

在数据库表中直接存储密码容易造成用户信息泄露的问题,只使用MD5加密是不够的。在存储密码还需要加盐(salt),每个公司的盐值是不同的,盐值被泄露密码也容易被破解。最好使用动态盐 + 非固定加密算法。格式如下:

$salt$cryption_algorithm$value

  • $salt:表示动态盐,每次用户注册时业务产生不同的盐值,并存储在数据库中。若做得再精细一点,可以动态盐值 + 用户注册日期合并为一个更为动态的盐值。
  • $cryption_algorithm:表示加密的算法,如 v1 表示 MD5 加密算法,v2 表示 AES256 加密算法,v3 表示 AES512 加密算法等。
  • $value:表示加密后的字符串。
1.6.9.6. 业务中DATETIME vs TIMESTAMP怎么选?

更建议使用DATETIME。如果要将时间精确到毫秒TIMESTAMP 要 7 个字节,和 DATETIME 8 字节差不太多,而且距离2038年时间也很近了,DATETIME的时区问题可以由前端或者服务转化一次。

如果使用 TIMESTAMP 必须显式的设置时区,不要使用系统时间,使用默认的操作系统时区,则每次通过时区计算时间时,要调用操作系统底层系统函数 __tz_convert(),而这个函数需要额外的加锁操作,以确保这时操作系统时区没有修改。所以,当大规模并发访问时,由于热点资源竞争,会产生性能抖动。

SET time_zone = 'Asia/Shanghai';

最好在每张业务核心表都增加一个 DATETIME 类型的 last_modify_date 字段,并设置修改自动更新机制,能够知道每个用户记录最近一次更新的时间,方便后续要进行的操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1632601.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Odoo:世界排名第一的免费开源设备资产(EAM)管理系统介绍

本文节选自Odoo亚太金牌服务机构【开源智造】所编写的《Odoo行业应用解决方案白皮书》如需获取完整的知识内容,请至开源智造官网免费获取。感谢网友一键三连:点赞、转发、收藏,您的支持是我们最大的前进动力! 概述 实施全面的维护…

免费语音转文字:自建Whisper,贝锐花生壳3步远程访问

Whisper是OpenAI开发的自动语音识别系统(语音转文字)。 OpenAI称其英文语音辨识能力已达到人类水准,且支持其它98中语言的自动语音辨识,Whisper神经网络模型被训练来运行语音辨识与翻译任务。 此外,与其他需要联网运行…

AI 工具合集

以下工具来源于互联网,可能会失效,请参考使用 网红工具 名称链接说明GPT-4https://chat.openai.com/ 需要梯子,需要付费。功能最强大的聊天机 器人。 文心一言https://yiyan.baidu.com/welcome 国内版 GPT,需要申请账号。回答问…

React的状态管理useState

基础使用 useState 是一个 React Hook(函数),它允许我们向组件添加一个状态变量, 从而控制影响组件的渲染结果和普通JS变量不同的是,状态变量一旦发生变化组件的视图UI也会跟着变化(数据驱动视图) useState…

C++:常函数

在C中,常函数(const member functions)是指在类的成员函数声明和定义中使用 const 关键字修饰的函数。常函数的存在主要是为了在类的实例上提供一种保证:该函数不会修改类的成员变量。 在类的成员函数声明中,如果函数…

2024年CMS市场的份额趋势和使用统计

目前市面上有超过一半的网站都是使用CMS来搭建的,据不完全统计,现在大概有900多种CDM可供选择,以下是最常见的CMS的市场份额和使用率信息: 除了WordPress以外,Shopify和Wix也是比较流行的内容管理系统,尤其…

面试集中营—ElasticSearch架构篇

一、为什么用ElasticSearch? 1、支持多种数据类型。它可以处理非结构化、数值和地理信息等多种类型的数据; 2、简单的RESTful API。ES提供了一个简单易用的RESTful API,使得它可以从任何编程语言中调用,降低了学习的曲线。 3、近实…

HUST华科校园网自动登录

HUST校园网开机自动登录,后台保活 校园网虽然有无感认证,但是每次还得弹出网页,再点击一次连接,还是挺麻烦的。而且对于一部分开机自启的联网app来说,每次开机后无网络可能导致某些应用功能出bug或者其他异常行为。因此…

笃行致远,“易”往无前 | 易保全成立10周年啦

日月其迈,岁律更新。2024年4月28日,易保全迎来了10周岁生日。10年磨一剑,易保全创立至今,始终坚定自己的初心和使命,在时代的激流勇进中,以电子数据保全机构的身份与中国区块链共成长。 “创”说十年&…

Blender常见操作

1.局部视图:Local View,也可称作Solo模式,按快捷键 “/”进入,在按退出,只显示选中的物体(可多选),方便编辑 2.物体合并:Ctrl J 其中,当选中多个物体时&am…

CSS border边框(理解网页边框制作)

目录 一、border边框介绍 1.概念 2.特点 3.功能 4.应用 二、border边框用法 1.border边框属性 2.边框样式 3.边框宽度 4.边框颜色 5.边框-单独设置各边 6.边框-简写属性 三、border边框属性 四、border边框实例 1.创建带有阴影效果的边框: 2. 创建一个类似标…

如何使用SOCKS5代理?

SOCKS5 是一个代理协议,在使用TCP/IP协议通讯的前端机器和服务器机器之间扮演一个中介角色,使得内部网中的前端机器变得能够访问Internet网中的服务器,或者使通讯更加安全。那么,SOCKS5代理该如何使用呢? 首先需要获取…

Aiseesoft Blu-ray Player for Mac:蓝光播放器

Aiseesoft Blu-ray Player for Mac是一款功能强大且易于使用的蓝光播放器,专为Mac用户打造。它以其卓越的性能和简洁的操作界面,为用户带来了全新的高清蓝光播放体验。 Aiseesoft Blu-ray Player for Mac v6.6.50激活版下载 这款软件支持播放任何高质量的…

2024年4月中国数据库排行榜:OceanBase再度登顶,KingBase稳步上升进前五

春风劲吹,迎来了2024年4月中国流行度排行榜。纵观本月榜单,各家数据库产品你追我赶,名次呈现微妙变动,它们正以不可忽视的力量,推动着中国乃至全球的数据管理革新。在这春意盎然的四月,让我们继续关注这些数…

命令执行。

命令执行 在该项目的readme中,描述了怎么去调用的flink 通过java原生的runtime来调用flink,下一步就是去看看具体的调用过程了,是否存在可控的参数 找到具体提交命令的类方法CommandRpcClinetAdapterImpl#submitJob() 这里要确定command&am…

【ESP32S3】使用 Flash 下载工具完成 Flash 加密功能

此篇文档记录通过 Flash 下载工具 完成 Flash 加密 功能的实现,此文档不启用 Flash 加密方案的 NVS 加密。 Flash 加密启动的验证代码:esp-idf/components/bootloader_support/src/flash_encrypt.c Flash 加密测试例程:esp-idf/examples/sec…

Qt绘图与图形视图之自定义图元实现拖拽、拉伸、旋转功能

往期回顾 Qt绘图与图形视图之移动鼠标手动绘制任意多边形的简单介绍-CSDN博客 Qt绘图与图形视图之场景、视图架构的简单介绍-CSDN博客 Qt绘图与图形视图之基本图元绘制的简单介绍-CSDN博客 Qt绘图与图形视图之自定义图元实现拖拽、拉伸、旋转功能 一、最终效果 实现对自定义图…

Agent AI智能体在未来,一定与你我密不可分

随着Agent AI智能体的逐渐成熟,人工智能应用的不断深入与拓展,相信在不久的将来,他与你我的生活一定是密不可分的。 目录 ​编辑 1 Agent AI智能体是什么? 2 Agent AI在语言处理方面的能力 2.1 情感分析示例 2.2 文本分类任…

Tetra Pak利乐中试工厂仿真 - 工艺开发、配方开发和无菌灌装的试验

此模型是基于速率的模型,使用Rate模块库中的离散速率模块和Item模块库中的离散事件模块。速率模块库位于ExtendSim Pro中。 利乐中试工厂(得克萨斯州丹顿)进行工艺开发、配方开发和无菌灌装的试验。它还对新的加工和灌装设备进行内部测试。该…

Colab用例与Gemma快速上手指南:如何在Colab和Kaggle上有效地运用Gemma模型进行机器学习任务

🐯 Colab用例与Gemma快速上手指南 🚀 文章目录 🐯 Colab用例与Gemma快速上手指南 🚀摘要引言正文📝 **基础使用:Gemma快速上手**环境设置和模型加载安装必要的库加载Gemma模型 推理示例 🛠 **Ge…