【DBA】手游数据库设计为啥第二种方法更优越

【DBA】手游数据库设计为什么第二种方法更优越?
本帖最后由 default7 于 2014-07-17 15:42:36 编辑
做过手游开发的进来探讨下以下哪种方法才是正确的!

需求:
1)手游运营平台,需要存放 【游戏】和【渠道】数据。
2)使用Oracle数据库,Oracle 11g

我个人的思路:需要设计三个表 TB_GAME(游戏资料),TB_AGENT(渠道资料),TB_GAME_AGENT_RELATION(对应关系表)


1)TB_GAME
  GAMEID      INT         PRIMARY KEY ,AUTO_INCREMENT
  GAMENAME    VARCHAR     (60)
  
2)TB_AGENT
  AGENTID     INT         PRIMARY KEY,AUTO_INCREMENT
  PARENTID    INT         INDEX KEY
  AGENTNAME   VARCHAR   (60)
  
3)TB_GAME_AGENT_RELATION
  ID          INT         PRIMARY KEY,AUTO_INCREMENT
  GAMEID      INT         INDEX KEY
  AGENTID     INT         INDEX KEY


游戏GAME,渠道AGENT全部独立,关联关系全部存入到RELATION表。
每个表都必须加上主键,RELATION表的GAMEID AGENTID全部设置上索引。




DBA的设计方案:2个表 TB_GAME(存放游戏资料),TB_AGENT(存放渠道资料)

1)TB_GAME <no primary key,no index key>
  GAMEID      INT           
  GAMENAME    VARCHAR     (256)
  
2)TB_AGENT<no primary key,no index key>
  AGENTID     INT         
  AGENTNAME   VARCHAR  (256) 
  PARENTID    INT         
  GAMEID


公司DBA给的设计方案:
1)所有的表没有一个有设置主键、索引或者节约字段的(比如varchar是256)。

2)游戏是独立存储的,但是每一个渠道却绑定了一个游戏,结果导致AGENT渠道表里面会有很多重复的AGENTNAME的数据,也就是说同一个渠道在渠道表会有多个纪录,很多次存入。
比如有一款游戏叫“三国”,他的渠道是百度。另外一款游戏叫毒霸,他的渠道也是百度。然后存入表TB_AGENT,就会出现两条AGENTNAME=百度的记录。【DBA】手游数据库设计为啥第二种方法更优越

3)AGENT表字段AGENTID的生成,让人难以理解。数据会变成这样:

TB_AGENT
AGENTID    PARENTID   AGENTNAME      GAMEID
1001          0          主渠道1        100
1002          0          主渠道2        100
1003          0          主渠道3        105
10012001      1001        主渠道1的子渠道  20
10012002      1001      主渠道1的第二个子渠道 0
10022015      1002      主渠道2的地15个子渠道 230

子渠道的ID是根据父渠道的ID 拼上 自己的MAX(同级)+1 ,且不足4位补到4位。
比如一个主渠道他的ID是 1005,他有一个子渠道 10052025,那么如果再给他新增一个子渠道。
ID是这样算的,先得到他父ID,和该父ID下的子渠道ID中ID最大的那个。10052025中去掉ID1005剩下2025,再2025+1,就得到了2026,拼接上父ID 1005,那么他的ID就是 10052026。为什么这样设计更优越。。。


现在比较疑问的是,为什么说DBA那样设置数据库才更优越??





------解决方案--------------------
个人感觉,比较赞同楼主的做法。因为游戏是游戏,渠道是渠道,对应是对应,很清晰明了。我想dba的想法会是从提高数据的运行效率考虑的,可以减少表的关联,能提高存储过程的执行时间。
------解决方案--------------------
感觉有时候冗余也不完全是坏事吧,何必在意一些细节,能满足需求,有同等或更优的执行效率就更佳了。既然dba说那样做就那样做吧,咳咳~~~
------解决方案--------------------
其实我觉得楼主的设计是对的,你那个DBA是打酱油,原因如下:
1. 某些情况下,即使是OLTP数据库,冗余也是允许的,但你那个场景不需要冗余,完全可以用视图代替,而且性能也有保证
2. 那个DBA没有考虑到数据一致性的问题, 比如说,如果agent的名字发生变化,应怎样保证更新是正确的?更进一步说,如果给agent增加额外的资料,那岂不傻眼了?
3. 至于索引的问题,像你那几张表,查询的次数会远远高于增删改的次数,在这种情况下,使用索引所付出的负面代价仅仅是额外的存储空间,却带来更好的查询性能,尤其是相关的查询频率比较高的情况下。如果是我的话,我还会加上外键约束,以避免代码可能插入垃圾数据的情况出现。

冗余是可以的,但不可以把允许冗余作为低级的表结构设计的借口