【MySQL基礎篇】:MySQL常用數據類型的選擇邏輯與正確使用

?感謝您閱讀本篇文章,文章內容是個人學習筆記的整理,如果哪里有誤的話還請您指正噢?
? 個人主頁:余輝zmh–CSDN博客
? 文章所屬專欄:MySQL篇–CSDN博客

在這里插入圖片描述

文章目錄

  • 數據類型
    • 1.數據類型分類
    • 2.數值類型
      • int整形類型
      • bit位類型
      • float小數類型
    • 3.字符串類型
    • 4日期和時間類型
    • 5.enum和set
      • enum類型
      • set類型

數據類型

1.數據類型分類

分類數據類型說明
數值類型BIT(M)位類型。M指定位數,默認值1,范圍1-64
TINYINT [UNSIGNED]帶符號的范圍-128~127,無符號范圍0~255,默認有符號
BOOL使用0和1表示真和假
SMALLINT [UNSIGNED]帶符號范圍-2^15~2^15-1,無符號范圍0~2^16-1
INT [UNSIGNED]帶符號范圍-2<^31~2^31-1,無符號范圍0~2^32-1
BIGINT [UNSIGNED]帶符號范圍-2^63~2^63-1,無符號范圍0~2^64-1
FLOAT[(M,D)] [UNSIGNED]M指定顯示長度,D指定小數位數,占用4字節
DOUBLE[(M,D)] [UNSIGNED]表示比float精度更大的小數,占用空間8字節
DECIMAL(M,D) [UNSIGNED]定點數M指定長度,D表示小數點的位數
文本、二進制類型CHAR(size)固定長度字符串,最大255
VARCHAR(size)可變長度字符串,最大長度65535
BLOB二進制數據
TEXT大文本,不支持全文索引,不支持默認值
時間日期DATE/DATETIME/TIMESTAMP日期類型(yyyy-mm-dd),(yyyy-mm-dd hh:mm:ss),timestamp時間戳
String類型ENUM類型字符串對象,值來自表創建時在列規定中顯示枚舉的一個列值
SET類型字符串對象,可包含零或多個允許值,多個值用逗號分隔(值中不能包含逗號)

接下來會講解幾個常用類型的使用:

2.數值類型

int整形類型

1.TINYINT

TINYINT          -- 有符號:-128 到 127
TINYINT UNSIGNED -- 無符號:0 到 255
  • 存儲空間大小:1字節;
  • 常見用途:布爾值,狀態標志,年齡等小數值;
  • 示例
 create table users(id int,age tinyint,status tinyint
);

不管是有符號還是無符號的,插入的數值必須在要求范圍中才能插入成功,否則就會插入失敗

在這里插入圖片描述

后面的幾個整型類型也是如此,就不演示了。

2.SMALLINT

SMALLINT          -- 有符號:-32,768 到 32,767
SMALLINT UNSIGNED -- 無符號:0 到 65,535
  • 存儲空間大小:2字節;
  • 常見用途:年份,端口號,小計數值等;

3.INT

INT               -- 有符號:-2,147,483,648 到 2,147,483,647
INT UNSIGNED      -- 無符號:0 到 4,294,967,295
  • 存儲空間大小:4字節;
  • 常見用途:主鍵,用戶ID,計數器等;

4.BIGINT

BIGINT            -- 有符號:-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
BIGINT UNSIGNED   -- 無符號:0 到 18,446,744,073,709,551,615
  • 存儲空間大小:8字節;
  • 常見用途:大數值,時間戳,大數據場景等;

注意

  • 盡量不要使用unsigned無符號,對于int類型存不下的數據,換成int unsigned同樣可能存不下,那還不如直接設置成一個更大的int類型;
  • 較小的整形索引更快,選擇合適的類型可以節省空間,而且整形比字符串要更加高效;

bit位類型

1.語法格式

BIT(M) -- M表示位數, 范圍1-64

2.基本用法

  • 單比特存儲
