MySQL表添加了一個欄位,竟然導致數據無法寫入,反思

  • 2019 年 11 月 11 日
  • 筆記

這是學習筆記的第 2152 篇文章

今天有一個同事通過即時通訊工具找我,說需要做一個數據變更操作,我一看需求很簡單,是新增了一個列,需要創建相關的索引。

對於SQL自動化上線,目前算是到了收穫的時段,從近期的工單情況來看,很多業務需求都從平台化的工單操作轉向了自動化單據,按照最新的數據統計結果,假設有150個工單,那麼100個左右都是自動化流程完成的,佔比近70%。

這個工單的操作是目前自動化不支援的,因為需求是刪除已有的索引,然後添加新的索引欄位。

當我看到問題的時候,我感覺到一種異常,但是又實在說不清楚,所以準備當面溝通下。

表結構資訊如下:

CREATE TABLE `data_stat` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`day` int(8) NOT NULL DEFAULT '0',

`kind` varchar(10) NOT NULL DEFAULT '',

`netid` varchar(3) NOT NULL DEFAULT '',

`item` varchar(10) NOT NULL DEFAULT '' ,

`value` varchar(20) NOT NULL DEFAULT '',

`room` varchar(10) NOT NULL DEFAULT 'null' ,

PRIMARY KEY (`id`),

KEY `idx_day_netid` (`day`,`kind`,`netid`,`item`)

) ENGINE=InnoDB AUTO_INCREMENT=55158 DEFAULT CHARSET=utf8 ;

大體的業務含義是對每一天的登錄數據進行統計,原本是3個維度(kind,netid,item),現在多了一個維度(room)。

舉個小例子,數據可以這樣描述:

在2019-01-01(day)這一天用戶通過手機(kind)登錄了網站,使用的是5G手機(netid),連接的就近站點(room)是北京,在線時長(item)為5分鐘(value)。

此時我需要了解的是業務的查詢模型,即通常都有哪些場景的查詢,而一旦這個room新欄位在複合索引中,而如果條件不滿足,則這個索引列不會被用到,其實效果更糟。

而通過溝通,我驚奇的發現業務對於這個表的使用是有問題的。他說如果不添加索引欄位room,業務就寫入不了數據了。

這個大大超出了我的預期,大家可以仔細看下這條SQL,按照我剛剛描述的場景,是否能夠理解。

經過溝通,理解了這個業務場景,總算是明白了為什麼業務寫入不了數據。

可以使用如下的兩條數據描述來說明:

第1條記錄:

2019-01-01(day)用戶通過手機(kind)登錄了網站,使用的是5G手機(netid),連接的就近站點(room)是北京,在線時長(item)為5分鐘(value)

第2條記錄:

2019-01-01(day)用戶通過手機(kind)登錄了網站,使用的是5G手機(netid),連接的就近站點(room)是北京,在線時長(item)為15分鐘(value)

在這種情況下,因為欄位(day,kind,netid,item)是唯一性索引,那麼第2條記錄對應的數據是無法寫入的。

所以按照這種設計,如果後續還有新的欄位,那索引就需要橫向擴展了,所以對於這個問題,我提出了改進建議。

索引確實需要重建,根據業務回饋的查詢場景,其實添加非唯一性索引(`day`,`netid`,`room`)已經足夠覆蓋目前的查詢,而更有意義的是:數據寫入不會因為索引設計不合理/新增業務欄位而導致數據無法寫入。

所以在明確了需求之後,幫業務同學重建了索引,這個問題的處理就告一段落。

這個問題帶給我的總結就是:

  1. 對於潛在的問題,第一要旨就是參考標準,如果違反了標準,我們可以很快發現潛在問題,而不是屈從於被動響應業務。
  2. 對於溝通,我們儘可能避免一些聊天式溝通,越是不夠明確清晰,我們的溝通成本反而更高,所以對於一些模糊問題,幾句話解釋不清楚的,我都喜歡當面溝通。
  3. 理解業務需求的深層次含義。這個業務開始的回饋是很緊急,通過熟悉業務後的改進來看,其實和開始的描述是有偏差的,業務緊急的深層次含義其實是業務因為新增欄位導致寫入不了數據了,所以迫切需要重建索引。而我們理解這個問題的出發點是基於數據統計查詢。而幫助業務解決了這個問題之後,對他們來說,收益更大,所以在溝通中也就淡化了這種緊急度。
  4. 需要換位思考,從熟悉業務的角度來進行優化調整。在這個過程中,我是本著幫他的態度去理解這個問題的,在溝通中不斷的調整自己的問題分析方向,最終發現這個問題,解決這個問題的過程其實是無法預料到這麼多潛在的問題的,而逐步理解了業務,也就掌握了主動性。
  5. 索引優化的知識補充,通過這個問題,無論是歷史遺留還是新人犯的錯誤,其實都從側面反映出我們需要提供一些可供參考的技術建議,這是一個持續改進的過程。