1. 程式人生 > >MySQL基礎篇(02):從五個維度出發,審視表結構設計

MySQL基礎篇(02):從五個維度出發,審視表結構設計

本文原始碼:GitHub·點這裡 || GitEE·點這裡

一、資料場景

1、表結構簡介

任何工具類的東西都是為了解決某個場景下的問題,比如Redis快取系統熱點資料,ClickHouse解決海量資料的實時分析,MySQL關係型資料庫儲存結構化資料。資料的儲存則需要設計對應的表結構,清楚的表結構,有助於快速開發業務,和理解系統。表結構的設計通常從下面幾個方面考慮:業務場景、設計規範、表結構、欄位屬性、資料管理。

2、使用者場景

例如儲存使用者基礎資訊資料,通常都會下面幾個相關表結構:使用者資訊表、單點登入表、狀態管理表、支付賬戶表等。

  • 使用者資訊表

儲存使用者三要素相關資訊:姓名,手機號,身份證,登入密碼,郵箱等。

CREATE TABLE `ms_user_center` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '使用者ID',
  `user_name` varchar(20) NOT NULL COMMENT '使用者名稱',
  `real_name` varchar(20) DEFAULT NULL COMMENT '真實姓名',
  `pass_word` varchar(32) NOT NULL COMMENT '密碼',
  `phone` varchar(20) NOT NULL COMMENT '手機號',
  `email` varchar(32) DEFAULT NULL COMMENT '郵箱',
  `head_url` varchar(100) DEFAULT NULL COMMENT '使用者頭像URL',
  `card_id` varchar(32) DEFAULT NULL COMMENT '身份證號',
  `user_sex` int(1) DEFAULT '1' COMMENT '使用者性別:0-女,1-男',
  `create_time` datetime DEFAULT NULL COMMENT '建立時間',
  `update_time` datetime DEFAULT NULL COMMENT '更新時間',
  `state` int(1) DEFAULT '1' COMMENT '是否可用,0-不可用,1-可用',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='使用者表';
  • 單點登入表

用意是在多個業務系統中,使用者登入一次就可以訪問所有相互信任的業務子系統,是聚合業務平臺常用的解決方案。

