資料庫設計優化

来源:https://www.cnblogs.com/slsectyoufromwrold/archive/2019/04/26/10773776.html
-Advertisement-
Play Games

物理設計: 選擇合適的資料庫管理系統。 考慮因素:成本,業務場景,開發語言,功能,操作系統等。 選擇合適的資料庫管理系統。 考慮因素:成本,業務場景,開發語言,功能,操作系統等。 Oracle 2.定義資料庫,表及欄位,要符合命名規範。 選擇存儲引擎:這裡以MySQL為例 選擇存儲引擎:這裡以MyS ...


物理設計:

  1. 物理設計要做什麼?
    • 選擇合適的資料庫管理系統。
    • 考慮因素:成本,業務場景,開發語言,功能,操作系統等。
資料庫類型 成本 開發語言 支持系統 業務場景

Oracle

商業型 php,java,python等 windows/liunx系統 企業級
SQLServer 商業型 .NET,C#等 只支持windows系統 企業級
MySQL 開源型 php,java,python等 windows/liunx系統 中小型
PgSQL 開源型 php,java,python等 windows/liunx系統 中小型

2.定義資料庫,表及欄位,要符合命名規範。

    • 選擇存儲引擎:這裡以MySQL為例
存儲引擎 索引 事務 鎖粒度 主要應用 忌用
MyISAM 支持 不支持 支持併發插入的表級鎖 select,insert高負載 讀寫並用
InnoDB 支持 支持 支持MVCC的行級鎖 事務處理
MEMORY 支持 不支持 表鎖 中間計算,靜態數據 大型數據集,持久性存儲
Archive 不支持 不支持 行級鎖 日誌記錄,聚合分析,只支持select,insert操作 隨機讀取,刪除
Ndb cluster 支持 支持 行級鎖 高可用集群 典型引用
    • 表及欄位命名規範
      1. 可讀性:命名可讀性強
        • 舉例:列名nickname和nick_name相比,後者更加清晰明瞭,看起來更加舒服一點。
      2. 表意性:見名知意
        • 舉例:列名col1和user_name相比,後者更加具有直觀性,可以讓我們一眼就知道當前列名所代表的意思和可能的數據類型
      3. 敏感性:不能與資料庫專有欄位命名衝突
        • 舉例:MySQL中 有user表,所以我們自己創建用戶表時,儘量不使用user命名,可以加一個首碼比如資料庫縮寫_user。

3.根據選擇的資料庫管理系統選擇合適的數據類型

    • 常用數據類型及占用空間
列類型 存儲空間
TINYINT 1個位元組
SMALLINT 2個位元組
MEDIUMINY 3個位元組
INT 4個位元組
BINGINT 8個位元組
DATE 3個位元組
DATETIME 8個位元組
TIMESTAMP 4個位元組
CHAR(M) M位元組,1<= M <=255
VARCHAR(M) L+1位元組,在此 L < = M 和  1 <=M <= 255
FLOAT 4位元組
DOUBLE 8位元組
DECIMAL 對DECIMAL(M,D) ,如果M>D,為M+2否則為D+2
    • 欄位類型的選擇的原則
  1. 當一個列可以選擇多種數據類型的時候,優先考慮數字類型,其次是日期類型和二進位類型,最後是字元類型。
  2. 對於相同的數據類型,應考慮占用空間較小的數據類型。
    • 欄位類型的選擇的原則依據
  1. 在對數據進行比較(查詢條件,JOIN條件及排序)操作時,同樣的數據,字元處理往往比數字處理效率要低,因為字元要參考數據字典進行比較,數字就不需要。
  2. 在資料庫中,數據處理以頁為單位,列的長度越小,一頁中存儲的數據就越多,載入相同的數據時的頁數就相對較小,速度會更快。
    • 如何具體選擇欄位類型?
  1. char和varchar該如何選擇?
    • char用於數據長度差不多是一致的,基本都在一個小區間內波動或者列中最大數據長度小於50位元組。
    • varchar用於數據長度變化較大,不能預知其具體長度的數據。
  2. decimal和float該如何選擇?
    • decimal用於存儲精確數據,精度最高,但是占用空間很大。
    • float占用空間比decimal小,適用於非精確數據,但會丟失數據精度。
  3. 時間類型如何存儲?
    • 使用int:int 是從 1970 年開始累加的,但是 int 支持的範圍是 1901-12-13 到 2038-01-19 03:14:07,如果需要更大的範圍需要設置為 bigInt。但是這個時間不包含毫秒,如果需要毫秒,還需要定義為浮點數。
    • 使用timestamp:記錄經常變化的更新 / 創建 / 發佈 / 日誌時間 / 購買時間 / 登錄時間 / 註冊時間等,並且是近來的時間,夠用,時區自動處理,比如說做海外購或者業務可能拓展到海外。
    • 使用datetime:記錄固定時間如伺服器執行計劃任務時間 / 健身鍛煉計劃時間等,在任何時區都是需要一個固定的時間要做某個事情。
    • 資料庫設計的其他註意事項
  1. 如何選擇主鍵?
    • 區分業務主鍵和資料庫主鍵:
      • 業務主鍵:用於標識業務數據,進行表與表之間的關聯。
      • 資料庫主鍵:為了優化數據存儲和查找。若沒有設置資料庫主鍵,則InnoDB引擎會自動生成6個位元組的隱含主鍵。
    • 考慮主鍵是否要自動順序增長:部分資料庫是按照主鍵的順序邏輯存儲的。
    • 主鍵的欄位類型所占用的空間要儘可能小:對於使用聚集索引方式存儲的表,每個索引都會附加上主鍵信息。
  2. 避免使用外鍵(避免使用資料庫來提供外鍵約束功能):限於互聯網項目
    • 在高併發業務中,使用外鍵約束會降低數據導入的效率,增加維護成本。
    • 建議使用邏輯外鍵,事實上在資料庫中並沒有設置外鍵約束,但在項目上都認為這是外鍵。由程式來維護外鍵約束,而不是資料庫伺服器本身來實現該功能。
    • 相關聯的列要建立索引,增加查找效率。
    • 該怎麼創建表就怎麼創建表,只是沒有了FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)該條外鍵約束命令。

