數據庫設計-物理設計


數據庫設計

物理設計:

  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.反范式化設計。

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM