SQL字符集

目標:了解字符集的概念,掌握MySQL數據庫存儲數據的字符集邏輯以及設置方式

  • 字符集概念

  • MySQL字符集關系

  • 解決亂碼問題

  • 字符集設置原理

1、字符集概念

目標:了解字符集概念,掌握字符集存儲和讀取的實現原理

概念

字符集:charset或者character set,是各種文字和符號在計算機中的總稱

  • 字符集根據不同國家的符號不同,有不同的字符集

  • 不同的字符集占用的存儲空間不一樣,存儲的底層也不一樣

  • 不同字符集之間可以進行轉換

  • 常見字符集

    • ASCI:美國信息交換標準碼,工般英文符號,一個字節存儲

    • latin1:拉丁文字符集,一個字節存儲,ISO-8859-1的別名,能夠向下兼容ASCII

    • GB2312:信息交換用漢字編碼字符集,是中國1981年的一套國標規范,2個字節存儲

    • GBK:漢字內碼擴展規范(1995年),兩個字節表示表示(漢字很多超過5000個)

    • Unicode:萬國碼(統一碼),使用統一的編碼方式來解決傳統的局限,1994年出現

    • UTE-8:8-bit Unicode Transformation Format(萬國碼),針對Unicode的可變長度字符編碼,采用1-6個字

      節編碼Unicode字符(目前通用編碼規則)。建議使用UTE-8字符集進行數據存儲

演示

ASCII碼表(單字節存儲:1 byke = 8 bits)

原理流程圖

1、數據存儲

graph LR
A(輸入符號<br>A)-->B[計算機存儲]
B-->C{字符集選擇}
C-->|ASCII|D[轉碼<br>01000001]C-->|GBK|E[轉碼<br>0000000001000001]
C-->|ASCII 存儲中文|G[轉碼<br>亂碼]
D-->F((存儲))
E-->F
G-->F

2、數據讀取

graph LR
A(數據讀取)-->B{字符集選擇}
B-->ASCII|C[讀1個字節<br>01000001]
B-->|GBK|D[讀2個字節<br>0000000001000001]
B-->|UTF-8|G[讀3個字節<br>錯誤讀取]
G-->H[解析<br>亂碼]
C-->E[解析<br>A]
D-->E
E-->F((輸出))
H-->F

小結

1、字符集是一套符號的總稱

2、不同國家地區的符號有區別,所以有自己的字符集

3、常見的字符集目前是三個

  • ASClI:美國信息交換標準碼

  • GBK:漢字內碼擴展規范(國標),兼容ASCII

  • UTF-8:8字節萬國碼,兼容GBK和ASCIl

4、目前基本都統一使用UTF-8開發和數據存儲

5、字符集是指定字符的存儲和讀取的規范

  • 指定的字符集存儲需要使用對應的字符集讀取

  • 錯誤的字符集存儲或者讀取都會產生亂碼

2、MySQL字符集

目標:了解MySQL中字符集的實現原理,掌握數據最終的存儲字符集

概念

MySQL字符集:MySQL內部對于數據實際存儲的字符集(服務器端)

  • MySQL內部對象可以在各個層級設置字符集

  • MySQL內部隊形存在字符集繼承:字段->表->數據庫->DBMS

  • MySQL內部內嵌支持幾乎所有主流字符集

  • 數據存儲的最終字符集由字段控制

  • 客戶端與服務器進行交互時,需要明確告知服務器客戶端自己的字符集(數據格式)

演示

查看MySQL支持的所有字符集

show charset;

結果

原理圖

1、數據庫內部對象字符集原理

graph TB
A(服務器數據管理)-->B[DBMS系統<br>安裝配置字符集]
B-->C[數據庫<br>設定字符集]
C-->|繼承DBMS字符集|B
C-->D[數據表<br>設定字符集]
D-->|繼承數據庫字符集|C
D-->E[數據字段<br>設定字符集]
E-->|繼承數據表字符集|D

1.1、服務端存儲的數據最終字符集由字段確定

1.2、字段通常不會設置字符集,繼承表的字符集

1.3、數據存儲的字符集與客戶端的字符集沒有直接關系,是由表(字段)決定