例如:使用資料庫創建外鍵約束

CREATE TABLE `m_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `user_name` varchar(50) NOT NULL DEFAULT '' COMMENT '用戶名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `m_order` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `total_price` decimal(10,2) NOT NULL DEFAULT '0.00',
  `user_id` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  CONSTRAINT `for_indx_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

      不使用資料庫創建外鍵約束:

CREATE TABLE `m_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `user_name` varchar(50) NOT NULL DEFAULT '' COMMENT '用戶名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `m_order` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `total_price` decimal(10,2) NOT NULL DEFAULT '0.00',
  `user_id` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `idx_user_id` (`user_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 3.避免使用觸發器

    • 觸發器是一個隱藏的存儲過程,因為它不需要參數,不需要顯示調用,往往在你不知情的情況下已經做了很多操作,無形中增加了系統的複雜性。
    • 涉及到複雜的邏輯的時候,觸發器的嵌套是避免不了的,如果再涉及幾個存儲過程,再加上事務等等,很容易出現死鎖現象。
    • 存儲過程的致命傷在於移植性,存儲過程不能跨庫移植,在後期系統升級維護時難度加大。

    4.謹慎使用預留欄位

    • 無法準確的知道預留欄位的類型。
    • 無法知道預留欄位中所存儲的內容。
    • 後期維護預留欄位的成本高。

      建議:

    1. “按需設計”,在經過詳細有效的分析之後,在數據表中只放置必要的欄位,而不要留出大量的備用欄位。
    2. 如果數量很少,而且信息的性質與原表密切相關,那麼就可以直接在原表上動態增加欄位,並將相關的數據更新進去
    3. 如果數量較大,或者並非是原表對象至關重要的屬性,那麼就可以新增一個表,然後通過鍵值連接起來。

4.反範式化設計。

    • 什麼是反範式化?
      • 適當的違反的範式的要求,允許少量的數據冗餘,用空間換取時間。
    • 優點:增加查詢效率。

  以上僅為本人學習過程中的知識總結,若有錯誤,還請諸位不吝賜教。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 如果執行線上項目拷下來sqlserver的.sql的資料庫腳本文件,如果文件較大時,那麼就會報錯記憶體不足之類的。 這時可以在命令提示符使用命令來執行腳本文件。切記,執行前先改一下資料庫存放位置! 命令:osql -S . ,1433 -U sa -P 123 -i C:\Users\Cheng\De ...
  • 2.2 鏈接:mysql --host=localhost --port=3306 --user=root --password mysql -u root -p 斷開鏈接:exit / ctrl + d 可以執行以分隔符; \g \G結尾的命令,;或\g對應的輸出水平顯示,\G對應的輸出垂直顯示 ...
  • 下麵為您介紹mysql觸發器new old的相關知識,供您參考學習,如果您在mysql觸發器方面遇到過類似的問題,不妨一看,相信對您會有所幫助。 mysql觸發器new old: "NEW . column_name"或者"OLD . column_name".這樣在技術上處理(NEW | OLD ...
  • 錯誤SQL 查詢:編輯SHOWFULLFIELDSFROM`表`FROM`資料庫`;MySQL 返回:#1030 - Got error 28 from storage engine根據返回值,可以判斷應該是某掛在分區空間已滿造成。[root@websites ~]# df -lhFilesyste ...
  • 1.binlog日誌基本知識 MySQL的二進位日誌binlog可以說是MySQL最重要的日誌,它記錄了所有的DDL和DML語句(除了數據查詢語句select),以事件形式記錄,還包含語句所執行的消耗的時間。 binlog有三種格式:Statement、Row以及Mixed。分別是:基於SQL語句的 ...
  • 1. 硬體優化 1.1 記憶體(Memory) 記憶體是最重要的因素,因為它允許您調整伺服器系統變數。更多的記憶體意味著可以將更大的密鑰和表緩存存儲在記憶體中,從而減少磁碟訪問速度,降低一個數量級。 如果未將伺服器變數設置為使用額外的可用記憶體,則僅添加更多記憶體可能不會帶來顯著改進。 在主板上使用更多RAM插 ...
  • spark的機器學習庫,包含常見的學習演算法和工具如分類、回歸、聚類、協同過濾、降維等使用演算法時都需要指定相應的數據集,下麵為大家介紹常用的spark ml 數據類型。1.本地向量(Local Vector)存儲在單台機器上,索引採用0開始的整型表示,值採用Double類型的值表示。Spark MLl ...
  • 1. 在where 從句,group by 從句,order by 從句,on 從句中出現的列; 2. 索引欄位越小越好; 3. 離散度大的列放到聯合索引的前面;比如: select * from payment where staff_id = 2 and customer_id = 236; 針 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...