春風博客

          春天里,百花香...

          導航

          <2008年9月>
          31123456
          78910111213
          14151617181920
          21222324252627
          2829301234
          567891011

          統計

          公告

          MAIL: junglesong@gmail.com
          MSN: junglesong_5@hotmail.com

          Locations of visitors to this page

          常用鏈接

          留言簿(11)

          隨筆分類(224)

          隨筆檔案(126)

          個人軟件下載

          我的其它博客

          我的鄰居們

          最新隨筆

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          數據庫設計三范式應用實戰

          數據庫設計三范式應用實戰

          問題:如何將下表中列出的訂單信息存入到關系數據庫中
          客戶名                  總價值         商品列表
          北京商戶張三      1000元         上衣:20
          大連商戶李四      1500元         上衣:10;褲子:15;
          上海商戶王五      7500元         上衣:30;褲子:45;鞋子:60;

          粗略設計方案

          根據訂單上三欄內容,擬用一個表來存儲訂單信息,此表稱為Order表,字段如下:
          Customer:可變字符型,用于存儲客戶地址姓名等信息。
          Total:數字類型,用于存儲一個訂單的總商品價值
          GoodsList:可變字符型,用于存儲商品名和商品數量

          這樣的設計是否符合數據庫設計三范式呢?可以一條條對照一下。

          數據庫設計三范式

          范式(Normal Form)共有五種,但第四和第五種難于實現,并非必要。前三種標準格式為:
          第一范式(1NF)要求信息必須是原子級的,信息不可再分。
          第二范式(2NF)要求數據符合第一范式的標準,另外數據元素被組織成組,消除了冗余的數據。每個組包含一個主鍵和非關鍵數據,非關鍵數據必須在功能上依賴于主鍵。
          第三范式(3NF)要求數據元素符合第二范式的標準,同時非關鍵數據不能包含依賴性。
          個人對其的總結:1.信息不可分;2.以分組消除冗余數據,組內有主鍵作為唯一標識;3.組內部的非主鍵數據不能相互依賴。

          現在來看看粗略設計方案是否符合數據庫設計三范式
          1.Customer和GoodsList列可分,不符合第一范式。
          2.無主鍵,且三大基本信息都不依賴于主鍵,沒有進行合適分組,不符合第二范式。
          3.total列明顯依賴于GoodsList列,不符合第三范式。

          因為粗略設計方案不符合三大范式,我們有必要對其進行修改。

          修改后的第二次設計方案

          首先為了滿足第一范式,將三大數據列細分如下:

          customerName:用于存儲客戶名稱
          customerAddress:用于存儲客戶地址
          total :用于存儲商品總價值
          Goods1:訂單商品一
          GoodsCount1:訂單商品一的數量
          Goods2:訂單商品二
          GoodsCount2:訂單商品二的數量
          Goods3:訂單商品三
          GoodsCount3:訂單商品三的數量

          到此,信息已經不可再分,這樣的方案滿足了第一范式的要求。

          第二次設計方案存在的問題

          第二次設計方案雖然滿足了范式一,但是還有以下問題:
          1.三個訂單商品列和訂單數量列高度相似。
          2.如果客戶訂單商品類別確定在三種內還可以,一旦超過只有再增加列,更麻煩的是商品類別數量不確定。
          3.各個字段作用差別很大,似乎不該放在同一張表的同一行中。

          上述問題說明第二次設計方案還有待改造,讓我們再來看看它是否合乎第二,三范式。

          第二范式及解釋

          第二范式(2NF)要求數據符合第一范式的標準,另外數據元素被組織成組,消除了冗余的數據。每個組包含一個主鍵和非關鍵數據,非關鍵數據必須在功能上依賴于主鍵。
          上面這段話中,組實際上就是“數據表”的意思,第二范式告訴我們,應該把數據元素按功能分開,分別存儲到不同表中,而且每個表都該含有一個主鍵,非關鍵列在功能上依賴于關鍵列。

          第三范式

          第三范式(3NF)要求數據元素符合第二范式的標準,同時非關鍵數據不能包含依賴性。
          第二次設計方案中,總價值total是依賴于商品類別和商品數量的。我們必須取消這樣的非關鍵列之間的依賴性。
          通過觀察我們可以發現,總價值=商品單價*商品數量的總和,這樣,總價值這一列就不需要存在了,直接計算得出即可。

          接下來形成了第三次設計方案

          訂單表orderTable
          id:主鍵,訂單流水id
          customerId:下訂單的客戶id,客戶表Id的外鍵

          訂單商品表ordergoods
          id:主鍵
          orderId:訂單表id的外鍵
          goodsId:商品表id的外鍵
          count:商品數量

          商品表goods:
          id:主鍵
          name:商品名
          price:單價

          客戶表customer:
          id:主鍵
          name:客戶名
          address:客戶地址

          諸表建表語句

          create table customer(
             id 
          int(10primary key not null
             name 
          VARCHAR(255), 
             address 
          VARCHAR(255)


          create table goods(
             id 
          int(10primary key not null,  
             name 
          VARCHAR(255), 
             price 
          DOUBLE(10,2


          create table orderTable(
             id 
          int(10primary key not null,
             customerid 
          int(10not null,
             
          foreign key(customerid) references customer(id)
          )

          create table ordergoods(
             id 
          int(10primary key not null,
             orderid 
          int(10not null,
             goodsid 
          int(10not null,
             
          count  int(10),
             
          foreign key(orderid) references orderTable(id),
             
          foreign key(goodsid) references goods(id)
          )


          插值語句

          insert into customer ( id, name, address ) values ( '1''張三''北京' )
           
          insert into customer ( id, name, address ) values ( '2''李四''大連' )
           
          insert into customer ( id, name, address ) values ( '3''王五''上海' )

           
          insert into goods ( id, name, price ) values ( '11''上衣''240' )
           
          insert into goods ( id, name, price ) values ( '12''褲子''300' )
           
          insert into goods ( id, name, price ) values ( '13''鞋子''350' )

           
          insert into ordertable ( id, customerid ) values ( '111''1' )
           
          insert into ordertable ( id, customerid ) values ( '112''2' )
           
          insert into ordertable ( id, customerid ) values ( '113''3' )

           
          insert into ordergoods ( id, orderid, goodsid, count ) values ( '1111''111''11''20' )
           
          insert into ordergoods ( id, orderid, goodsid, count ) values ( '1112''112''11''10' )
           
          insert into ordergoods ( id, orderid, goodsid, count ) values ( '1113''112''12''15' )
           
          insert into ordergoods ( id, orderid, goodsid, count ) values ( '1114''113''11''30' )
           
          insert into ordergoods ( id, orderid, goodsid, count ) values ( '1115''113''12''45' )
           
          insert into ordergoods ( id, orderid, goodsid, count ) values ( '1116''113''13''60' )


           查詢訂單總價值

          select t01.orderId,t01.customerName,t02.total from
          (
          select 
             concat(customer.address,
          '商戶',customer.name) as customerName,
             orderTable.id  
          as orderId  
          from 
             orderTable,
             customer
          where 
             ordertable.customerid
          =customer.id) t01,
          (
          select orderid,sum(ordergoods.count*goods.price) as total
          from ordergoods,
               goods
          where
               ordergoods.goodsid
          =goods.id
          group by orderid) t02
          where t01.orderid=t02.orderid

          查詢結果

          查詢訂單貨物細節

          select ordergoods.orderid,ordergoods.count,goods.name,goods.price
          from ordergoods,
               goods
          where
               ordergoods.goodsid
          =goods.id
          order by orderid


          查詢結果

           

          posted on 2008-09-19 11:42 sitinspring 閱讀(2872) 評論(5)  編輯  收藏 所屬分類: DB&SQL

          評論

          # re: 數據庫設計三范式應用實戰[未登錄] 2008-09-19 17:32 june

          訂單表orderTable
          id:主鍵,訂單流水id
          customerId:下訂單的客戶id,客戶表Id的外鍵

          訂單商品表ordergoods
          id:主鍵
          orderId:訂單表id的外鍵
          goodsId:商品表id的外鍵
          count:商品數量

          拋開訂單流水的概念(因業務而定,在當前這個中業務中肯定是需要的),為什么不把兩個表合起來呢?
          如下:

          訂單商品表ordergoods
          客戶id和商品表id兩個一起做主鍵
          customerId:客戶id的外鍵
          goodsId:商品表id的外鍵
          count:商品數量
            回復  更多評論   

          # re: 數據庫設計三范式應用實戰 2008-09-20 20:36 sitinspring

          @june

          目前這么做也未為不可。但考慮到業務的擴展,能細分的還是先細分下去,如果使用后再調整表結構往往已經為時太晚了。  回復  更多評論   

          # re: 數據庫設計三范式應用實戰 2008-09-28 17:14 YZ

          支持,這才叫做原創!  回復  更多評論   

          # re: 數據庫設計三范式應用實戰 2009-04-28 10:27 學與習

          動作描述 使用聚集索引 使用非聚集索引
          -----------------------------------------------------------
          列經常被分組排序 應 應
          返回某范圍內的數據 應 不應
          一個或極少不同值 不應 不應

          感覺樓主建的主鍵不太對哦  回復  更多評論   

          # re: 數據庫設計三范式應用實戰 2009-04-29 01:37 學與習

          @sitinspring


          ordergoods與ordertable設計我很不理解,看了您對一樓的回復,您說是應用業務擴展,我真是想不出來,這對業務有什么幫助,希望樓主,可以舉個例子{只要說明就行了}。

          順便說一下,非常支持樓主的原創精神

            回復  更多評論   


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          sitinspring(http://www.aygfsteel.com)原創,轉載請注明出處.
          主站蜘蛛池模板: 成都市| 基隆市| 平邑县| 山丹县| 本溪| 济源市| 浑源县| 射阳县| 上思县| 库车县| 武强县| 靖安县| 通江县| 毕节市| 英德市| 玛多县| 彭州市| 临沂市| 姜堰市| 呼和浩特市| 漳州市| 上高县| 和平区| 新乐市| 柳江县| 射阳县| 革吉县| 浠水县| 莎车县| 龙南县| 璧山县| 宣武区| 芦溪县| 台江县| 罗城| 正镶白旗| 余干县| 新野县| 蒲江县| 河源市| 永川市|