这其实在大学就会学到的观念了,
虽然我感觉大学的数据库很多人教得不太好,
教得太抽象很容易让人听不懂...
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种作法都适合吗?
: 会有什么后续要注意的状况?