1. 程式人生 > >資料庫設計的三大正規化,分散計算思想

資料庫設計的三大正規化,分散計算思想

資料庫設計的三大正規化

1第一正規化:做到每列不可拆分,(一列資料中不要出現可以拆分的資料)

2.第二正規化:確保一個表只做一件事情(不要讓一個表儲存的資料可以做多個事情)

3.第三正規化:在滿足正規化二時,消除表的傳遞依賴。(比如說,表A裡的資料可以通過表A的其他資料得到。產生了多餘列,應為完全可以在程式碼中得到)

資料庫設計的反三正規化

反三正規化就是在以滿足上述三個正規化的基礎上,為了滿足客戶的特殊需求,在滿足三大正規化的基礎上又加了多餘欄位,我們稱之為反三正規化。

如:客戶在一張表中有單價,數量,需要我們給一個總價  我們設立一行總價的列就是反三正規化

分散計算思想(一般都寫在service層)

如:有兩張表,一張A(總金額表),一張B(單個商品總價表),當客戶訪問資料時,客戶想要在A中看到總金額,我們這裡就需要遍歷表B的總價,再相加,最後賦值給表A,這樣的話會造成資料載入遲緩,針對這種情況,我們可以在每次修改增加刪除表B的資料時,只要操作一次就把總價格傳給表A  進行加減,實時維護資料,這樣客戶再檢視總金額是就增強了載入速度,。而這種過程就是分散計算思想。

案例:儲存 修改 新增資料時  既要修改自己的總金額,還要修改最大的表的總金額

 public void saveOrUpdate(ContractProduct entity) {
         //1.先判斷是新增,還是修改,等於id=null為新增,
        if(UtilFuns.isEmpty(entity.getId())){//新增
            double amount=0.0;//2.先把貨物表的總金額設為0.
            if(UtilFuns.isNotEmpty(entity.getPrice())&&UtilFuns.isNotEmpty(entity.getCnumber())){  //3.再在其單價和數量都是新增的情況下,,,,讓其相乘,得到貨物的總價
                amount=entity.getPrice()*entity.getCnumber();                
            }
         //4.將獲得的總價賦值給貨物總價,   
            entity.setAmount(amount);
         //5.通過銷售合同的ID 查到銷售合同的資料  
                Contract contract = contractDaoimpl.findOne(entity.getContract().getId());
         //6.通過資料給總金額賦值  總金額+新的貨物總價
                contract.setTotalAmount(amount+contract.getTotalAmount());
         //7.儲存修改銷售合同的總金額後的資料
                contractDaoimpl.save(contract);
            
            
            
        }else{ //修改
           //1.獲取當前貨物的總價 
            Double amount = entity.getAmount();
           //2.把修改後的貨物總價設為0
            Double amount1=0.0;
            if(UtilFuns.isNotEmpty(entity.getPrice())&&UtilFuns.isNotEmpty(entity.getCnumber())){    //3.再在其單價和數量都是新增的情況下,,,,讓其相乘,得到貨物的總價
                amount1=entity.getPrice()*entity.getCnumber();
            }
           //4.判斷修改後的貨物總價與原先是否相等,是就不修改了,不是則繼續修改
            if(amount1!=amount){
           //5.用計算出的新的貨物總價   為貨物總價賦值
                entity.setAmount(amount1);
           //5.通過銷售合同的ID 查到銷售合同的資料  
                Contract contract = contractDaoimpl.findOne(entity.getContract().getId());
            //6.通過資料給總金額賦值  總金額+新的貨物總價-原來的貨物總價
                contract.setTotalAmount(contract.getTotalAmount()+amount1-amount);
            //7.儲存修改銷售合同的總金額後的資料
                contractDaoimpl.save(contract);
            }
        }
        //儲存貨物資料
        ContractProductdao.save(entity);
    }

打斷設計思想:

定義:在一方的表中加入冗餘欄位,用於儲存多方的主鍵,並用指定的字元進行分隔。

應用場景:一般在一對一,一對多是使用,多對多不推薦使用

好處:當關聯層級大於4級時,最好考慮打斷設計,能夠優化查詢速度

案列:有兩張表使用的打斷設計 entity :運單表(一)   ,contract :合同表(多), ContractIds :他們之間的打斷設計的欄位  ,當儲存一張表時,需要把打斷

public void saveOrUpdate(Export entity) {
//UtilFuns.isEmpty(entity.getId())判斷是否為null   null 為新增資料
        if(UtilFuns.isEmpty(entity.getId())){//先判斷是不是新增的,
//更具運單表獲取中間表ContractIds,由於是用字元拼接的這裡我們需要使用split切割下
            String[] ContractIds = entity.getContractIds().split(", ");
//new StringBuffer  以便存放資料 
            StringBuffer ab = new StringBuffer();
            for (String con : ContractIds) {
                //更具ID查詢合同表的資料
                Contract contract = contractDaoimpl.getOne(con);
                //用append 存放資料,並使用空格進行分隔
                ab.append(contract.getContractNo()).append(" ");
                
            } 
        exportdao.save(entity);//呼叫儲存方法
    }

設計的冗餘欄位進行更新