create table flags(id int,is_active bit(1),    -- 存儲0/1is_deleted bit(1)    -- 存儲0/1
);
  • 多比特存儲
create table permissions(id int,user_flag bit(8),   -- 8位用戶權限system_flag bit(32) -- 32位系統標志
);

3.存儲范圍

BIT(1)   -- 0 或 1
BIT(8)   -- 0 到 255
BIT(16)  -- 0 到 65535
BIT(32)  -- 0 到 4294967295
BIT(64)  -- 0 到 18446744073709551615

4.插入數據

-- 方式1:使用十進制
insert into permissions values(1001, 21, 252);-- 方式2:使用b前綴(b表示二進制字面量) 比較推薦這種寫法
insert into permissions values(1002, b'10101', b'11111100');-- 方式3:使用十六進制
insert into permissions values(1003, 0x15, 0xFC);

5.查詢和顯示

-- 默認顯示
select *from permissions;

在較新版本的MySQL8.0中,BIT類型默認以十六進制格式顯示(在老版本中會顯示看不見任何數據):

在這里插入圖片描述

除了默認格式顯示,也可以指定形式顯示:

 select id,bin(user_flag) as user_flag_binary,  -- 二進制格式顯示hex(system_flag) as system_flag_hex  -- 十六進制格式顯示from permissions;

在這里插入圖片描述

float小數類型

float是單精度浮點數類型,用于存儲小數數據;

1.基本語法

float[(M,D)] [unsigned] [zerofill]
  • M:總位數(精度);
  • D:小數點后的位數(標度);
  • unsigned:無符號(非負數);
  • zerofill:用零填充;

存儲范圍和精度:

-- FLOAT的存儲特性
-- 范圍:-3.402823466E+38 到 -1.175494351E-38, 0, 1.175494351E-38 到 3.402823466E+38
-- 精度:約7位十進制數字

2.常用示例

  • 創建表時使用float
create table products(name varchar(30),price float(8,2),weight float(8,3),rating float,discount float(3,2) unsigned
);
  • 插入數據:
insert into products values('蘋果', 5.99, 0.250, 4.5, 0.10),('香蕉', 4.88, 0.200, 4.0, 0.15),('橙子', 3.99, 0.300, 3.9, 0.20);
  • 查詢和計算:
-- 基本查詢
select * from products;-- 數學計算select name,price,price*(1-discount) as final_price -- 計算折扣后的價格from products;

在這里插入圖片描述

3.精度問題

以float(4,2)為例,表示的范圍就是-99.99-99.99MySQL在保存數據時會進行四舍五入;如果是float(8.2),表示的范圍就是-99999999.99-99999999.99,同樣也是四舍五入;

insert into products values('葡萄', 2.991, 0.150, 4.1, 0.15),('桃子', 2.947, 0.350, 3.7, 0.20);

在這里插入圖片描述

如果是一個float(4,2) unsigned 無符號的,這時表示范圍就是0-99.99,直接把負數舍棄掉;

除了float之外,還有一個浮點數類型decimal,它的用法和float一模一樣,float怎么用,decimal就怎么用(這里就不展示示例了),唯一的區別就是表示的精度不同

create table test(id int,f1 float(10,8),f2 decimal(10,8)
);

在這里插入圖片描述

對于插入相同的一個浮點數,floatdecimal因為精度不同,導致存儲的數據不同;

  • float的精度大約為7位;
  • decimal整數最大位數m為65位,如果m省略,默認位10;支持小數最大位數d是30,如果d被省略,默認為0;
  • 如果希望小數的精度高,推薦使用decimal

3.字符串類型

CHAR 類型

  • 固定長度:無論存儲多少字符,都占用相同的存儲空間;

  • 語法:char(M) 其中 M 是字符數(1-255),char(2)表示可以存放兩個字符,可以是字母或漢字,但是不能超過2個;

  • 存儲方式:總是占用 M 個字符的存儲空間,不足的部分用空格填充;