小結 1、MySQL服務端數據存儲的字符集依賴各個對象設置

  • DBMS:設置最廣,一旦設置所有對象都可以依賴,但是優先級最低

  • DB:針對數據庫內的所有表,優先級高于DBMS,可以繼承DBMS(一般在數據庫層設置)

  • Table:針對當前表的設置,優先級高于DB,可以繼承DB

  • Field:針對當前字段設置,優先級高于Table,可以繼承Table,優先級最高2

2、通常字符集的設置都是圍繞數據表(現在都在數據庫層),不會到具體字段

3、建議使用UTE-8字符集存儲數據(MySQL8以后建議使用UTF8MB4)

4、MySQL服務端支持各種字符集,并且能夠進行各種字符集轉換

5、客戶端存儲數據到服務端原理

  • 客戶端告知服務端客戶端的字符集

  • 服務端按照客戶端指定的字符集接收數據(如果沒有指定,使用默認,可能出現亂碼)

  • 服務端按照實際存儲表對應的字符集進行轉換

  • 服務端存儲數據

6、客戶端讀取服務端數據原理

  • 客戶端告知服務端客戶端的字符集

  • 服務端按照客戶指定的指令從數據庫讀取原始字符集數據

  • 服務端按照客戶端的需求將數據進行字符轉換

  • 服務端發送目標數據給客戶端

  • 客戶端按照自己的字符集進行解析

3、亂碼問題解決

目標:了解亂碼發生的原因,實現亂碼問題的解決方案

概念

亂碼:指數據不能按照正確的字符集進行存儲或者解析。

  • 亂碼原因1:數據在存儲的時候已經變成亂碼

    • 客戶端字符集與服務端解析字符集不一致

    • 讀取時想轉成其他字符集均會錯誤

  • 亂碼原因2:數據存儲時正確,但是讀取時解析成錯誤字符集

    • 客戶端能解析的字符集與服務器提供的字符集不一致

  • 亂碼解決方案:不論存儲還是讀取,都提前告知服務器當前客戶端的字符集

set names 客戶端字符集;

演示

1、MySQL客戶端(CMD打開),客戶端字符集是固定的GBK

set names gbk;

流程圖

graph TB
A(客戶端連接認證服務端)-->B[設定字符集<br>告知服務端當前客戶端的字符集]
B-->C[其他操作<br>內部字符集轉換不用管]
C-->D((結束))

小結

1、亂碼的本質原因就是客戶端與服務端的字符集不一致導致

  • 客戶端存儲數據的時候服務端沒有正確理解(服務端按照默認的存儲,存儲的就是亂碼)

  • 客戶端讀取的時候沒有正確告知服務端(服務端按照默認的提供)

2、解決亂碼問題的方案:保證服務端正確理解客戶端的字符集

  • setnames 客戶端字符集

  • 在任何數據操作之前(尤其是寫數據)

4、字符集設置原理

目標:了解set names字符集的本質原理

概念

字符集設置原理:服務器端正確保障對客戶端的數據識別

  • MySQL服務端提供了變量來記錄客戶端的字符集

  • MySQL對應的存儲字符集的變量可以修改

  • set names 字符集就是對變量的修改,總共有三個

    • character_set_client:客戶端提供的數據的字符集

    • character_set_results:客戶端需要服務端提供的數據的字符集

    • character_set_connection:連接使用的字符集,內部數據操作

演示

1、查看系統內部存儲這些記錄字符集的信息

show variables like 'character_set%'; ? #%表示通配符,匹配后續所有不確定的數據

2、修改客戶端字符集變量,保證數據正常存進服務端

set character_set_client = gbk;

3、修改客戶端解析字符集變量,保證數據正常被客戶端查看

set character_set_results = gbk;

4、使用set names 字符集批量修改,保證客戶端被服務端正確理解,同時客戶端也能正確解析

set names gbk;

小結

1、MySQL字符集控制是在服務端內部通過變量連接(針對每個獨立的客戶端)

2、set names字符集是一種快捷方式,本質有三個變量被修改

  • character_set_client:服務端接收客戶端數據

  • character_set_connection:服務端內部連接使用

  • character_set_results:服務端提供數據給客戶端

3、通常我們都是使用set names字符集來進行統一設置,而且是在建立連接之后操作數據之前就設置

5、總結

1、字符集是所有編程語言里都必須面對的首要問題,必須在一開始就選擇好字符集(去到企業后先問清楚)

  • 業務針對的符號

  • 業務針對的范圍

