Sql-Server

如何在 SQL 中以更好的方式使用規範化設計數據庫表?

  • December 14, 2017

我以以下方式設計了我的表格。

國家表:-

PkId --- + Country Name --- + StatusFlag
1        | India            | L
2        | China            | L
3        | Sri Lanka        | L

州名表:-

PkId --- + CountryFkId --- + State Name --- + StatusFlag
1        | 1               | Maharastra     | L
2        | 1               | Madhya Pradesh | L 
3        | 1               | Utter Pradesh  | L

城市表:-

PkId --- + StateFkId --- + City Name --- + StatusFlag
1        | 1             | Mumbai        | L
2        | 1             | Pune          | L 
3        | 1             | Nagpur        | L

密碼表:-

PkId --- + CityFkId --- + PinCode --- + Area ---       + StatusFlag
1        | 1            | 400037      | Antop Hill     | L
2        | 2            | 412206      | Ambade         | L 
3        | 3            | 441108      | Ashta          | L

客戶表:-

PkId --- + CustomerId --- + CustomerName --- + PinCodeFkId--- + StatusFlag
1        | C00001         | John             | 1              | L
2        | C00002         | Ram              | 2              | L 
3        | C00003         | Anwar            | 3              | L

詢問:-

Select C.CustomerId, C.CustomerName, P.Area, CT.CityName, S.StateName, CNT.CountyName
From dbo.Customers C
Inner Join dbo.PinCodes P On C.PinCodeFkId = P.PkId
Inner Join dbo.Cities CT On P.CityFkId = CT.PkId
Inner Join dbo,StateNames S On CT.StateFkId = S.PkId
Inner Join dbo.Countries CNT On S.CountryFkId = CNT.PkId

但是我的同事告訴我,如果我這樣寫,就會發生巨大的邏輯讀取。他們還告訴他們這些表結構遵循了太多的規範化。他們沒有像上面那樣設計客戶表,而是給出了其他建議。即,在客戶表本身中維護 CountryName、StateName、CityName、PinCode 和 Area。

重組客戶表:-

PkId --- + CustomerId --- + CustomerName --- + PinCode ---   + Area ------- + CityName --- + StateName --- + CountryName--- + StatusFlag
1        | C00001         | John             | 400037        | Antop Hill   | Mumbai       | Maharastra    | India          | L
2        | C00002         | Ram              | 412206        | Ambade       | Pune         | Maharastra    | India          | L     
3        | C00003         | Anwar            | 441108        | Ashta        | Nagpur       | Maharastra    | India          | L

重組查詢:-

Select CustomerId, CustomerName, Area, CityName, StateName, CountyName
From dbo.Customers

在上面的查詢中,我沒有對其他相關表添加任何連接條件。當表有大量記錄時,哪種表設計最適合規範化和更好的性能?

您的同事建議的表結構可能適用於數據倉庫,但通常不會減少 OLTP 數據庫中的 I/O。

考慮一下——如果您對一個城市中的所有客戶執行一個返回 1,000 行的查詢,使用非規範化表,數據庫引擎將不得不讀取 CityName、StateName 和 CountryName 1,000 次。更少的行將適合數據庫頁面,因此它將最終讀取更多頁面來完成查詢。

對於規範化的表,它只需要讀取這些列的 ID(與文本欄位相比非常小),並且只讀取一次實際的 CityName、StateName 和 CountryName。更多的行將適合數據庫頁面,因此需要讀取更少的頁面來完成查詢。

此外,考慮非規範化表對緩衝區的作用。如果緩衝區中有 1,000 條客戶記錄,則城市、州和國家名稱也在緩衝區中出現 1,000 次。對於規範化表,這些名稱僅在緩衝區中出現一次,使用的空間要少得多。因此,您將在帶有規範化表的緩衝區中擁有更多數據。

引用自:https://dba.stackexchange.com/questions/192859