VARCHAR 類型

  • 可變長度:根據實際存儲的字符數占用存儲空間;

  • 語法:varchar(M) 其中 M 是最大字符數(不能超過65535字節);

  • 存儲方式:只占用實際字符數 + 1-3字節的長度前綴(用來記錄數據大小);

示例

create table student(name varchar(30),gender char(2)
);insert into student values('張三', '男'),('李四', '女');select * from student;
+--------+--------+
| name   | gender |
+--------+--------+
| 張三   ||
| 李四   ||
+--------+--------+

注意點

varchar(M)中,M的大小和表的編碼密切相關;

在編碼utf8中,一個字符占用3個字節,假設長度前綴占用一個字符,就是三個字節,所以實際上有效字節數就是65535-3=65532;有效字符數就是65532/3=21844;

所以在創建表時,使用varchar定義的字符大小一定不能超過21844,這是單個varchar列的限制

create table s1(name varchar(21844),  -- 21844 * 3 = 65532字節
)charset utf8;

在這里插入圖片描述

但是還要考慮整行大小限制,一行除了varchar大小之外,還有其他字段的大小,比如下面這種情況:

create table s1(name varchar(21844),  -- 21844 * 3 = 65532字節gender char(2)        -- 2 * 3 = 6字節
)charset utf8;

實際計算:

  • name 列:21844字符 × 3字節 = 65532字節

  • gender 列:2字符 × 3字節 = 6字節

  • VARCHAR長度前綴:3字節(存儲實際長度)

  • 總計:65532 + 6 + 3 = 65541字節 > 65535字節

正確的最大長度應該是:

-- 計算:65535 - 其他列開銷 - VARCHAR長度前綴
-- 65535 - 6 - 3 = 65526字節
-- 65526 ÷ 3 = 21842字符

在這里插入圖片描述

char和varchar比較

實際存儲char(4)varchar(4)char占用字節varchar占用字節
abcdabcdabcd4*3=124*3+1=13
AAA4*3=121*3+1=4
Abcde數據超過長度數據超過長度

如何選擇定長或變長字符串?

  • 如果數據確定長度都一樣,就使用定長(char),比如:身份證,手機號,md5

  • 如果數據長度有變化,就使用變長(varchar), 比如:名字,地址,但是你要保證最長的能存的進去。

  • 定長的磁盤空間比較浪費,但是效率高。

  • 變長的磁盤空間比較節省,但是效率低。

  • 定長的意義是,直接開辟好對應的空間

  • 變長的意義是,在不超過自定義范圍的情況下,用多少,開辟多少。

4日期和時間類型

常用的日期有以下三個

  • date:日期yyyy-mm-dd,占用三個字節;
  • datetime:時間日期格式yyy-mm-dd hh:ii:ss表示范圍從1000到9999,占用八個字節;
  • timestap:時間戳,從1970年開始的yyyy-mm-dd hh-ii-ss格式和datetime完全一致,占用四個字節;

示例

create table birthday(-> t1 date,-> t2 datetime,-> t3 timestamp default current_timestamp-> );

default current_timestamp在插入數據時不用輸入,時間戳會自動補上當前時間;通常用來更新數據的插入時間;

在這里插入圖片描述

5.enum和set

enum類型

1.基本語法

enum('值1', '值2', '值3', ...);

2.存儲機制-數字存儲

  • 內部存儲:用整數存儲(1, 2, 3…),可以理解為從1開始的下標;

  • 值1 = 1,值2 = 2,值3 = 3…以此類推;

  • 存儲空間:1-2字節(取決于選項數量);

3.常用示例

-- 創建表
create table student (name varchar(50),gender enum('男', '女'),status enum('active', 'inactive', 'pending')
);-- 插入數據
insert into users values 
('張三', '男', '1'),
('李四', '女', '2'),
('趙六', '1', '3');-- 查詢(可以用數字代替字符串)
select * from student where gender = 1;  -- 等同于 where gender = '男'
select * from student where status = 2;  -- 等同于 where status = 'inactive'

