MySQL中的哥哥表、妹妹欄位,是什麼鬼?

2021-02-17 小姐姐味道

原創:小姐姐味道(微信公眾號ID:xjjdog),歡迎分享,轉載請保留出處。

晚上,我被叫進寬大的辦公室,總監正在煮茶。高壓鍋煮著長嘴茶壺,水蒸氣繚繞。領導舉手之間,淡黃茶水奔湧而出,倒立而下澆上茶葉,漏出兩杯茶水。

「喝茶?」領導推給我一杯,然後自己抿了一口。沉默良久,把顯示器轉到我這邊:「最近資料庫表出現了些有意思的東西,你來看看」。

我探著腦袋一瞧,心涼了半截。

時隔五年,又在項目裡見到哥哥表和妹妹欄位,著實讓我坐立不安。所謂哥哥表,就是名稱叫做gg的資料庫表,意為公共;所謂妹妹欄位,就是名稱叫做mm的表子段,意為密碼。比起shit mountain來,這些命名更讓人浮想聯翩,實為不規範之典範。

這麼魔幻的事情,不止一次出現,任何領導都會坐不住。可惜的是,一次次的會議,專項討論某一個SQL禁止條例,到最後還是大開方便之門,過往的規範承諾皆拋之腦外。

資料庫命名規範是最基礎的規範,連這個都沒做好,證明監管工作確實出現了紕漏。我趕緊掏出自己的手機,翻到xjjdog的文章,打算把資料庫要注意的點,給領導匯報一下。

也順便向大家匯報。

我把規範分成了統一的規範、索引規範、SQL規範、命名規範、安全規範、性能小Case等6個部分。

請聽我慢慢道來。

1. 統一的規範

首先,我們來一些通用的規範。這裡有很多是經驗值,如果你的資料庫所在的宿主機硬體,並不是十分的牛X,可以考慮再降低一下標準。

存儲引擎: 請統一使用innodb存儲引擎,特殊的資料庫引擎必須通過DBA的評審。

字符集:統一使用utf8字符集。這個要從應用程式、伺服器、資料庫的表、欄位等全部統一起來。注意:MySQL中的utf8mb4字符集,才是真正的utf8,請用這個。

作用範圍:不要在MySQL存儲大對象,比如圖片、音樂等;不要用MySQL做Gis運算、全文檢索;不使用存儲過程、觸發器、函數、外鍵,避免破壞資料庫的性能和擴展性。

使用上限:

單張表中索引數量不超過5個,單個索引中的欄位數不超過5個;varchar欄位最大值不超過1024;注意:VARCHAR(N)中的N表示字符數而非字節數2. 索引規範

索引是資料庫中非常重要的結構,可以加速數據的檢索。但索引是要佔用大量空間的,如果你的數據表裡面沒幾條記錄,就不必創建索引。比如2000條以下。

選擇性很小的欄位(低基數列),不要加索引。比如一些state,type,布爾判斷等。因為加了也沒用。

儘量讓索引的內容儘量的短!比較長的子段,要使用前綴索引。比如:title varchar (64) ,可以創建前綴索引 idx_title (title(16))。

合理利用索引的最左原則,合併相似的索引。比如 (a) (ab) (abc)三種索引需求,我們只需要創建abc這一個索引就ok了。

避免在索引列做計算(這將造成索引失效),比如 data_format(created_date),substring(short_name,0,6) = 'xjjdog'。

不能使用%前綴模糊查詢,因為無法使用索引,例如:WHERE name LIKE '%味道'。

不能使用資料庫端做全文檢索操作。雖然它支持,也不要這麼做。

索引的命名要有章可循:idx_前綴表明是普通索引,而 uk_前綴表明的是唯一索引。

3. SQL規範

建議在每個表中,添加下面三個欄位。其實,SpringBoot JPA,也建議你添加上這三個欄位。根據時間欄位,除了審計,還能夠做一些非常nice的遷移操作;version欄位是高並發下的樂觀鎖實現,UPDATE語句可以結合version欄位,避免並發操作造成的不一致情況。

version:「樂觀鎖」的版本標記,long型,默認為0

大多數欄位應該定義成not null的,並分配默認值,但是不要default null,因為資料庫無法索引null值。

複雜的SQL查詢語句,是絕對要避免的。我們所說的,就是慢查詢。慢查詢會佔用大量資源,並阻塞線程,應該見諒將大SQL拆分成多條簡單的SQL,減少數據的鎖定時間。

另外,不要在不同數據類型的欄位上進行比較,避免欄位類型轉換造成性能損失,這就要求我們在SQL語句中傳入的參數類型,和資料庫中所定義的類型是相同的。

禁止使用select *進行輸出,應該選擇具體的欄位進行輸出。除了避免無用的欄位造成傳輸上的性能損耗,還能在一定程度上避免敏感信息的洩漏。

SQL中避免出現now()、rand()、sysdate()、current_user()等不確定結果的函數。

禁止使用order by rand()。

插入語句,不要直接使用 nsert into table values(),而應該加入具體的欄位,否則無法適應資料庫變更情況。在做批量插入時,一次性操作100-200條就可以,沒必要把batch數量設置成上千上萬。

禁止非框架類業務代碼,直接調用set sql_mode或者set tx_isolation,禁止使用SELECT … FOR UPDAT,優先採用樂觀鎖實現。

多表關聯不要超過3個,儘量拆分成簡單的SQL處理。

大多數開發人員會在需要時寫UNION,這往往會導致執行一個排序來消除重複。應該儘量使用UNION ALL來代替UNION。

注意OR語句的一些改善情況。比如WHERE id=1 OR id=2可以 改寫為WHERE id IN(1,2)。在不同的欄位,可以將OR改寫為UNION ALL。

4. 命名規範

資料庫表和欄位的命名,不要使用駝峰命名方式。比如,不能叫saleOrder,而應該叫做sale_order。因為大多數資料庫,都不區分大小寫,下劃線命名會更安全。

這些命名,只能使用英文小寫字母、數字和下劃線,長度不超過17個字符。

命名應該有確切的含義。和代碼規範一樣,不允許使用a,b等無意義的字符串。不允許中文拼音縮寫、中英文混用等。

嚴禁出現哥哥表和妹妹欄位。

5. 安全安全安全

(1) 伺服器隔離 如果你的公司有多個環境,比如dev環境,測試環境等,就要做好相應的隔離。比如,不允許在線上環境直接進行開發和測試、禁止在線上做資料庫壓⼒力測試。這是非常重要的,避免了無謂的數據錯亂。如果條件允許,甚至可以做物理隔離,用不同的IP段進行區分。不長腦子的程式設計師有很多,你永遠不知道他們連的是哪個環境的資料庫。

(2)帳戶的權限 永遠不要在生產上,讓root帳號遠程可連。對不同的應用,應該分配不同的database,並建立相互隔離的帳號。

帳號默認開啟select/insert/update/delete/execute的權限就可以。create都不能放開,用根本上杜絕程式設計師們刪庫跑路的機會。

針對安全級別高的應用,應分配讀寫帳號。讀帳號去掉各種更新權限,只能做一些sql查詢。帳號命名方式上,可以加入_w或者_r後綴,表明它們的意圖。

對於SQL的傳入參數(數字,字符和混用)必須進行合法性檢查,防止SQL注入。業務應該提前準備好風險SQL語句,進行集中審核,負責後果自負。

6. 性能小case

如有自增欄位,請使用無符號型(unsigned)int或bigint 。優先使用更小的數據類型,比如:

數字用tinyint、smallint、mediumint、int、bigint類型;使用更小的數據類型,能用tinyint的就不用smallint,能用timestamp的就不用datetime類型;

不能使用tinyblob、mediumblob、blob和longblob類型欄位,對於表存在大欄位類型,應當考慮單獨拆分。

OLTP資料庫絕對要避免大事務和資料庫端運算,可以考慮使用NoSQL或者大數據計算平臺。

End

可以看到,我們規範裡,有些禁止的東西,其實最後還是用了。比如分區表、大欄位存儲、GIS操作。但這是和規範不衝突的。

規範,只定義了一些常見的可能會引起嚴重後果的操作禁止,然後將風險的事情,交給專業的人去做,並評估、控制風險點的規模。

規範定了,要執行才行。不論是人工的review,還是工具的檢測。如此,系統才能健康成長,程式設計師才能不加班,領導才能開上保時捷。

這時候,我匯報完畢,抬頭向領導望去。他的頭倚在真皮座椅後背上,已經沉沉的的睡了過去。我把外套輕輕脫下來,披在他身上,這才捧過自己的茶杯,咕咚一口喝了下去。雖然茶已經涼了,但醇香一直在嘴中繚繞。

