MySQL虛擬列:一個被低估的MySQL特性

前言

最近在做訂單系統重構時,遇到了一個有趣的問題。

系統里有很多地方都要計算訂單的總價(數量×單價),這個計算邏輯分散在各個服務中,產生了不少相似甚至重復的代碼。

代碼評審時,同事提出了一個建議 —— 使用MySQL的虛擬列來統一處理這類計算,在調研后我們一致決定采納。

經過一段時間的生產實踐,也逐漸摸清了虛擬列的套路,這里就和大家分享一下這個特性的使用心得。

耐心看完,你一定有所收獲。

MySQL 5.7版本引入的虛擬列(Generated Columns)允許我們定義一個基于其他列計算得出的列。

它有點像Excel中的計算列,但更加強大和靈活。

虛擬列分為兩種類型:

  1. VIRTUAL(虛擬列):在讀取時實時計算,不占用存儲空間
  2. STORED(存儲列):在數據寫入時計算并存儲,會占用實際存儲空間

基本語法

創建虛擬列的語法不難:

-- 例如,計算訂單總價CREATE TABLE orders (quantity INT,unit_price DECIMAL(10,2),total_price DECIMAL(10,2) GENERATED ALWAYS AS (quantity * unit_price) VIRTUAL);

虛擬列還是比較好用的,但是也得注意,不是所有的場景都適合使用,這里先講適合的。

適合使用虛擬列的場景

  1. 可以簡化查詢和業務操作的,避免在多個查詢中重復編寫相同的表達式

-- 例如,計算訂單總價CREATE TABLE orders (quantity INT,unit_price DECIMAL(10,2),total_price DECIMAL(10,2) GENERATED ALWAYS AS (quantity * unit_price) VIRTUAL);
  1. 需要確保計算值始終正確且一致

-- 自動計算年齡CREATE TABLE persons (birth_date DATE,age INT GENERATED ALWAYS AS (YEAR(CURDATE()) - YEAR(birth_date)) VIRTUAL);
  1. 從JSON列中提取特定字段或者做一些判斷
CREATE TABLE products (attributes JSON,product_name VARCHAR(100) GENERATED ALWAYS AS (attributes->>'$.name') VIRTUAL
);
  1. 利用虛擬列創建索引,提高查詢性能

這個特性需要MySQL 8.0+


CREATE TABLE users (full_name VARCHAR(100),first_name VARCHAR(50) GENERATED ALWAYS AS (SUBSTRING_INDEX(full_name, ' ', 1)) VIRTUAL,INDEX (first_name));

不適合使用虛擬列的場景

  1. 計算成本過高、過于復雜的表達式會影響性能
  2. 頻繁更新的表,則不適用VIRTUAL列,畢竟在每次查詢時都會重新計算
  3. 存儲空間嚴重受限時,謹慎使用使用STORED類型時,因為STORED列會增加存儲空間
  4. MySQL 5.7 以下不支持虛擬列
  5. 計算依賴于不確定性函數(如NOW()、RAND())的,也不能使用

虛擬列的限制

  1. 不能在虛擬列中使用子查詢
  2. 不能引用自增列
  3. 不能使用存儲函數或用戶定義的函數
  4. 不能使用不確定函數(如NOW())
  5. 不能將虛擬列作為外鍵
  6. 不能設置默認值

性能考慮

  1. VIRTUAL列:查詢時計算,適合計算簡單、不頻繁查詢的列
  2. STORED列:寫入時計算,適合計算復雜、頻繁查詢的列
  3. 索引:只能在STORED列上創建索引(MySQL 8.0+支持在VIRTUAL列上創建索引)

總結

MySQL虛擬列為我們提供了一個優雅的解決方案,可以將部分計算邏輯從應用層轉移到數據層,既保證了數據的一致性,又簡化了應用層代碼。

在我們的訂單系統中,目前有不少字段都用上了虛擬列,確實代碼會更加清晰,維護成本也有相應降低。

當然,是否使用虛擬列需要根據具體場景來判斷。

對于簡單的計算邏輯,特別是需要在多處使用的計算結果,虛擬列是個不錯的選擇。
但對于復雜的業務邏輯,還是建議放在應用層處理為好。

希望這篇文章能幫助大家更好地理解和使用MySQL虛擬列這個實用的特性。

如果你的項目中有類似的場景,不妨嘗試一下這個功能,也歡迎使用過的朋友來交流下心得。

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

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

相關文章

音頻導入規范

一般音頻可以交給策劃來導入提交,需要遵循一些規范,下面是我們實際項目用到的一些規范 1、Force To Mono: 勾選,強制單聲道。(可以減少音效文件的內存占用) 2、Normalize: 勾選,引…

使用html寫一個倒計時頁面

一個使用 HTML、CSS 和 JavaScript 實現的倒計時頁面,包含動態效果和響應式布局: 功能特點: 動態效果: 每個時間單元帶有 hover 動畫(懸浮時輕微上浮)倒計時數字實時更新,精確到秒結束時自動更換背景顏色并顯示提示信息響應式設計: 適配移動端屏幕(屏幕寬度小于600px…

spring boot源碼和lib分開打包

1.項目通過maven引入的jar多了之后&#xff0c;用maven打出的jar會非常龐大&#xff0c;我的是因為引入了ffmpeg的相關jar,所以&#xff0c;每次上傳服務更新都要傳輸好久&#xff0c;修改maven打包方式&#xff0c;改為源碼和lib分離模式 2.maven的pom.xml配置如下 <build…

計算機網絡筆記(三十)——5.2用戶數據報協議UDP

5.2.1UDP概述 一、UDP 的定義 用戶數據報協議 (User Datagram Protocol, UDP) 是傳輸層的無連接、不可靠協議。它提供最小化的協議機制&#xff0c;僅支持數據報的簡單傳輸&#xff0c;不保證數據順序或可靠性。 二、UDP 的核心特點 無連接 通信前無需建立連接&#xff0c;直…

Java異步編程之消息隊列疑難問題拆解

前言 在Java里運用消息隊列實現異步通信時&#xff0c;會面臨諸多疑難問題。這里對實際開發中碰到的疑難為題進行匯總及拆解&#xff0c;使用RabbitMQ和Kafka兩種常見的消息隊列中間件來作為示例&#xff0c;給出相應的解決方案&#xff1a; 一、消息丟失問題 消息在傳輸過程…

香橙派3B學習筆記10:snap打包C/C++程序與動態鏈接庫(.so)

esnap打包C/C程序與動態鏈接庫&#xff08;.so&#xff09; 之前已經學會了snap基本的打包程序&#xff0c;現在試試打包C/C程序與動態鏈接庫&#xff08;.so&#xff09; ssh &#xff1a; orangepi本地ip 密碼 &#xff1a; orangepi 操作系統發行版&#xff1a; 基于 Ubun…

【Python工具開發】k3q_arxml 簡單但是非常好用的arxml編輯器,可以稱為arxml殺手包

k3q_arxml 介紹 倉庫地址1 倉庫地址2 極簡的arxml編輯庫&#xff0c;純python實現 用法 from pprint import pp # 可以美化打印對象&#xff0c;不然全打印在一行 import k3q_arxml # 加載arxml文件 io_arxml k3q_arxml.IOArxml(filepaths[test/model_merge.arxml])# 打印…

【CSS-8】深入理解CSS選擇器權重:掌握樣式優先級的關鍵

CSS選擇器權重是前端開發中一個基礎但極其重要的概念&#xff0c;它決定了當多個CSS規則應用于同一個元素時&#xff0c;哪條規則最終會被瀏覽器采用。理解權重機制可以幫助開發者更高效地編寫和維護CSS代碼&#xff0c;避免樣式沖突帶來的困擾。 1. 什么是CSS選擇器權重&…

大語言模型原理與書生大模型提示詞工程實踐-學習筆記

&#x1f4d8; 第五期書生葡語實戰營講座總結 &#x1f399; 主講人&#xff1a;王明&#xff08;東部大學 數據挖掘實驗室 博士生&#xff09; 一、大語言模型的生成原理 架構基礎&#xff1a;采用 Transformer&#xff08;Decoder-only&#xff09;架構&#xff0c;如 GPT …

李沐 《動手學深度學習》 | 實戰Kaggle比賽:預測房價

文章目錄 1.下載和緩存數據集2.數據預處理讀取樣本預處理樣本數值型特征處理特征標準化的好處離散值處理轉換為張量表示 訓練K折交叉驗證模型選擇最終模型確認及結果預測代碼總結提交到Kaggle 房價預測比賽鏈接&#xff1a;https://www.kaggle.com/c/house-prices-advanced-reg…

一鍵部署Prometheus+Grafana+alertmanager對網站狀態進行監控

在建設監控體系的過程中&#xff0c;針對一個系統的監控是多維度的&#xff0c;除了服務器資源狀態、中間件狀態、應用狀態外&#xff0c;對系統訪問狀態的監控也是很有必要&#xff0c;可以在系統訪問出現異常時第一時間通知到我們。本文介紹使用 Docker-compose 方式一鍵部署…

康謀方案 | 高精LiDAR+神經渲染3DGS的完美融合實踐

目錄 一、從點云到高精地圖的重建 1、數據采集 2、點云聚合 3、高精地圖建模 4、三維建模與裝飾 二、顛覆性革新&#xff1a;NeRF 與 3DGS 重建 1、僅需數日&#xff0c;完成街景重建 2、進一步消除 Domain gap&#xff0c;場景逼真如實地拍攝 3、降本增效&#xff0c…

MySQL-事務(TRANSACTION-ACID)管理

目錄 一、什么是事務&#xff1f; 1.1.事務的定義 1.2.事務的基本語句 1.3.事務的四大特性&#xff08;ACID&#xff09; 二、數據庫的并發控制 2.1.什么是并發及并發操作帶來的影響&#xff1f; 2.2.并發操作帶來的隔離級別 三、使用事務的場景 3.1.銀行轉賬場景示例 3.2.模擬…

centos系統docker配置milvus教程

本人使用的是京東云服務器配置milvus 參考教程&#xff1a;https://blog.csdn.net/withme977/article/details/137270087 首先確保安裝了docker 、docker compose docker -- version docker-compose --version創建milvus工作目錄 mkdir milvus # 進入到新建的目錄 cd milvu…

什么是JSON ?從核心語法到編輯器

一、什么是JSON &#xff1f; JSON&#xff0c;即 JavaScript 對象表示法&#xff0c;是一種輕量級、跨語言、純文本的數據交換格式 。它誕生于 JavaScript 生態&#xff0c;但如今已成為所有編程語言通用的 “數據普通話”—— 無論前端、后端&#xff0c;還是 Python、Java&…

計算機網絡(7)——物理層

1.數據通信基礎 1.1 物理層基本概念 物理層(Physical Layer)是所有網絡通信的物理基礎&#xff0c;它定義了在物理介質上傳輸原始比特流(0和1)所需的機械、電氣、功能、過程和規程特性 1.2 數據通信系統模型 信源&#xff1a;生成原始數據的終端設備&#xff0c;常見形態包括…

深度學習基礎知識總結

1.BatchNorm2d 加速收斂&#xff1a;Batch Normalization 可以使每層的輸入保持較穩定的分布&#xff08;接近標準正態分布&#xff09;&#xff0c;減少梯度更新時的震蕩問題&#xff0c;從而加快模型訓練速度。 減輕過擬合&#xff1a;批歸一化引入了輕微的正則化效果&#…

iOS 抖音首頁頭部滑動標簽的實現

抖音首頁的頭部滑動標簽(通常稱為"Segmented Control"或"Tab Bar")是一個常見的UI組件&#xff0c;可以通過以下幾種方式實現&#xff1a; 1. 使用UISegmentedControl 最簡單的實現方式是使用系統自帶的UISegmentedControl&#xff1a; let segmentedCo…

ThreadLocal實現原理

ThreadLocal 是 Java 中實現線程封閉&#xff08;Thread Confinement&#xff09;的核心機制&#xff0c;它通過為每個線程創建變量的獨立副本來解決多線程環境下的線程安全問題。 Thread └── ThreadLocalMap (threadLocals) // 每個線程持有的專屬Map├── Entry[] tab…

【筆記】結合 Conda任意創建和配置不同 Python 版本的雙軌隔離的 Poetry 虛擬環境

如何結合 Conda 任意創建和配置不同 Python 版本的雙軌隔離的Poetry 虛擬環境&#xff1f; 在 Python 開發中&#xff0c;為不同項目配置獨立且適配的虛擬環境至關重要。結合 Conda 和 Poetry 工具&#xff0c;能高效創建不同 Python 版本的 Poetry 虛擬環境&#xff0c;接下來…