Storage 001 電商數據庫設計

【大概流程 】用戶登陸 》 選購商品 》 加入購物車 》 檢查庫存 》提交訂單    》  選擇在線支付  或 選擇貨到付款 》 發貨 mysql

 

【用戶模塊】註冊 登錄 nginx

【商品模塊】先後臺商品管理和瀏覽sql

【訂單模塊】訂單及購物車的生成管理數據庫

【倉配模塊】倉庫庫存和物流管理緩存

 

【數據庫實際開發模式】直接確立表名 字段 數據類型 。併發

 

【數據庫設計規範】運維

Mysql5.5 早期存儲引擎 Myisam 表,現代選擇 Innodb(支持事務、行級鎖、更好的恢復性、高併發)。數據庫設計

統一字符集 UTF-8 (mysql utf-8 漢字佔3字節 ,ascii佔1字節 )函數

全部表和字段 都要 comment ,維護數據字典。高併發

【單表數據量】控制在 500萬行內,易於修改表結構、備份、恢復 。

    【控制手段】歷史數據歸檔、分庫分表。

    【謹慎使用 mysql 分區表】物理上表現爲多個文件,在邏輯上爲一個表。選擇好分區鍵可致使跨分區查詢效率更低。

   【建議物理分表】適合大數據,IO

 

儘可能冷熱數據分離,減小表的寬度(最大4096列),

目的減小磁盤IO保證熱數據的內存緩存命中率,避免往緩存讀入無用的冷數據。

一般表現爲   【常常使用的列放到一塊兒,減小關聯查詢】

 

預留字段的危害 , 自己數據類型、命名都是模糊的,若是修改預留字段,致使表的鎖定,得不償失。

 

二進制數據(圖片、文件)不是存在數據庫的,使用vsftpd +nginx 。

 

禁止在線上作數據庫壓力測試,應該用專用壓力環境,畢竟有垃圾數據。開發 測試 生產 應該隔離。

 

① 命名   統一小寫字母並用下劃線分割。 

  長度不超過32個字符     庫 mc_userdb 表 user_account  

  臨時庫表   tmp+日期

  備份表 bak+日期

========================================

字段 類型、約束 怎麼肯定?

~ 儘可能全部列 NOT NULL

  比較和計算 須要判斷

 

 

~ 符合需求節省空間

【第一 】將字符串轉成數字類型存儲  INET_ATON('255.255.255.255') = 429496729,

【第二】不可能負數的 就直接使用無符號類型,多一倍空間,4字節。

【第三】VARCHAR(N)   N是字符(N個漢字),而非字節數。 Mysql_UTF8   varchar(255) = 765字節。

 

~ 避免使用 TEXT BLOB數據類型 ,扔到擴展表中(TEXT 不實用 實際 VARCHAR夠了)。

限制:只能用前綴索引

~ 避免使用 ENUM 數據類型

限制:使用ALTER語句修改值

缺點:ORDER BY 效率降低,須要額外操做

~ 避免 用字符串存儲日期型數據 , 不能使用日期函數計算比較。

應該:TIMESTAMP(1970~2038年) 或 DATETIME

~ 商業數據 DECIMAL  (科學計算才用 float double)

優勢:比 bigint 更大

========================================================

② 索引(primary index unique )

單表索引不要超過5個。(下降 Mysql 優化查詢效率 致使 插入、更新下降)

~ 充分利用已經有的索引

left join 或 not exists 來優化 not in 操做

 

Innodb按照 【主鍵索引】順序組織表。

【建議使用自增ID值】主鍵不使用 UUID、MD五、HASH、字符串列,不是順序增加。

 

【判斷是否加索引經驗】

① SELECT UPDATE DELETE 的 WHERE

② ORDER BY 、GROUP BY、DISTINCT 的 字段。

③ 須要 JOIN操做 的關聯列。

 

聯合索引列順序怎麼安排?

1 最明確區分放在最左側

2 長度小的列放在最左側

3 最頻繁的列放在左側

 

【頻繁的查詢 覆蓋索引】包含全部查詢字段的索引。

避免了 Innodb表進行索引二次查找。

把隨機IO變成順序IO加快查詢。

 

【儘可能避免使用外鍵】不使用外鍵約束,把關聯列創建索引,剩下交給程序。

自己外鍵用來保證數據參照完整性,但實際仍是業務爲主/

還會影響 父表和子表的 寫操做下降性能。

 

==============================

③ sql 面向開發人員

 

【預編譯語句】可維護、可分發

PREPARE stmt1

FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';

SET @a = 3;

SET @b = 4;

EXECUTE stmt1 USING @a,@b;

DEALLOCATE PREPARE stmt1;

 

 

~ 避免數據類型隱式轉換

 select name,phone from user where id = '111'   致使索引失效。

 

 

 不一樣庫要不一樣的帳號。

不容許 select * 。

把子查詢優化成 join 。(由於子查詢結果集沒法使用索引、臨時表數據量大影響大)

每 join 一份表會產生 join_buffer_size 。

 

【分頁】數據庫適合批量一次性操做。

 【in 代替 or 】in值不該超過500,有效利用索引。

【不宜 order by rand()】隨機排序,所有都放到內存!放到程序去排序。

【WHERE從句使用函數、計算】致使索引失效。

 索引X  where date(createtime) = '20160901'

 索引O  where createtime >= '20160901' and createtime < '20160902'

明顯沒有重複值【Union ALL】          【Union】產生臨時表。

 

MYSQL 一個大sql只能使用一個CPU。

 

 ④ 方便運維    數據庫操做規範。

【主從延遲】 【大事務】【日誌多】超過100萬條數據,應該分批屢次進行操做。

 

【大表工具】使用 pt-online-schema-change修改表結構。

【最大鏈接數限制】容許1個有super權限用戶鏈接   DBA 專用。

程序不能有 drop 權限。

相關文章
相關標籤/搜索