作者簡介:小姐姐味道  (xjjdog),一個不允許程式設計師走彎路的公眾號。聚焦基礎架構和Linux。十年架構,日百億流量,與你探討高並發世界,給你不一樣的味道。我的個人微信xjjdog0,歡迎添加好友,進一步交流。

相關焦點

  • mysql怎麼處理大表在不停機的情況下增加欄位
    MySQL中給一張千萬甚至更大量級的表添加欄位一直是比較頭疼的問題,遇到此情況通常該如果處理?本文通過常見的三種場景進行案例說明。使用工具在線添加雖然Online DDL添加欄位時,表依舊可以讀寫,但是生產環境使用場景中對大表操作使用最多的還是使用工具pt-osc或gh-ost添加。
  • MySQL資料庫測試題
    以下哪條語句用於統計test表中的記錄總數?C、在Mysql提示符下輸入以下命令mysqldump -uroot -p1234 test>d:/db.sql4、下列SQL語句中,創建關係表的是?中創建book表,並添加id欄位和title欄位?
  • 資料庫基礎知識篇:MYSQL如何判斷某欄位是否包含某個字符串!
    在實際應用中,我們會遇到各種各樣的需求,這些需求都跟資料庫有著緊密的關係,在複雜的邏輯也只不過是增刪改查。其時,如果我們將資料庫中每一個欄位都看成是一個變量,即然是變量就可以運算,只要能運算,結果就是我們所需要的值。
  • MySQL 資料庫的哈希表-愛可生
    MySQL 哈希索引又基於哈希表(散列表)來實現,所以了解什麼是哈希表對 MySQL 哈希索引的理解至關重要。接下來,我們來一步一部介紹哈希表。1.數組在各個開發語言以及資料庫中都有類似的結構,類似下圖1:圖 1 展示了一個一維整數數組,數組的長度為 10,下標從 0-9, 每個下標對應不同的值。
  • MySQL 一千個不用 Null 的理由
    NULL是創建數據表時默認的,初級或不知情的或怕麻煩的程式設計師不會注意這點。很多人員都以為not null 需要更多空間,其實這不是重點。重點是很多程式設計師覺得NULL在開發中不用去判斷插入數據,寫sql語句的時候更方便快捷。2、是不是以訛傳訛?
  • Mysql資料庫的常用操作
    本文主要介紹mysql資料庫的查詢操作,捎帶腳增刪改操作。insert into:insert into table (欄位) values (數據)(數據)...insert into table values (數據)(數據)...
  • 一則MySQL慢日誌監控誤報的問題分析
    排查過幾次代碼層面的邏輯,沒有發現明顯的問題,幾次下來,問題依舊,這可激發了修正的念頭,決定認真看看到底是什麼原因。後端使用的是基於ORM的模式,數據都存儲在模型MySQL_slowlog_sql_history對應的表中。
  • MySQL分支資料庫MariaDB之CentOS安裝教程
    刪除匿名用戶,拒絕root遠程登錄(系統總是拒絕,這裡配置不起作用),刪除test,重新加載權限表。1.1.4 測試登錄:mysql -u root –p查看埠是否開啟成功:netstat -anpt | grep mysqld1.2 配置UTF字符集編碼1)vi /etc/my.cnf在 [mysqld
  • Mysql資料庫部分
    面試中我們經常會被要求做一份筆試題,筆試題通過後會有技術大佬來面試我們。在筆試題最後一般都是有一道關於mysql語句的問題,讓手寫出增、刪、改、查語句,今天我們就學習一下mysql語句。12.應儘量避免在 where 子句中對欄位進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:可以在num上設置默認值0,確保表中num列沒有null值,然後這樣查詢(在項目開發中,一開始我寫的查詢語句加了null判斷,一位前輩指點我要多思考,無論是代碼還是庫表,應遵『循精簡有效『的原則):
  • 100條MySQL規範,從入門到精通,很實用!
    >7、禁止在表中建立預留欄位預留欄位的命名很難做到見名識義 預留欄位無法確認存儲的數據類型,所以無法選擇合適的類型 對預留欄位類型的修改,會對表進行鎖定8、禁止在資料庫中存儲圖片,文件等大的二進位數據通常文件很大,會短時間內造成數據量快速增長,資料庫進行資料庫讀取時,通常會進行大量的隨機IO操作,文件很大時
  • MySQL 8.0 中的索引可以隱藏了…
    隱藏索引是什麼鬼? 隱藏索引 字面意思就是把索引進行隱藏,即不可見,它不是用來查詢優化的,所以它不會被優化器使用到。隱藏索引適用於除主鍵索引(顯示或者隱式設置)之外的索引,意味著主鍵索引是不能通過任何方式隱藏的。
  • EXCEL 與 MySQL 數據互通
    在日常工作中,數據表通常以 EXCEL 的形式存在,但有的時候有很多數據邏輯不適合在 EXCEL 中完成,通常會導入資料庫中進行操作,那麼如何實現 EXCEL 與 MySQL 資料庫交互使用?讓我們一起揭開迷霧!下載插件 為了使得 EXCEL 與 MySQL 順暢溝通,需要一些配置,即 MySQL  for EXCEL 插件。
  • MySQL敏感數據怎麼加密 數據加密解密教程
    準備工作為了便於後面對比,將各種方式的數據集存放在不同的表中。MySQL加密函數的方式2.1  MySQL加密將明文表中的數據插入到f_user_m中,同時對pwd密碼欄位進行加密存儲,注意要記住加密的字符串,因為解密的時候要用到這個值。
  • MySQL優化:定位慢查詢的兩種方法以及使用explain分析SQL
    一條SQL查詢語句在經過MySQL查詢優化器處理後會生成一個所謂的執行計劃,這個執行計劃展示了具體執行查詢的方式,比如多表連接的順序是什麼,對於每個表採用什麼訪問方法來具體執行查詢等等。本章的內容就是為了幫助大家看懂EXPLAIN語句的各個輸出項都是幹嘛使的,從而可以有針對性的提升我們查詢語句的性能。學習步驟定位慢查詢。
  • mysql性能分析explain之id詳解
    前言在mysql的編程世界裡,有時候我們往往需要對自己編寫的sql語句進行分析,來去查看sql的執行計劃,這個還是很有必要的。因為我們在開發中,往往需要從資料庫中查詢數據,當數據量一旦大的時候,這個時候就會出現查詢瓶頸,我們首先呢可能就會去查看我們的sql語句的執行過程,判斷是否可進行優化,那如何去定位分析呢?這個就是本文講到的使用explain工具來去定位分析。說明由於explain這個分析工具查詢出來的欄位過多,本文主要講第一部分,id的講解。
  • 聊聊mysql分組查詢group by以及分組條件having的用法
    今天和大家一起學習一下mysql的分組查詢group by的使用方法,也是重新回憶和複習一下。我們來看一下分組查詢的語法:1、語法:group by + 分組的欄位;下面我們來看一張學生表信息:我們現在需要實現這樣一個需求:1、按性別分組,分別查詢出男、女學生的數學平均分
  • MySQL 是怎麼死鎖的?
    起初業務程序思路是這樣的:投資人投資後,將金額隨機分為幾份,然後隨機從借款人表裡面選幾個,然後通過一條條select for update 去更新借款人表裡面的餘額等。,但id=5的記錄已經被鎖住了,鎖的等待在id=8的這裡不信請看Session3:mysql> select * from t3 where id=5 for update;鎖等待中Session4:mysql> select * from t3 where id=10 for update;+----+--
  • 總結零散的 MySQL 基礎知識
    CREATE:創建資料庫及其對象(如表,索引,視圖,存儲過程,函數和觸發器)ALTER:改變現有資料庫的結構DROP:從資料庫中刪除對象TRUNCATE:從表中刪除所有記錄,包括為記錄分配的所有空間都將被刪除COMMENT:添加注釋RENAME:重命名對象常用命令如下:# 建表 CREATE TABLE sicimike (
  • MySQL索引與索引優化
    每個表你最多可以建249個聚簇索引。聚簇索引需要量的硬碟空間和內存BTree 與 Hash 索引有什麼區別?MySQL索引類型: mysql 有4種不同的索引:主鍵索引(PRIMARY)數據列不允許重複,不允許為NULL,一個表只能有一個主鍵。
  • 什麼是ETL,如何使用spark,mysql,python構建大數據平臺
    1.數據提取-從類似或者不同的源中檢索數據來進行進一步的數據處理和數據存儲的過程。2.數據轉換-在數據處理過程中,將清除數據,並修改或刪除不正確或不正確的記錄。3.數據加載-將處理後的數據加載到目標系統中,例如數據倉庫或NoSQL或RDBMS。