CREATE TABLE `ms_user_sso` (
  `user_id` int(11) NOT NULL COMMENT '使用者ID',
  `sso_id` varchar(32) NOT NULL COMMENT '單點資訊編號ID',
  `sso_code` varchar(32) NOT NULL COMMENT '單點登入碼,唯一核心標識',
  `log_ip` varchar(32) DEFAULT NULL COMMENT '登入IP地址',
  `create_time` datetime DEFAULT NULL COMMENT '建立時間',
  `update_time` datetime DEFAULT NULL COMMENT '更新時間',
  `state` int(1) DEFAULT '1' COMMENT '是否可用,0-不可用,1-可用',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='使用者單點登入表';
  • 狀態管理表

系統使用者在使用時候可能出現多個狀態,例如賬戶凍結、密碼鎖定等,把狀態聚合到一起,可以更加方便的管理和驗證。

CREATE TABLE `ms_user_status` (
  `user_id` int(11) NOT NULL COMMENT '使用者ID',
  `account_status` int(1) DEFAULT '1' COMMENT '賬戶狀態:0-凍結,1-未凍結',
  `real_name_status` int(1) DEFAULT '0' COMMENT '實名認證狀態:0-未實名,1-已實名',
  `pay_pass_status` int(1) DEFAULT '0' COMMENT '支付密碼是否設定:0-未設定,1-設定',
  `wallet_pass_status` int(1) DEFAULT '0' COMMENT '錢包密碼是否設定:0-未設定,1-設定',
  `wallet_status` int(1) DEFAULT '1' COMMENT '錢包是否凍結:0-凍結,1-未凍結',
  `email_status` int(1) DEFAULT '0' COMMENT '郵箱狀態:0-未啟用,1-啟用',
  `message_status` int(1) DEFAULT '1' COMMENT '簡訊提醒開啟:0-未開啟,1-開啟',
  `letter_status` int(1) DEFAULT '1' COMMENT '站內信提醒開啟:0-未開啟,1-開啟',
  `emailmsg_status` int(1) DEFAULT '0' COMMENT '郵件提醒開啟:0-未開啟,1-開啟',
  `create_time` datetime DEFAULT NULL COMMENT '建立時間',
  `update_time` datetime DEFAULT NULL COMMENT '更新時間',
  `state` int(1) DEFAULT '1' COMMENT '是否可用,0-不可用,1-可用',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='使用者狀態表';
  • 支付賬戶表

使用者交易的核心表,儲存使用者相關的賬戶資金資訊。

CREATE TABLE `ms_user_wallet` (
  `wallet_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '錢包ID',
  `user_id` int(11) NOT NULL COMMENT '使用者ID',
  `wallet_pwd` varchar(32) DEFAULT NULL COMMENT '錢包密碼',
  `total_account` decimal(20,2) DEFAULT '0.00' COMMENT '賬戶總額',
  `usable_money` decimal(20,2) DEFAULT '0.00' COMMENT '可用餘額',
  `freeze_money` decimal(20,2) DEFAULT '0.00' COMMENT '凍結金額',
  `freeze_time` datetime DEFAULT NULL COMMENT '凍結時間',
  `thaw_time` datetime DEFAULT NULL COMMENT '解凍時間',
  `create_time` datetime DEFAULT NULL COMMENT '建立時間',
  `update_time` datetime DEFAULT NULL COMMENT '更新時間',
  `state` int(1) DEFAULT '1' COMMENT '是否可用,0-不可用,1-可用',
  PRIMARY KEY (`wallet_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='使用者錢包';

二、設計規範

1、涉及模組

通過上面幾個表設計的案例,可以看到表設計關聯到資料庫的各個方面知識:資料型別,索引,編碼,儲存引擎等。表設計是一個很大的命題,不過也遵循一個基本規範:三正規化。

2、三正規化

  • 基礎概念

一正規化

表的列的具有原子性,不可再分解,即列的資訊,不能分解,關係型資料庫MySQL、Oracle等自動的滿足。

二正規化

每個事實的資料記錄只會出現一次, 不會冗餘, 通常設計一個主鍵來實現。

三正規化

要求一個表中不包含已經存在於其它表的非主鍵資訊,例如部門和員工的資訊,員工表包含部門表的主鍵ID,則可以關聯獲取相關資訊,沒必要在員工表儲存相關資訊。

  • 優缺點對比

正規化化設計

正規化化結構設計通常更新快,因為冗餘資料較少,表結構輕巧,也更好的寫入記憶體中。但是查詢起來涉及到關聯,代價非常高,非常損耗查詢效能。

反正規化化設計

所有的資料都在一張表中,避免關聯查詢,索引的有效性更高,但是資料的冗餘性極高。

  • 建議結論

上述的兩種設計方式在實際開發中都是不存在的,在實際開發中都是混合使用。比如彙總統計,快取資料,都會基於反正規化化的設計。

三、欄位屬性

合適的欄位型別對於高效能來說非常重要,基本原則如下:簡單的型別佔用資源更少;在可以正確儲存資料的情況下,選最小的資料型別。

1、資料型別選擇

  • 整數型別

TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT,根據資料類型範圍合理選擇即可。

  • 實數型別

FLOAT、DOUBLE、DECIMAL,建議資金貨幣相關型別使用高精度DECIMAL儲存,或者把資料成倍擴大為整數,採用BIGINT儲存,不過處理相對麻煩。

  • 字元型別

CHAR、VARCHAR,長度不確定建議採用VARCHAR儲存,不過VARCHAR型別需要額外開銷記錄字串長度。CHAR適合儲存短字元,或者定長字串,例如MD5的加密結構。

  • 時間型別

DATETIME、TIMESTAMP,DATETIME儲存大範圍的值,精度秒。TIMESTAMP以時間戳的格式,範圍相對較小,效率也相對較高,所以通常情況建議使用。

MySQL的欄位型別有很多種,可以根據資料特性選擇合適的,這裡只描述常見的幾種型別。

2、基礎用法操作

  • 資料型別

修改欄位型別

ALTER TABLE ms_user_sso MODIFY state CHAR(1) DEFAULT '0' ;

ALTER TABLE ms_user_sso 
MODIFY state INT(1) DEFAULT '1' COMMENT '狀態:0不可用,1可用';

修改名稱位置

ALTER TABLE ms_user_sso 
CHANGE log_ip login_ip VARCHAR(32) AFTER update_time ;
  • 索引使用

索引型別:主鍵索引,普通索引,唯一索引,組合索引,全文索引。這裡演示普通索引的操作。MySQL的核心模組,後續詳說。

新增索引

ALTER TABLE ms_user_wallet ADD INDEX user_id_index(user_id) ;
CREATE INDEX state_index ON ms_user_wallet(state) ;

檢視索引

SHOW INDEX FROM ms_user_wallet;

刪除索引

DROP INDEX state_index ON ms_user_wallet ;

修改索引

不具有真正意義上的修改,可以把原有的索引刪除之後,再次新增索引。

  • 外來鍵關聯

用處:外來鍵關聯的作用保證多個數據表的資料一致性和完整性,建表時先有主表,後有從表;刪除資料表,需要先刪從表,再刪主表。複雜場景不建議使用,實際開發中用的也不多。

新增外來鍵

ALTER TABLE ms_user_wallet 
ADD CONSTRAINT user_id_out_key FOREIGN KEY(user_id) REFERENCES ms_user_center(id) ;

刪除外來鍵

ALTER TABLE ms_user_wallet DROP FOREIGN KEY user_id_out_key ;

四、表結構管理

1、檢視結構

DESC ms_user_status ;
SHOW CREATE TABLE ms_user_status ;

2、欄位結構

  • 新增欄位
ALTER TABLE ms_user_status 
ADD `delete_time` datetime DEFAULT NULL COMMENT '刪除時間' ;
  • 刪除欄位
ALTER TABLE ms_user_status DROP COLUMN delete_time ;

3、修改表名

ALTER TABLE ms_user_center RENAME ms_user_info ;

4、儲存引擎

  • 儲存引擎
SELECT VERSION() ; SHOW ENGINES ;

MySQL 5.6 支援的儲存引擎有InnoDB、MyISAM、Memory、Archive、CSV、BLACKHOLE等。一般預設使用InnoDB,支援事務管理。該模組MySQL核心,後續詳解。

  • 修改引擎

資料量大的場景下,儲存引擎修改是一個難度極大的操作,容易會導致表的特性變動,引起各種後續反應,後續會詳說。

ALTER TABLE ms_user_sso ENGINE = MyISAM ;

5、修改編碼

表字符集預設使用utf8,通用,無亂碼風險,漢字3位元組,英文1位元組,utf8mb4是utf8的超集,有儲存4位元組例如表情符號時使用。

  • 檢視編碼
SHOW VARIABLES LIKE 'character%';
  • 修改編碼
ALTER TABLE ms_user_sso DEFAULT CHARACTER SET utf8mb4; 

五、資料管理

1、增刪改查

新增資料

INSERT INTO ms_user_sso (
    user_id,sso_id,sso_code,create_time,update_time,login_ip,state
)
VALUES
    (
        '1','SSO7637267','SSO78631273612',
        '2019-12-24 11:56:57','2019-12-24 11:57:01','127.0.0.1','1'
    );

更新資料

UPDATE ms_user_sso SET 
 user_id = '1',sso_id = 'SSO20191224',sso_code = 'SSO20191224',
 create_time = '2019-11-24 11:56:57',update_time = '2019-11-24 11:57:01',
 login_ip = '127.0.0.1',state = '1'
WHERE user_id = '1';

查詢資料

一般情況下都是禁止使用 select* 操作。

SELECT user_id,sso_id,sso_code,create_time,update_time,login_ip,state 
FROM ms_user_sso WHERE user_id = '1';

刪除資料

DELETE FROM ms_user_sso WHERE user_id = '2' ;

不帶where條件,就是刪除全部資料。原則上不允許該操作,優化篇會詳解。TRUNCATE TABLE也是清空表資料,但是佔用的資源相對較少。

2、資料安全

  • 不可逆加密

這類加密演算法,多用來做資料驗證操作,比如常見的密碼驗證。

SELECT MD5('cicada')='94454b1241ad2cfbd0c44efda1b6b6ba' ;
SELECT SHA('cicada')='0501746a2e4fd34e1d14015fc4d58309585edc7d';
SELECT PASSWORD('smile')='*B4FB95D86DCFC3F33A3852714DC742C77504479D' ;
  • 可逆加密

安全性要求高的系統,需要做三級等保,對資料的安全性極高,資料在儲存時必須加密入庫,取出時候需要解密,這些就需要可逆加密。

SELECT DECODE(ENCODE('123456','key_salt'),'key_salt') ;
SELECT AES_DECRYPT(AES_ENCRYPT('cicada','salt123'),'salt123');

上述資料安全的管理,也可以基於應用系統的服務(程式碼)層進行處理,相對專業的流程是從資料生成源頭處理,規避資料傳遞過程洩露,造成不必要的風險。

六、原始碼地址

GitHub·地址
https://github.com/cicadasmile/mysql-data-base
GitEE·地址
https://gitee.com/cicadasmile/mysql-data-base

相關推薦

MySQL基礎(02)維度出發審視結構設計

本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、資料場景 1、表結構簡介 任何工具類的東西都是為了解決某個場景下的問題,比如Redis快取系統熱點資料,ClickHouse解決海量資料的實時分析,MySQL關係型資料庫儲存結構化資料。資料的儲存則需要設計對應的表結構,清楚的表結構,有助於快

MySQL基礎(03)系統和自定義函式總結觸發器使用詳解

本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、系統封裝函式 MySQL 有很多內建的函式,可以快速解決開發中的一些業務需求,大概包括流程控制函式,數值型函式、字串型函式、日期時間函式、聚合函式等。以下列出了這些分類中常用的函式。 1、控制流程函式 case...when 根據值判斷返

MySQL基礎(04)儲存過程和檢視用法和特性詳解

本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、儲存過程 1、概念簡介 儲存程式是被儲存在伺服器中的組合SQL語句,經編譯建立並儲存在資料庫中,使用者可通過儲存過程的名字呼叫執行。儲存過程核心思想就是資料庫SQL語言層面的封裝與重用性。使用儲存過程可以較少應用系統的業務複雜性,但是會增加資

MySQL基礎(05)邏輯架構圖解和InnoDB儲存引擎詳解

> 本文原始碼:[GitHub·點這裡](https://github.com/cicadasmile/mysql-data-base) || [GitEE·點這裡](https://github.com/cicadasmile/mysql-data-base) # 一、MySQL邏輯架構 ##

Java基礎(02)特殊的String類和相關擴充套件API

> 本文原始碼:[GitHub·點這裡](https://github.com/cicadasmile/java-base-parent) || [GitEE·點這裡](https://gitee.com/cicadasmile/java-base-parent) # 一、String類簡介 ##

MySQL基礎(06)事務管理鎖機制案例詳解

本文原始碼:[GitHub·點這裡](https://github.com/cicadasmile/mysql-data-base) || [GitEE·點這裡](https://github.com/cicadasmile/mysql-data-base) # 一、鎖概念簡介 ## 1、基礎描述 鎖

MySQL基礎(07)使用者和許可權管理日誌體系簡介

本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、MySQL使用者 1、基礎描述 在資料庫的使用過程中,使用者作為訪問資料庫的鑑權因素,起到非常重要的作用,安裝MySQL時會自動生成一個root使用者,作為資料庫管理員,擁有所有許可權。在多使用者的應用場景下,可能需要給不同的使用者分配不同的許可

MySQL進階(01)基於多維度分析伺服器效能

本文原始碼:[GitHub·點這裡](https://github.com/cicadasmile/mysql-data-base) || [GitEE·點這裡](https://gitee.com/cicadasmile/mysql-data-base) # 一、伺服器效能簡介 ## 1、效能定義

彙編基礎練習題6鍵盤輸入數字字元利用程式得到對應的數值在利用2中的輸出子程式將得到的數值輸出。

彙編基礎練習題6: 從鍵盤輸入數字字元,利用程式得到對應的數值,在利用練習題2中的輸出子程式,將得到的數值輸出。 編譯工具:Masm for Windows 整合實驗環境2012.5 (附帶一個工具下載地址https://download.csdn.net/download/qq_3

維度來談談視覺設計師如何闡述設計風格

設計風格是一種很虛的東西,對於大部分的 UI 設計師來說,都是如此。 相信很多人都是在一家小型的網際網路公司做設計,估計還是公司唯一的設計師,同時對設計風格又拿捏不定,總感覺是跟著產品經理或老闆的思路去做設計。比如老闆的要求是“大氣”,誰 TM 知道這“大氣”指的

#圖文詳解實際和理論出發帶你瞭解Java中的多執行緒

這裡並沒有講什麼新東西,只是把多執行緒一些知識來個總結。大家懂得可以複習複習,還有些童鞋對多執行緒朦朧的可以拿這個做為入門~ 舉個栗子說明啥是多執行緒:玩遊戲,前面一堆怪,每個怪都是一個執行緒,你射了一槍,子彈飛出去了,這顆子彈也是一個執行緒。你開啟你的程序管理,看到你遊戲的後臺程序,這就是程序

【C語言】用結構體陣列指標完成有三學生資訊存放在結構體陣列中要求輸出全部資訊

//用結構體陣列指標完成:有三個學生資訊,存放在結構體陣列中,要求輸出全部資訊 #include <stdio.h> struct Stu { int num; char name[2

方面解說數字技術對就業的有怎樣的影響你知道嗎?

    一直以來人們對技術進步又愛又恨,技術進步所帶來的糾結在歷史上不勝列舉。     公元一世紀,羅馬皇帝韋巴薌拒絕採用新機器運輸神廟石柱,因為這會搶了工人的飯碗。     十八世紀工業革命後,英國工人為奪回被機器代替的工作崗位,開始搗毀機器,發洩憤怒,掀起“盧德運動”

Docker基礎11Compose部署tomcat及mysql

1、compose不是tomcat容器 1、獲取映象 [[email protected] /]# docker pull tomcat 2、建立目錄 [[email protected] /]# mkdir /opt/docker/tomcat -p [[ema

IC設計基礎系列之CDC6CMOS到觸發器(一)

  我們或多或少知道,電晶體在數位電路中的主要作用就是一個電子開關,通過電壓或者電流,控制這個“開關”開還是關。電晶體大概有兩種分類:一種是雙極性電晶體(BJT,bipolar  junction  transistor),另外一種是金屬-氧化物-半導體場效應電晶體(MOSFET或者MOS,metal-ox

程式設計必備基礎知識|計算機組成原理(02)計算機的分類

計算機基礎方面的知識,對於一些非科班出身的同學來講,一直是他們心中的痛,而對於科班出身的同學,很多同學在工作之後,也意識到自身所學知識的不足與欠缺,想回頭補補基礎知識。關於計算機基礎的課程很多,內容繁雜,但無論是相關書籍還是大學課程,都有點脫離工作。特別地,計算機基礎知識體系龐雜,想要從零學習或者複習都耗時耗

Qt入門之基礎 ( 二 ) Qt項目建立、編譯、運行和發布過程解析

qt 5 對話 讓我 進度 qmake ctr deploy 設定 設置 轉載請註明出處:CN_Simo。 題解:   本篇內容主講Qt應用從創建到發布的整個過程,旨在幫助讀者能夠快速走進Qt的世界。   本來計劃是講解Qt源碼靜態編譯,如此的話讀者可能並不能清楚地知

Qt入門之基礎 ( 一 ) Qt4及Qt5的下載與安裝

mingw ins 第3版 點擊 調試 但我 關系 構建 eas 轉載請註明出處:CN_Simo. 導語: Qt是一個跨平臺的C++圖形界面應用程序框架。它提供給開發者建立圖形用戶界面所需的功能,廣泛用於開發GUI程序,也可用於開發非GUI程序。Qt很容易擴展,並

MySQL基礎

基礎 log sql基礎 image mage ges alt com images MySQL基礎篇