2、亂碼是編程中最基礎要解決的問題,一旦數據產生了亂碼,通常是不可逆操作

3、解決亂碼問題其實本質就是統一字符集問題

  • 客戶端字符集:character_set_client

  • 連接層字符集:character_set_connection

  • 結果集字符集:`character_set_results

  • 簡單統一方式:set names 客戶端字符集

  • 存儲字符集:不用考慮,因為數據庫有強大的字符集轉換能力,只要在開始設置好,保證后續數據不會超出字符集即可

二、校對集

目標:了解校對集的概念以及校對集在校對時的作用

概念

校對集:collate/collation,即數據比較時對應的規則

  • 校對集依賴字符集

  • 校對集的校對方式分為三種

    • 大小寫不敏感:ci,case insensitive(不區分大小寫)

    • 大小寫敏感:cs,case sensitive(區分大小寫)

    • 二進制比較: bin(區分大小寫)

  • 校對集是在進行數據比較的時候觸發

演示

1、_cì,大小寫不敏感

A 與 a 是相同的,不存在誰大誰小(系統會轉換成一種)

2、_cs,大小寫敏感

A 與 a有大小關系,所以不同(存儲數值)

3、_bin,二進制比較

A的二進制是01000001
a的二進制是01100001
二進制按位比較,所以不同

小結

1、校對集是數據比較的規則

  • 校對集依賴字符集存在

  • 每個字符集有多種校對規則

2、校對規則一共有三種

  • _ci:大小寫不敏感,不區分大小寫

  • _cs:大小寫敏感,區分大小寫

  • _bin:二進制比較(區分大小寫)

1、校對集設置

目標:了解MySQL中校對集的設計方式以及規則查看

概念

校對集設置:在創建數據表的時候創建校對規則

  • 校對規則可以在MySQL四層對象設計

    • DBMS:系統配置

    • DB:數據庫指定(庫選項)

    • Table:表指定(表選項)

    • Field:字段指定(字段選項,一般不用)

  • 校對集從Field到DBMS繼承;優先級Field最高。

  • 每個校對集都有字符集對應的默認規則

  • 校對集設置語法

co11ate 校對集規則;

演示

1、查看MySQL支持的所有校對集

show co1lation;

2、在數據庫層設計校對集(常見)

create database db_4 charset utf8mb4 collate utf8mb4_bin;

3、在數據表層設計校對集

create table t_4(id int,name varchar(10)
)charset utf8mb4 collate utf8mb4_bin;

4、在字段層設計校對集(一般不常用)

create table t_5(id int,name varchar(10) collate utf8mb4_bin
)charset utf8mb4;

小結

1、MySQL中四層對象都可以設置校對集

  • DBMS:配置文件

  • DB:創建數據庫時限定(設置)

  • Table:創建表示限定

  • Field:創建字段時限定

2、校對集從Field到DBMS實現繼承

3、校對集依賴字符集,且每個字符集都有默認的校對集(一般情況不需要設置)

2、校對集應用

目標:了解不同校對集的實際校對原理,掌握校對規則的應用場景

概念

校對集應用:觸發校對規則的使用

  • 校對集的應用通常是通過數據比較觸發:order by 字段

  • 數據表中數據一旦產生,校對集的修改就無效

演示

1、創建校對規則數據表并插入數據

# 創建默認校對規則表(不區分大小寫)
create table t_4(name varchar(1)
)charset utf8mb4;
insert into t_4 value('B');
insert into t_4 values('A');
insert into t_4 values('b');
insert into t_4 values('a');#創建二進制校對規則(區分大小寫)
create table t_5(name varchar(1)
)charset utf8mb4 collate utf8mb4_bin;
insert into t_5 values('B');
insert into t_5 values('A');
insert into t_5 values('b');
insert into t_5 values('a');

2、觸發校對:排序 order by

select *from t_4 order by name;#升序
select *from t_5 order by name;

3、數據已經存在的表重新修改校對規則無效

alter table t_5 collate utf8mb4_general_ci: 

小結

1、校對集的應用不是主動觸發,而是通過數據比較自動觸發

2、校對集對應的數據一旦產生,那么就不可以修改數據表的校對規則

3、校對集通常使用字符集默認校對集,如果需要進行額外的比較應用(通常是區分大小寫),那么需要在建表的時候設定好目標校對規則

3、總結

1、校對集是數據比較的標準

2、校對集的校對規則都是依賴字符集存在的,不外乎三種規則

  • _ci:不區分大小寫

  • _cs:區分大小寫

  • _bin:二進制比較(區分大小寫)

3、校對集的觸發是自動的,只要數據在進行比較的時候就會自動觸發設定的校對規則

  • 校對集的維護要在數據產生之前

  • 數據產生之后校對集的修改將無效

4、在進行數據表設計之前,要提前了解數據后續可能產生的比較形態,選擇好合適的校對規則(一般都默認不區分大小寫)

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

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

相關文章

(十二)【Jmeter】線程(Threads(Users))之setUp 線程組

簡述 操作路徑如下: 作用:在正式測試開始前執行預加載或預熱操作,為測試做準備。配置:設置預加載或預熱操作的采樣器、循環次數等參數。使用場景:確保在正式測試開始前應用程序已經達到穩定狀態,減少測試結果的偏差。優點:提供預加載或預熱操作,確保測試的準確性。缺…

Centos開機網卡自啟動失敗

問題背景 每次都要手動啟動在這里插入代碼片 解決方案: 關閉 NetworkManager 服務 systemctl disable NetworkManager systemctl stop NetworkManager重啟就會發現網卡已經可以自動啟動了

2024幻獸帕魯游戲服務器租用價格表_一年和1個月報價明細

游戲服務器租用多少錢一年&#xff1f;1個月游戲服務器費用多少&#xff1f;阿里云4核16G10M游戲服務器26元1個月、149元半年&#xff0c;騰訊云4核16G游戲服務器32元、312元一年&#xff0c;華為云26元&#xff0c;京東云主機也是26元起&#xff0c;游戲服務器配置從4核16G、4…

代碼隨想錄算法刷題訓練營day22

代碼隨想錄算法刷題訓練營day22&#xff1a;LeetCode(236)二叉樹的最近公共祖先、LeetCode(235) 二叉搜索樹的最近公共祖先、LeetCode(701)二叉搜索樹中的插入操作、LeetCode(450)刪除二叉搜索樹中的節點 LeetCode(236)二叉樹的最近公共祖先 題目 代碼 /*** Definition for…

【鴻蒙 HarmonyOS 4.0】路由router

一、介紹 頁面路由指在應用程序中實現不同頁面之間的跳轉和數據傳遞。HarmonyOS提供了Router模塊&#xff0c;通過不同的url地址&#xff0c;可以方便地進行頁面路由&#xff0c;輕松地訪問不同的頁面。 二、頁面跳轉 2.1、兩種跳轉模式&#xff1a; router.pushUrl()&…

vue2與vue3中父子組件傳參的區別

本次主要針對vue中父子組件傳參所進行講解 一、vue2和vue3父傳子區別 1.vue2的父傳子 1).在父組件子標簽中自定義一個屬性 <sonPage :子組件接收到的類名"傳輸的數據">子組件</sonPage> 2).在子組件中peops屬性中拿到自定屬性 props: {子組件接收的…

Stable Diffusion算法、結構全流程概述

Stable Diffusion能力強、功能多、插件廣&#xff0c;本文擬概述SD的全流程&#xff0c;方便梳理算法各結構的關系 1、stable diffusion訓練用ddpm, 采樣用ddim DDPM的推理采樣步長和訓練時的步長一樣&#xff0c;導致采樣步數過多&#xff0c;推理時間長。DDIM指出&#xff…

安卓游戲開發之音頻技術優劣分析

一、引言 在安卓游戲開發中&#xff0c;音頻處理技術扮演著至關重要的角色&#xff0c;它不僅能夠增強游戲的沉浸感和玩家體驗&#xff0c;還能通過聲音效果傳達關鍵的游戲信息。以下將對幾種常見的安卓游戲音頻處理技術進行優劣分析&#xff0c;并結合應用場景來闡述其特點。 …

docker鏡像打包和解壓

背景 工作記錄 打包鏡像 docker save -o 壓縮包名稱.tar 鏡像名稱:鏡像版本 例如 docker save -o app-web.tar app-web:2.0解壓鏡像 這里解壓上面打包的app-web的壓縮包 docker load<壓縮包名稱.tar docker load<app-web.tar這樣解壓下來的實際就是app-web:2.0這個鏡…

微服務-微服務API網關Spring-clould-gateway實戰

1. 需求背景 在微服務架構中&#xff0c;通常一個系統會被拆分為多個微服務&#xff0c;面對這么多微服務客戶端應該如何去調用呢&#xff1f; 如果根據每個微服務的地址發起調用&#xff0c;存在如下問題&#xff1a; 1.客戶端多次請求不同的微服務&#xff0c;會增加客戶端…

Qt 事件

1. 事件 事件是對各種應用程序需要知道的由應用程序內部或者外部產生的事情或者動作的通稱。在Qt中使用一個對象來表示一個事件&#xff0c;它繼承自QEvent類。 2. 事件和信號 事件與信號并不相同&#xff0c;比如我們使用鼠標點擊了一下界面上的按鈕&#xff0c;那么就會產生…

node 之 初步認識

思考&#xff1a;為什么JavaScript可以在瀏覽器中被執行 代執行的js代碼——JavaScript解析引擎 不同的瀏覽器使用不同的JavaScript解析引擎 Chrome 瀏覽器 》 V8 Firefox瀏覽器 》OdinMonkey(奧丁猴&#xff09; Safri瀏覽器 》JSCore IE瀏覽器 》Chakra(查克拉&#xff09; e…

XML的寫法

下面我將以如下代碼來解釋下XML的寫法 <?xml version"1.0" encoding"UTF-8" ?> <Steam><steam id"1"><zhanghao>admin</zhanghao><mima>123</mima><num>120</num></steam><st…

金航標電子位于廣西柳州鹿寨縣天線生產基地于大年正月初九開工了

金航標電子位于廣西柳州鹿寨縣天線生產基地于大年正月初九開工了&#xff01;&#xff01;&#xff01;金航標kinghelm&#xff08;www.kinghelm.com.cn&#xff09;總部位于中國深圳市&#xff0c;兼顧技術、成本、管理、效率和可持續發展。東莞塘廈實驗室全電波暗室、網絡分析…

關于路徑字串標準化的代碼

上文說到&#xff0c;得到執行的正確路徑。有時這個路徑并不規范&#xff0c;所以要進行一番標準化。具體工作&#xff1a; //替換為//./替換為/../的處理 近來專門研究了一下&#xff0c;寫了個代碼。其實也不難&#xff0c;主要是處理../時麻煩。 char* format_to_exe_path…

運維SRE-06 階段性復習軟件管理體系

那些年運維必會操作-第一彈 操作 文件&#xff1a;增刪改查 增&#xff1a;touch,vim,>,>>,cp刪除&#xff1a;rm修改&#xff1a;內容&#xff1a;vi/vim,>,>> 文件名&#xff1a;mv查看&#xff1a;內容&#xff1a;cat/vim/less/more/head/tail/sed/awk/…

Day03-課后練習-參考答案(流程控制_分支結構)(判斷年、月、日是否合法,判斷打魚還是曬網,判斷星座)

文章目錄 鞏固題1、從鍵盤輸入一個整數&#xff0c;判斷它是否是5的倍數2、從鍵盤輸入一個字符&#xff0c;判斷字符類型3、計算折扣后金額4、輸出月份對應的英語單詞5、計算今天是星期幾 簡答題拔高題&#xff08;自愿&#xff09;6、判斷年、月、日是否合法7、判斷打魚還是曬…

【C++】STL容器之string(迭代器,范圍for)

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;個人主頁 &#xff1a;阿然成長日記 …

ubuntu內核卸載重裝

目錄 問題1.問題復現2.可以正常啟動的方式 保存快照卸載有問題的內核重裝最新內核參考資料 問題 1.問題復現 ubuntu開機出現如下畫面,啟動不能正常啟動 2.可以正常啟動的方式 使用其他內核可以正常工作 保存快照 在解決之前保存快照,防止破壞時恢復 卸載有問題的內核…

微信小程序開發:通過wx.login()獲取用戶唯一標識openid和unionid

下面代碼展示了 openid 的獲取過程。 想獲取 unionid 需要滿足條件&#xff1a;小程序已綁定到微信開放平臺賬號下&#xff0c;不然只會返回 openid。 【相關文檔】 微信小程序開發&#xff1a;appid 和 secret 的獲取方法 wx.login({success (res) {if (res.code) {// 發起網…