在這里插入圖片描述

4.數字存儲驗證

select gender,gender + 0 as gender_number,status,status + 0 as status_numberfrom student;

在這里插入圖片描述

set類型

1.基本語法

set('值1', '值2', '值3', ...)

2.存儲機制-位掩碼存儲

  • 內部存儲:用位掩碼(bitmask)存儲;

  • 值1 = 1 (001),值2 = 2 (010),值3 = 4 (100);

  • 組合存儲:多個值用位運算組合;

  • 存儲空間:1-8字節(取決于選項數量);

3.位掩碼示例

-- 假設 set('A', 'B', 'C', 'D');
-- A = 1(0001)
-- B = 2(0010)
-- C = 4(0100)
-- D = 8(1000)-- 組合存儲
-- 'A, B' = 1 + 2 = 3(0011)
-- 'A, C' = 1 + 4 = 5(0101)
-- 'B, C, D' = 2 + 4 + 8 = 14(1110)

4.常用示例

-- 創建測試表create table student(name varchar(30),gender char(2),hobby set('籃球', '足球', '羽毛球', '乒乓球'));-- 插入數據
insert into student values('張三', '男', '籃球'),('李四', '女', '羽毛球, 乒乓球'),('王五', '男', '2'),('趙六', '女', '7');-- 查詢
select * from student;
select * from student where hobby = 1;       -- 1對應0001,籃球
select * from student where hobby = '羽毛球'; -- 查找羽毛球的

在這里插入圖片描述

這里就有一個問題了,在查找羽毛球時,顯示為空,但是表中明明有人包含了羽毛球,為什么會沒有顯示出來呢?

這是因為set類型的精確匹配特性

  • where hobby = ‘羽毛球’ 是精確匹配;

  • 它只查找 hobby 字段完全等于 ‘羽毛球’ 的記錄;

  • 而在上面的數據中,羽毛球都是和其他愛好組合在一起的;

但是我們實際生活中每個人都有好幾個愛好,總不能必須只有一個愛好才能查找出來吧?當然不是,這時候就要借助其他查找方式了

這里推薦兩種方式:

  • 使用find_in_set函數
select * from student where find_in_set('羽毛球', hobby);
  • 使用位運算
-- SET('籃球', '足球', '羽毛球', '乒乓球') 的位掩碼
-- 籃球=1, 足球=2, 羽毛球=4, 乒乓球=8
select * from student where hobby & 4;

在這里插入圖片描述

5.位掩碼存儲驗證

select name,hobby,hobby + 0 as hobby_numberfrom student;

在這里插入圖片描述

總結

性能優勢

enum優勢

  • 存儲效率高:1-2字節 vs VARCHAR的變長存儲

  • 查詢速度快:整數比較比字符串比較快

  • 索引效率高:整數索引更緊湊

set優勢

  • 多選存儲:一個字段存儲多個值

  • 位運算查詢:支持高效的位運算查詢

  • 存儲緊湊:多個選項組合存儲

注意事項

enum注意事項

  • 數字轉換:可以用數字代替字符串,但不推薦
  • 修改選項:修改ENUM選項會影響現有數據
  • 空值:NULL和空字符串是不同的

set注意事項

  • 順序無關:‘A,B’ 和 ‘B,A’ 等價
  • 重復值:自動去重
  • 位運算:理解位掩碼有助于高級查詢
    位掩碼存儲驗證**

以上就是關于MySQL數據類型中常用的幾個類型的使用講解,如果哪里有錯的話,可以在評論區指正,也歡迎大家一起討論學習,如果對你的學習有幫助的話,點點贊關注支持一下吧!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/93308.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/93308.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/93308.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

三、搭建springCloudAlibaba2021.1版本分布式微服務-springcloud loadbalancer負載均衡

