簡體   English   中英

我想在數據庫設計中刪除表字段中的冗余

[英]I want to remove redundancy in table fields in my database design

我有2張桌子:

學生碩士

身份證,名字,姓氏,電子郵件,電話號碼,國家/地區,州/省/直轄市/自治區/直轄市/自治區,個人資料picurl,性別,出生日期。

教練大師

ID,名字,姓氏,電子郵件,電話號碼,Countryid,stateid,cityid,Profilepicurl,性別,出生日期,語言。

現在您可能會注意到,除了2個額外字段(即coachmaster中的 Language)外,這2個表僅具有公共字段。

我正在考慮制作一個包含兩個表中所有字段的表,即該UserMaster (包含StudentMaster和CoachMaster),如下所示:

UserMaster

ID,其余所有常用字段,語言(來自教練主)

我已經與一位經驗豐富的開發人員的朋友討論了這個問題,他告訴我僅創建一個單獨的表,他向我展示了以下2種2種創建兩個單獨表的方案

  1. 如果我只有1個通用表,那就是UserMaster,如果將來我想在coach master中添加2個額外的字段,那么這種結構將很糟糕。

  2. 如果我在UserMaster中添加了教練所需的這兩個額外字段,並且如果我只想要任何特定的學生詳細信息,那么也將不必要地獲取那兩個額外的字段(在教練的第一點中添加)。

注意 :其他場景也可能存在,只有一個表同時維護教練和學生的詳細信息。

除此之外,我的朋友告訴我的是,我在這里不遵循規范化規則,如果我只有一個表,那就是usermaster,那么為了確定哪個用戶是學生, 哪個用戶是老師,我將總是必須使用join檢查是 Userinrole表,我將像這樣維護:

角色主管:Id,姓名(值:學生,教練)

UserInRole:RoleId(引用RoleMaster ID),UserId(存儲Studentid或CoachId)

當我有任何身份證時,這就是我始終必須尋找是否是教練生的方式。

因此,有人可以幫助我指導如何創建一個好的結構來解決這兩種情況並避免在此表中不必要地創建重復字段的情況嗎?

SQL不能為“一種”關系提供很好的支持。 有方法,但是它們往往有些笨拙。

因為除了“學生”和“教練”外,您還在考慮“用戶”,所以聽起來您有另一個實體。 “用戶”是“學生”或“教練”。

我想我會以兩種方式之一來解決您的問題。

兩者都以Users表開頭,其中包含學生中的所有字段。 用戶,學生和教練的主要關鍵。 除非他們有成為教練的證據,否則所有用戶都被視為學生。 這是什么證據?

一種可能性是“ Users表中的“ type列以及所需的其他字段。 這通常是解決此問題的非常合理的方法。

第二個是具有CoachId主鍵的加法表Coaches ,它也是UserId的外鍵。 這包含有關教練的其他信息。 另外,它使在需要的地方輕松建立外鍵關系成為可能。

您當然可以為Student和Coach維護一張表,但是,正如您已經注意到的那樣,這存在可維護性問題。 但是,您(或您朋友)的分析存在一個缺陷。 如果您有一個帶有指示符的表,該指示符顯示了用戶類型(例如,“ S”或“ C”),並具有如下查找表:

ID   Name     <other>
==   ====     =======
 S   Student  ...
 C   Coach    ...

從“用戶”表中的指示符字段到該表的FK引用將強制執行以下規則:用戶必須是一個或另一個,並且別無其他。 但是,查詢不一定總是必須聯接到該表。 當您執行“插入用戶”表或更改該指標字段值的更新時,系統將驗證該表中是否存在FK值。 否則,查詢僅在希望獲取存儲在其中的其他數據時才加入該表。

話雖這么說,除非您知道您的設計將在相當長的一段時間內保持穩定,否則我建議您使用超表-次表設計。 可以在以下位置找到對類似問題的更詳細的答案:

圍繞繼承結構設計關系

在您的情況下,通用或超級Masters表看起來像您當前的StudentMaster表,但增加了MasterType字段:

create table Masters(
    ID         int not null auto_generated primary key,
    ...
    MasterType char( 1 ) not null,
    ...
    constraint FK_Masters_Type foreign key( MasterType )
        references MasterTypes( ID ),
    constraint UQ_Masters_Type unique( ID, MasterType )
);

FK強制將條目定義為“學生”或“教練”。 然后,StudentMaster表將很簡單,因為它沒有向通用主表添加任何新屬性:

create table StudentMasters(
    MasterID    int not null primary key,
    MasterType  char( 1 ) check( MasterType = 'S' ),
    constraint  FK_StudentMasters_Master foreign key( MasterID, MasterType )
        references Masters( ID, MasterType )
);

該檢查意味着只能將學生插入此表。 FK表示ID必須與Masters表中的條目匹配,並且還必須將其定義為Student。 無法將已定義為“教練”(或任何可能的將來類型)的“學生”中的ID值存儲在StudentMasters表中。

CoachMasters表將是相同的,除了它將定義“語言”字段並且檢查將是“ MasterType ='C'”。

現在,您可以從其他表中引用母版。 對於引用母版的那些FK,無論類型如何,都可以將其定義到母版表中。 如果只能說是Coach(CoachedBy),則可以參考CoachMasters表。 因此,絕不會將學生ID值意外插入該字段中。 與僅必須參考學生的引用相同。

另一個建議:在這些表的前面有兩個視圖,CoachMasters和StudentMasters(將表重命名為其他名稱)。 然后,您的應用程序甚至可以在不知道底層結構的情況下獲得教練或學生的信息。 視圖上的觸發器將允許所有操作都通過視圖。 這使您可以在需要時更改表的物理布局。 只需重新定義視圖和觸發器,就無需更改應用程序代碼。 這一技巧可以大大提高數據庫的可維護性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM