日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

好-字典表設(shè)計

 cjavahtml 2018-04-10

在稍大一些的項目中,我們總是需要管理各種各樣的類型類型數(shù)據(jù)(如商品類型、游戲類型。。。)。對于這些類型的管理類似,如果為每一種類型都建立一張表去維護(而在項目中,正常出現(xiàn)50種類型),那工作量是可想而之大,并且我們不得不去了解每一個類型表的名字,以去關(guān)聯(lián)它。

   因此,我們需要一種數(shù)據(jù)模型以完成對多種多樣類型管理的需求。

=========================================================================================================字典表設(shè)計及應(yīng)用舉例      為了響應(yīng)志峰兄弟的需求,今天抽了點時間寫點關(guān)于字典表設(shè)計的東西,順便結(jié)合一個小的應(yīng)用對設(shè)計做個用例體驗。

咱先來看看什么叫字典。
     時間緊張,先略了,以后再談呵呵
字典存在的必要性及他的好處。
     同上^_^
字典設(shè)計思路。
     字典信息在系統(tǒng)中充當基礎(chǔ)參數(shù)的角色,基本上有些重要的基本信息是要在系統(tǒng)在為正式業(yè)務(wù)服務(wù)之前就由系統(tǒng)管理員維護進去的,有的字典信息是在使用過程中由系統(tǒng)管理員或者其他用戶維護進去的。

     也就是說,我們有“維護字典信息”的需求,那么我們在設(shè)計字典信息表結(jié)構(gòu)的時候就要考慮到這個需求。
     在維護的時候,我們肯定希望能對字典信息分文別類的進行維護,這樣我們需要設(shè)計一個字典類類別表(Dic_Type),結(jié)構(gòu)如下:
     ID(字典類型ID) 
  Name(字典類型名稱,即該類型的具體中文描述)

     具體表數(shù)據(jù)特征請看下面的例子。
     有了類別表后,我們還需要一個存放每個類別的字典信息的具體數(shù)據(jù)表(Dic_Data或者稱Dict_Item):

     ATID(自動增長的ID,沒有實際作用) 
  TypeID(字典信息歸屬的字典類別ID,即父表的id)
  ID(字典信息ID,在程序中使用的字典ID就是這個,我認為更好用itemvalue或者itemcode,表示項目值)
  Name(字典信息內(nèi)容,即該項目的具體中文描述)

     這樣,在我們的業(yè)務(wù)信息表中,存放的和字典相關(guān)的字段的值就是Dic_Data中的ID的值,那么就涉及到在界面上顯示信息的問題,如果不做處理,顯示出來的肯定就是原始的字典信息的ID,肯定不是用戶希望得到的,基于這個需求,
  我們?yōu)槊總€類型的字典信息做一個視圖(具體方法見后面的例子),
  將信息表與對應(yīng)的視圖做關(guān)聯(lián)查詢就可以得到字典信息ID對應(yīng)的真正內(nèi)容。

應(yīng)用舉例。
     假定做一個學生信息管理系統(tǒng)
     字典類型表設(shè)計如下(Dic_Type):
     ID Name
     1  Sex
     2  ...

     字典內(nèi)容表設(shè)計如下(Dic_Data):
     ATID TypeID ID Name
     1    1      1   男
     2    1      2   女
     3    2      1   ...
     4    2      2   ...
     5    2      3   ...
     6    2      4   ...
    ...  ...    ...  ...

     性別類型字典的視圖(VW_Sex):
     select ID,Name from Dic_Data where TypeID=1

     假設(shè)學生信息表如下T_Student:
     ID Name  ... Sex
     1  采采  ...  1
     2  花花  ...  2
     3  剛剛  ...  1

     取學生列表信息可通過如下方法實現(xiàn):
     select T_Student.ID as StudentID,T_Student.Name as StudentName,VW_Sex.Name as SexName
     from T_Student left join VW_Sex on T_Student.Sex=VW_Sex.ID

     結(jié)果如下:
     StudentID  StudentName  SexName
     1              a            男
     2              b            女
     3              c            女

 

時間倉促,寫的粗糙了點,還請見諒,有時間再補充。。。

綠色通道:好文要頂關(guān)注我收藏該文與我聯(lián)系

 

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

 

我們現(xiàn)在在進行數(shù)據(jù)庫字典表設(shè)計時,有二種方式,其一是傳統(tǒng)的方式,每個字典表都有ID、Name兩字段。第二種方式是將所有字典表的數(shù)據(jù)放在同一張表中,結(jié)構(gòu)如下:

TypeTable(typeID,typeName)【主表,用來記錄字典表表名信息】;DataTable(typeID,DataId,DataName)【從表,記錄所有字典表數(shù)據(jù)信息】

如性別、婚姻狀態(tài),在TypeTable中是兩條記錄,{02,性別},{06,婚姻狀態(tài)};而在DataTable中各有三條記錄{02,0,女 / 02,1,男 / 02,9,其它},{06,0,未婚 / 06,1,已婚 / 06,9,離異}

另有一張病人列表patient(patientID,SexID,MarryStatusID…)

現(xiàn)在需要查詢病人信息,sql語句如下:

Select b.DataName as SexName,c.DataName as MarryStatusName

from patient a left join DataTable b on b.DataId=a.SexID and b.typeID=’02’

left join DataTable c on c.DataId=a.MarryStatusId and b.typeID=’06’


在數(shù)據(jù)庫中執(zhí)行該Sql語句,由于DataTable約1000條左右的數(shù)據(jù)量,相對第一種方式必將對數(shù)據(jù)庫有一定的影響。

(當然在實際業(yè)務(wù)中可能類似的字典表約達5-10個,patient的數(shù)據(jù)量約500w條)


但不知道在一個系統(tǒng)中所有字典表獲取數(shù)據(jù)都采用這種方式對數(shù)據(jù)庫性能到底影響到什么程度,約降低百分之幾的性能?會有其它隱患沒?

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

樓上的可能沒明白樓主的意思。

不是指學歷表和國籍表數(shù)據(jù)量大,而是指人員表所具有的屬性可能太多(這里不一定指人員表,也可能是其它的實體,即隨著系統(tǒng)的復雜程度增加,實體的屬性增加)。這里以人員為例,說了國籍和學歷兩個屬性,如果人員還有職位,那么必然多出職位表,如果還有其它...

那即,當取得一條實例的完全數(shù)據(jù)時,那將進行幾十個表的join,樓主考濾的應(yīng)該是這個問題。

person_info(person_id,name,country_id,education_id,position_id,....) 
country(country_id,name,...) 
position(position_id,name,...) 
education(education_id,name,....) 
...


所以樓主采用了另一種設(shè)計方式: 
所有屬性類(屬性本身也是實體,只不過是主表的某個屬性)放置在一個表中,用屬性名和屬性值來區(qū)別。 
persion_info(persion_id,name,...) 
1 aaa 
2 bbb 
attributes(attributes_id,persion_id,attributes_name,attributes_value) 
1 1 country china 
2 1 education 小學 
3 1 position 公司總裁 
4 2 country usa 
5 2 education 碩士 
6 2 postion DBA


補充:

在 應(yīng)用開發(fā)中,總會遇到許多數(shù)據(jù)字典項,比如對象狀態(tài)、對象類型等等,這些項一般都是固定的若干可選值選項,比如對象狀態(tài)可能有新建、修改、刪除等狀態(tài),這 些數(shù)據(jù)字典項一旦定義完畢改動的頻率非常低;在應(yīng)用開發(fā)中,為了處理方便,一般要對這些數(shù)據(jù)字典項值選項進行數(shù)字編碼(例如: 0表示新建,1表示修改,2表示刪除等),以方便應(yīng)用程序中使用。而UI顯示對象信息時不能顯示對象狀態(tài)等的編碼,對于編碼值設(shè)計人員知道代表什么意思,但用戶就不明白了,所以需要進行編碼轉(zhuǎn)換,從編碼轉(zhuǎn)換為文字描述(名稱),也就是需要把狀態(tài)編碼0轉(zhuǎn)換為“新建”,把1轉(zhuǎn)換為“修改”,把2轉(zhuǎn)換為“刪除”等顯示給用戶,用戶才明白對象當前的狀態(tài)是什么。


下面介紹一下常用的實現(xiàn)方法:


實現(xiàn)方案:


一、在java文件中定義數(shù)據(jù)字典項


我們習慣上把應(yīng)用中遇到的數(shù)據(jù)字典項都定義到一個java文件中,這是最常用的方法,實現(xiàn)起來比較簡單,但維護起來就非常繁瑣,特別是數(shù)據(jù)字典項比較多的情況下,相應(yīng)的java文件就會比較大,一旦數(shù)據(jù)字典項有更新那么維護起來就比較費時費力。


在java文件中定義數(shù)據(jù)字典項通常情況下定義為static,舉例來說,類ReportConstants中定義了以下數(shù)據(jù)字典項:


    public static final int CODE_USERINF_TECHELEVEL_GJ = 1;


    public static final String CODE_USERINF_TECHELEVEL_GJ_KEY = “高級“;


    public static final int CODE_USERINF_TECHELEVEL_ZJ = 2;


    public static final String CODE_USERINF_TECHELEVEL_ZJ_KEY = “中級“;


    public static final int CODE_USERINF_TECHELEVEL_CJ = 3;


    public static final String CODE_USERINF_TECHELEVEL_CJ_KEY = “初級“;


    public static final int CODE_USERINF_TECHELEVEL_WJ = 4;


public static final String CODE_USERINF_TECHELEVEL_WJ_KEY = “無職稱“;


那么我們在實現(xiàn)中就可以直接引用相應(yīng)的數(shù)據(jù)字典項編碼及名稱,另外,一般情況下需要定義數(shù)據(jù)字典項編碼和名稱的轉(zhuǎn)換方法,比如:


    public static String getCodeName(int lCode)


       {


              //初始化返回值


              String strReturn = “未知“;


        switch (lCode)


              {


                     case CODE_USERINF_TECHELEVEL_GJ :


                            strReturn = CODE_USERINF_TECHELEVEL_GJ_KEY;


                            break;


                     case CODE_USERINF_TECHELEVEL_ZJ :


                            strReturn = CODE_USERINF_TECHELEVEL_ZJ_KEY;


                            break;


                     case  CODE_USERINF_TECHELEVEL_CJ :


                            strReturn = CODE_USERINF_TECHELEVEL_CJ_KEY;


                            break;


                     case  CODE_USERINF_TECHELEVEL_WJ :


                            strReturn = CODE_USERINF_TECHELEVEL_WJ_KEY;


                            break;


              }


              return strReturn;


       }


這個方法實現(xiàn)了通過數(shù)據(jù)字典項編碼獲得數(shù)據(jù)字典項名稱的功能。那么還需要實現(xiàn)一個對應(yīng)的方法,getCodeByName(String name),即通過數(shù)據(jù)字典項名稱獲取數(shù)據(jù)字典項編碼功能(代碼這里省略,請讀者自己完成)。這樣就可以實現(xiàn)數(shù)據(jù)字典項編碼和名稱的相互轉(zhuǎn)換。


但是一旦出現(xiàn)數(shù)據(jù)字典項名稱或編碼需要更改(“無職稱”項編碼需要由“4”改為“0”),或增加減少數(shù)據(jù)字典項,都需要更新java文件代碼。是否有簡便的方法在滿足上述需求的情況下又不更新java文件代碼?答案是肯定的。下面我們來介紹兩種實現(xiàn)方法:一中使用xml文件,一種在數(shù)據(jù)庫定義。


二、在xml文件中定義


第一種方案是應(yīng)用xml配置文件來定義數(shù)據(jù)字典項。使用xml配置文件,以便最大限度的減小維護的工作量,避免java代碼的頻繁修改。


下面我們分步驟詳細介紹一下使用xml配置文件的實現(xiàn)方案


第一步:定義xml數(shù)據(jù)字典項配置文件


首先新建一個xml文件,命名為DataDictionaryConfig.xml(名字可以自己定義),把應(yīng)用的用到的數(shù)據(jù)字典項分組定義到xml文件中,舉例如下,我們定義了下列數(shù)據(jù)字典項:


<?xml version=”1.0″ encoding=”GB2312″?>


<data-dictionaries>


    <data-dictionary>


      <group value = “0” name=”O(jiān)bjectStatus”>


         <option value=”0″ name=”detached”/>


         <option value=”1″ name=”new”/>


         <option value=”2″ name=”updated”/>


         <option value=”3″ name=”deleted”/>


      </group>


      <group value = “1” name=”O(jiān)bjectTypes”>


         <option value=”0″ name=”對象類型選項0″/>


         <option value=”1″ name=”對象類型選項1″/>


         <option value=”2″ name=”對象類型選項2″/>


         <option value=”3″ name=”對象類型選項3″/>


<option value=”4″ name=”對象類型選項4″/>


      </group>


    </data-dictionary>


</data-dictionaries>


這個xml文件可以根據(jù)需要進行擴展,滿足更復雜應(yīng)用的需要。


第二步,定義數(shù)據(jù)字典項對象類和數(shù)據(jù)字典項分組對象類:


    對于數(shù)據(jù)字典項這里我們定義了一個數(shù)據(jù)字典項對象類,一組數(shù)據(jù)字典選項集我們定義了一個數(shù)據(jù)字典項分組對象類,如下:


(1)、數(shù)據(jù)字典項類:


public class DataDictionaryItem


{


  public DataDictionaryItem()


  {


  }


  private String code;


  private String name;


  public void setCode(String code)


  {


    this.code = code;


  }


  public String getCode()


  {


    return this.code;


  }


  public void setName(String name)


  {


    this.name = name;


  }


  public String getName()


  {


    return this.name;


  }


}


(2)、數(shù)據(jù)字典項分組類


public class DataDictionaryItems


{


  public DataDictionaryItems()


  {


  }


  //數(shù)據(jù)字典項分組編碼


  private String groupCode;


  //數(shù)據(jù)字典項分組名稱


  private String groupName;


  //數(shù)據(jù)字典項詳細


  private java.util.ArrayList items;


  public void setGroupCode(String code)


  {


    this.groupCode = code;


  }


  public String getGroupCoude()


  {


    return this.groupCode;


  }


  public void setGroupName(String name)


  {


    this.groupName = name;


  }


  public String getGroupName()


  {


    return this.groupName;


  }


  //設(shè)置數(shù)據(jù)字典項


  public void setDataDictionaryItem(DataDictionaryItem item)


  {


    if(this.items == null)


      this.items = new java.util.ArrayList();


    this.items.add(item);


  }


  //設(shè)置數(shù)據(jù)字典項


  public void setDataDictionaryItem(String itemName, String itemCode)


  {


    if(this.items == null)


      this.items = new java.util.ArrayList();


    DataDictionaryItem item = new DataDictionaryItem();


    item.setCode(itemCode);


    item.setName(itemName);


    this.items.add(item);


  }


  //獲得數(shù)據(jù)字典項組對象


  public java.util.ArrayList getDataDictioanryItems()


  {


    return this.items;


  }


第三步,定義Xml數(shù)據(jù)字典項配置文件解析類,這里我們使用Dom4J,相應(yīng)的jar可以在http://www./上找到


import org.dom4j.*;


import org.dom4j.io.*;


import java.util.*;


public class XMLDDItemParser {


  //數(shù)據(jù)字典項結(jié)構(gòu)


  public static DataDictionaryItems dataItems ;


  private static String GROUP_NAME = “name”;


  private static String GROUP_CODE = “value”;


  private static String ITEM_NAME = “name”;


  private static String ITEM_CODE = “value”;


  public XMLDDItemParser() {


  }


    /**


   * 獲得分組數(shù)據(jù)字典項集


   * @param groupName String


   * @return DataDictionaryItems


   */


  public static DataDictionaryItems getDataDictionaryItems(String groupName)


  {


    if(dataItems == null)


      dataItems = parseXML(groupName);


    return dataItems;


  }


  /**


   * 根據(jù)分組名稱解析xml文件,獲得該分組下數(shù)據(jù)字典項集


   * @param gName String


   * @return DataDictionaryItems 數(shù)據(jù)字典項分組對象


   */


  public static DataDictionaryItems parseXML(String gName)


  {


    try


    {


      org.dom4j.io.SAXReader saxReader = new org.dom4j.io.SAXReader();


      Document document = saxReader.read(“DataDictionaryConfig.xml”);


      dataItems = new DataDictionaryItems();


      List list = document.selectNodes(“//group”);


      Iterator iter = list.iterator();


      while (iter.hasNext())


      {


        Node node = (Node) iter.next();


        if (node instanceof Element)


        {


          //document


          Element element = (Element) node;


          String GroupName = element.attributeValue(GROUP_NAME);


          String GroupValue = element.attributeValue(GROUP_CODE);


          //設(shè)置分組名稱編碼


          dataItems.setGroupName(GroupName);


          dataItems.setGroupCode(GroupValue);


          //取組內(nèi)數(shù)據(jù)字典項


          if (gName.equals(GroupName))


          {


            //取數(shù)據(jù)字典項名稱編碼


            Iterator elemIter = element.elementIterator();


            while (elemIter.hasNext())


            {


              Element elem = (Element) elemIter.next();


              dataItems.setDataDictionaryItem(elem.attributeValue(ITEM_NAME), elem.attributeValue(ITEM_CODE));


            }


          }


        }


      }


    }


    catch (Exception ex) {


      ex.printStackTrace();


    }


    return dataItems;


  }


第四步,提供數(shù)據(jù)字典項編碼轉(zhuǎn)換方法類:


public class DataDictionaryUtils {


  public DataDictionaryUtils() {


  }


  /**


   * 根據(jù)數(shù)據(jù)項名稱轉(zhuǎn)換為數(shù)據(jù)項編碼


   * @param groupName String


   * @param itemName String


   * @return String  數(shù)據(jù)項編碼


   */


  public static String getItemCode(String groupName, String itemName)


  {


    String code = “-1″;


    DataDictionaryItems dataItems = XMLDDItemParser.getDataDictionaryItems(groupName);


    java.util.ArrayList items = dataItems.getDataDictioanryItems();


    if(items != null)


    {


      DataDictionaryItem item;


      for(int i = 0; i < items.size(); i++)


      {


        item = (DataDictionaryItem) items.get(i);


        if(item != null)


        {


          String name = item.getName();


          if(name.equals(itemName))


          {


            code = item.getCode();


            break;


          }


        }


      }


    }


    return code;


  }


  /**


   * 根據(jù)數(shù)據(jù)項編碼轉(zhuǎn)換為數(shù)據(jù)項名稱


   * @param groupName String


   * @param itemCode String


   * @return String


   */ 


  public static String getItemName(String groupName, String itemCode)


  {


    String name = “未知“;


    DataDictionaryItems dataItems = XMLDDItemParser.getDataDictionaryItems(groupName);


    java.util.ArrayList items = dataItems.getDataDictioanryItems();


    if (items != null)


    {


      DataDictionaryItem item;


      for (int i = 0; i < items.size(); i++)


      {


        item = (DataDictionaryItem) items.get(i);


        if (item != null)


        {


          String code = item.getCode();


          if (code.equals(itemCode))


          {


            name = item.getName();


            break;


          }


        }


      }


    }


    return name;


  }


至此,我們已經(jīng)完成了該方案的設(shè)計。使用xml文件,增加刪除數(shù)據(jù)字典項等只需要更新xml文件即可,不涉及java文件的更新。


Xml可以根據(jù)應(yīng)用的具體需要進行擴展設(shè)計。這里僅僅拋磚引玉,提供一種思路。


三、使用數(shù)據(jù)庫表


上一種方法我們使用xml文件定義數(shù)據(jù)字典項,現(xiàn)在我們把數(shù)據(jù)字典項定義在數(shù)據(jù)庫表中,下面我們來詳細介紹實現(xiàn)方式:


第一步:定義數(shù)據(jù)字典項數(shù)據(jù)表結(jié)構(gòu)


根據(jù)前面xml文件定義,這里我們定義兩張表,一張是數(shù)據(jù)字典分組信息表,一張是數(shù)據(jù)字典項詳細信息表。如下:


drop table datadic_groups;

create table datadic_groups(

    group_code varchar2(20) primary key,

    group_name varchar2(50) 

);


drop table datadic_items;

create table datadic_items(

    dataitem_code varchar2(20) primary key,

    dataitem_name varchar2(50),

    group_code varchar2(20)

);


alter table datadic_items 

add constraint dataitem_foreignkey foreign key (group_code) 

references datadic_groups(group_code);


這兩張表可以根據(jù)應(yīng)用的具體需求進行擴充,這里不再贅述。


第二步:根據(jù)定義的數(shù)據(jù)字典表結(jié)構(gòu)定義數(shù)據(jù)字典實體類。


(請參照二、在xml文件中定義的第二步)


第三步:實現(xiàn)數(shù)據(jù)庫表中數(shù)據(jù)字典項的查詢功能


  /**


   * 實現(xiàn)從數(shù)據(jù)庫查詢數(shù)據(jù)字典項


   * @param gName String


   * @return DataDictionaryItems


   */


  public static DataDictionaryItems getFromDB(String gName)


  {


     dataItems = new DataDictionaryItems();


     try


     { 


        //獲取數(shù)據(jù)連接


        java.sql.Connection conn = getConnection();


        if(conn != null)


        {


           //查詢數(shù)據(jù)庫,根據(jù)組名稱查詢組編號,根據(jù)組編號獲取該組內(nèi)數(shù)據(jù)字典項信息


           String strSql = “select items.dataitem_code, items.dataitem_name, items.group_code, dgroups.group_name from datadic_items items, datadic_groups dgroups where items.group_code = dgroups.group_code and dgroups.group_name='”+gName+”'”;


           java.sql.Statement stmt = conn.createStatement();


           java.sql.ResultSet rs = stmt.executeQuery(strSql);


           while(rs.next())


           {


               String dataitem_code = rs.getString(1);


               String dataitem_name = rs.getString(2);


               dataItems.setDataDictionaryItem(dataitem_name, dataitem_code);


               String group_code = rs.getString(3);


               String group_name = rs.getString(4);


               dataItems.setGroupCode(group_code);


               dataItems.setGroupName(group_name);


           }


        }


     }


     catch(Exception ex)


     {


       ex.printStackTrace();


     }


     return dataItems;


  }


第四步:提供數(shù)據(jù)字典項編碼轉(zhuǎn)換方法類:


    (請參照二、在xml文件中定義的第四步)


四、進一步完善


1、兩種方式都可以提供數(shù)據(jù)字典項維護界面,直接在維護界面上操作數(shù)據(jù)字典項,避免由于誤操作導致xml文件或數(shù)據(jù)庫數(shù)據(jù)錯誤。具體的實現(xiàn)也是比較簡單,不再詳細說明。


2、 使用數(shù)據(jù)庫表方式時,如果想減少頻繁查詢數(shù)據(jù)庫,可以將數(shù)據(jù)字典項信息在系統(tǒng)啟動后第一次訪問時加載內(nèi)存中,如果數(shù)據(jù)字典項數(shù)據(jù)量比較大,可實現(xiàn)一自維護 線程,采用最近最少使用算法,將頻繁使用的數(shù)據(jù)字典項駐留內(nèi)存,將長期不用的數(shù)據(jù)字典項從內(nèi)存中刪除,每次自動檢查內(nèi)存中的數(shù)據(jù)字典項,如果存在則從內(nèi)存 中讀取,如果不存在則查詢數(shù)據(jù)庫,替換內(nèi)存中最少使用的數(shù)據(jù)字典項。


3、增加運行日志記錄,可以使用log4J來記錄運行日志

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多