這其實在大學就會學到的觀念了,
雖然我感覺大學的資料庫很多人教得不太好,
教得太抽象很容易讓人聽不懂...
anyway,
以我判斷,
這狀況要拆成3張表,
甲表是共用field,
乙表是A情境用,
丙表是B情境用,
然後甲表和乙表做成view專門給A情境用,
甲表再和丙表做成view給B情境用,
舉例子來講會比較好懂,
我們要設計遊戲,
遊戲裡有文官和將軍,
將軍沒有行政屬性,不能做行政職,
但有戰鬥屬性,可以帶兵,
文官有行政屬性沒戰鬥屬性,可以做行政,但不能帶兵,
所以我會先建一張表叫人物表,
表上有姓名,性別,生日等所有人物都有的屬性
(當然這時候會有天兵用年齡當field而不是生日,這就要打屁股了)
另一張表叫將軍表,
屬性有人物id,可以join到人物表,
還有戰鬥能力,戰鬥經驗值,
再一張表叫文官表,
屬性有人物id,外交能力,內政能力,研究能力...
再把將軍表和人物表變將軍view,
文官表和人物表變文官view,
要為軍隊選擇將軍時,就讀將軍view,
要選內閣時,就讀文官view,
要看人物列表時,就只讀人物表,
當然會有人既是將軍也是文官,例如凱末爾或艾森豪,
但在這種結構下,這種全才會同時存在將軍與文官的view中,
所以不用擔心
設計資料庫的道理和OO有共同之處,
就是一個表,和一個field最好只有一個很明確的存在目的,
而且要儘量讓結構可以很靈活的組合,
就像變形金鋼一樣可以變來變去,
如果一個表用來做一大堆事的話,
那就會變得很難維護了...一動就會扯到很多事,
細節前面與推文也很多人有講了就不多說,
要注意的地方大概就是要看一張表的數據量會不會超大,
如果超過百萬筆的話就要注意,
因為百萬筆的表再join其他表的話,很可能有效能問題,
如果要讓效能提升,
只做成2張表也行,各自應付A情境和B情境而不join,
就是所謂的反正規化,
但這樣做的缺點是若要查A情境和B情境共同的東西時的話,
就得用union了,
如查人物列表,變成要文官表union將軍表,
用field去把一個表模擬成兩張表...
我目前是想不到這樣做有什麼好處啦,
比較像是有人沒受過資料庫訓練,
自己幻想出的solution,
等A情境需要加些field或key,
B情境也需要加些field或key,
再來個C情境要加些field,
你就會看到傳說中的資料庫大魔王表,一張有上百個field的表,
你就可以唱首歌,
"我們的table,一眼望不完~,數不完的fields,峰峰相連到天邊~",
實務上我也碰過幾次這種前人留下的資料表坑,
費了九牛二虎之力還不一定解決得完,
因為表用在正式系統後,就不能隨便動了,動了容易出事,
所以會這樣告訴你,
也發現雖然資料庫大家都在用,
但很多人不太會設計,
有時候還真想去當老師教資料庫
※ 引述《asleepme (500年沒換暱稱了)》之銘言:
: 請教dba神人,之前遇到一個應用情境是這樣
: 我們有一組核心資料,跟2種服務
: 這2個服務(A、B)會用核心資料,去呈現不同的應用
: 所以A、B會有部分相同功能、部分不同功能
: 例如A會有功能 G、X、Y
: B會有功能 H、X、Y
: X、Y是一樣的功能只是A情境下用,或是B情境下用
: 所以X、Y功能在db中需要的structure也是一樣
: A、B儲存在X、Y裡面的資料是互相獨立的,沒有任何關聯
: 也就是說,在情境A下存進A.X的資料B完全不知道也沒差
: 在這情況下,我們可以為A的X功能建立一個 A_func_X 的table
: 同樣,B的X功能也可以建立一個 B_func_X 的table
: 但是這2個table的structure會一模一樣
: 也可以A、B共用一個table func_X
: 裡面有一個field叫type存A、或B,代表是哪個服務所建立的資料
: 想請教一下2種作法都適合嗎?
: 會有什麼後續要注意的狀況?