什么是負責均衡 Spring Cloud LoadBalancer是一個客戶端負載均衡器&#xff0c;類似于Ribbon&#xff0c;但是由于Ribbon已經進入維護模式&#xff0c;并且Ribbon 2并不與Ribbon 1相互兼容&#xff0c;所以Spring Cloud全家桶在Spring Cloud Commons項目中&#xff0c;添加了Sp…

Oracle不完全恢復實戰指南:從原理到操作詳解

核心提示&#xff1a;當誤刪表、日志損壞或控制文件丟失時&#xff0c;Oracle的不完全恢復是DBA最后的救命稻草。掌握關鍵恢復技術&#xff0c;可在數據災難中力挽狂瀾。一、不完全恢復核心概念 1. 核心特點 必須關閉數據庫&#xff1a;在MOUNT狀態下執行重做日志恢復權限要求&…

Linux之shell腳本篇(二)

一、shell編程之if語句引言Linux在shell編程中&#xff0c;通常都是以自上而下運行&#xff0c;但是為了提高其代碼嚴謹性&#xff0c;我們即引入了多條件 控制語句例如&#xff1a;if、for、while、case等語句&#xff0c;有時候針對條件我們還會結合正則表達式去運用。將這些…

如何在android framewrok dump camera data

實現dump 函數 實現1 void dumpBufferToFile(buffer_handle_t* buffer, int width, int height, int frameNum) {void* data NULL;GraphicBufferMapper::getInstance().lock(*buffer, GRALLOC_USAGE_SW_READ_OFTEN, Rect(width, height), &data);char filename[128];sprin…

機器學習中的可解釋性:深入理解SHAP值及其應用

機器學習可解釋性的重要性在人工智能技術快速發展的2025年&#xff0c;機器學習模型已經深度滲透到醫療診斷、金融風控、司法量刑等關鍵領域。然而&#xff0c;隨著模型復雜度的不斷提升&#xff0c;一個根本性矛盾日益凸顯&#xff1a;模型預測性能的提升往往以犧牲可解釋性為…

.NET9 使用 OData 協議項目實戰

.NET 中 ODate 協議介紹 OData(Open Data Protocol) 是一個開放的 Web 協議&#xff0c;用于查詢和更新數據。在 .NET 生態系統中&#xff0c;OData 被廣泛支持和使用。 主要特性 1. 統一的數據訪問方式 提供標準化的查詢語法支持 CRUD 操作支持元數據描述 2. 查詢能力 標…

Android 性能優化:提升應用啟動速度(GC抑制)

前言 在移動應用開發領域&#xff0c;啟動速度是用戶體驗的重要指標。對于Android應用而言&#xff0c;垃圾回收&#xff08;Garbage Collection, GC&#xff09;機制雖然是內存管理的核心&#xff0c;但在應用啟動期間頻繁觸發GC會顯著拖慢啟動速度。本文將深入探討如何通過GC…

做了一款小而美的本地校驗器

需求說明 前陣子收到一則讀者留言&#xff0c;指出&#xff1a;市面上AI核稿工具&#xff08;ProWritingAid&#xff0c;WPS AI Spell Check&#xff0c;Writer&#xff0c;QuillBot&#xff0c;Grammarly&#xff09;要么收費太高&#xff0c;要么讓人擔心文章泄露。 如下圖所…

uniapp + uview-plus 微信小程序二維碼生成和保存完整解決方案

uniapp + uview-plus 微信小程序二維碼生成和保存完整解決方案 ?? 項目背景 在開發微信小程序時,經常需要實現二維碼的生成和保存功能。本文檔提供了一個基于 uniapp + uview-plus 框架的完整解決方案,徹底解決了以下常見問題: ? Canvas API 兼容性問題 ? 微信小程序權…

Linux中應用程序的安裝于管理

Linux中應用程序的安裝于管理 一 . rpm安裝 1.掛載 光驅里面存放了很多rpm的軟件包 光驅在系統中使用時&#xff0c;需要掛載 mount /dev/cdrom /mnt/ cd /mnt[rootstw mnt]# ls CentOS_BuildTag GPL LiveOS RPM-GPG-KEY-CentOS-7 EFI images Packag…

mysql重置密碼

要區分 MySQL 是通過 systemd 還是傳統 service 管理&#xff0c;以及對應的密碼重置方案&#xff0c;可按以下步驟操作&#xff1a; 一、如何區分管理方式&#xff08;systemd 還是傳統 service&#xff09; 通過以下命令判斷系統默認的服務管理方式&#xff1a;檢查系統是否使…

C++ TAP(基于任務的異步編程模式)

&#x1f680; C TAP&#xff08;基于任務的異步編程模式&#xff09;1. 引言&#xff1a;走進異步編程新時代&#xff08;&#x1f680;&#xff09; 在當今高性能計算領域&#xff0c;同步編程模型的局限性日益凸顯。傳統的回調地獄和線程管理復雜性促使微軟提出了基于任務的…

利用C++手撕棧與隊列的基本功能(四)

棧和隊列詳細教程可以觀看 https://www.bilibili.com/video/BV1nJ411V7bd?spm_id_from333.788.videopod.episodes&vd_sourcedaed5b8a51d3ab7eb209efa9d0ff9a34&p48棧和隊列概念 棧和隊列是限定插入和刪除只能在表的端點進行的線性表在裝電池、裝彈夾、拿放盤子時都會出…

net8.0一鍵創建支持(Redis)

Necore項目生成器 - 在線創建Necore模板項目 | 一鍵下載 RedisController.cs using CSRedis; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using UnT.Template.Application.Responses; using UnT.Template.Domain;namespace UnT.Template.Controllers {…

Leetcode——42. 接雨水

還記得第一次見該題根本無從下手。其實&#xff0c;我們不妨把問題拆解&#xff0c;簡單化。不要怕自己寫的是暴力算法&#xff0c;有很多算法技巧其實就是在暴力算法的基礎上優化得來。題目目的是求所有可接雨水數量&#xff0c;我們可以求出每一個位置可接雨水數量&#xff0…

Go 語言-->指針

Go 語言–>指針 它允許你操作內存中的實際數據&#xff0c;而不僅僅是數據的副本。指針存儲的是另一個變量的內存地址&#xff0c;而不是變量的實際值。 1. 什么是指針 指針是存儲變量內存地址的變量&#xff0c;它指向另一個變量。通過指針&#xff0c;你可以間接地訪問和修…

軟工八將:軟件開發全流程核心角色體系解析

軟工八將&#xff1a;軟件開發全流程核心角色體系解析 作者注&#xff1a;本概念是由大學生董翔提出&#xff0c;具有一些影響意義。 在現代軟件開發領域&#xff0c;團隊角色的專業化分工是產品成功的核心保障。“軟工八將”作為一套系統梳理軟件開發全流程核心角色的術語&…

安全風險監測系統是什么?內容有哪些?

安全風險監測系統是基于物聯網感知網絡與智能分析技術的綜合管理平臺&#xff0c;通過實時采集、分析和評估各類安全風險指標&#xff0c;構建起覆蓋識別、預警、處置全流程的主動防御體系。作為現代安全管理的中樞神經系統&#xff0c;該系統實現了從被動響應到主動預防的范式…

車載診斷架構 ---面向售后的DTC應該怎么樣填寫?

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 簡單,單純,喜歡獨處,獨來獨往,不易合同頻過著接地氣的生活,除了生存溫飽問題之外,沒有什么過多的欲望,表面看起來很高冷,內心熱情,如果你身…

墨者:SQL注入漏洞測試(寬字節)

墨者學院&#xff1a;SQL注入漏洞測試(寬字節)&#x1f680; 1. 寬字節注入原理? 1.1. 與普通注入對比? 特性普通注入寬字節注入適用場景無轉義處理使用addslashes()等轉義函數核心原理直接閉合引號利用GBK等編碼吞掉轉義符\關鍵字符 " -- #%df %5c防御難度易防御需調…