分类表是一种典型的层次化关系的表,从数据库设计工作的角度看,让每个分类记录的parentId字段指向它们父分类的Id即可。
把层次关系转化为数据表并不困难,而且层次还相对比较清晰,但在这种表面现象的背后还有许多难题在等待着用户解决。比如,我们无法只用一个简单的SELECT就把指定分类的父分类或者子分类全部查询出来,而必须通过多次查询才能解决这个问题(或者一次查出后,用程序来进行处理)。
事实上,数据库设计和SQL编程有着千丝万缕的联系,很难将他们完全区分开来,再者,如果SQL不足以把想要查询的数据从数据表里提取出来,那么,想拿出一个优秀的数据为设计方案就只能是一句空谈。
想要通过数据表去管理和使用层次关系,得解决很多难题,而这些难题几乎都与SQL语言不能递归查询这一事实有关。以分类表为例:
1、只用一个查询就把指定分类的所有父分类全部查出来是不可能的
2、把完整的数据表还原为层次关系(树状)也是一个难点,还是必须执行多次SQL才能完成。
3、把指定分类下所有子分类全部查询出来
4、设计时,一个分类不能有两个父分类(例如:sql语言既能够放在database分类中,但好象放在programming分类下也行,因此,如果sql语言有两个父分类仿佛才是合理的)
5、层次关系最担心 的是留下循环引用隐患(比如手工删除数据或者添加数据时,很容易导致第4条的情况发生,数据库层次断链或者重复等)
虽然有这些存在的问题,但并非不可解决,而从上面这些难点来说,层次关系往往会导致即使是一个相对简单的问题也需要很多条SQL查询才能得出答案,而且整个过程都相当慢。如果不使用层次关系(或者使用有限的层次关系),上述问题即都可以避免。如果必须使用多级的层次关系,增 加一些数据列或数据表来提供更多关于层次关系的信息,将有助于层次关系的解决方案变得简单一些。
从范式的标准来说,冗余是不对的,它会导致存储空间不必要的浪费,增加数据库内部管理工作的负担,但为了提高应用程序的执行效率,冗余反而是一种相当简明的解决方案,因此,数据库设计其实是一件多方妥协和折中的事。在数据库领域,通往同一个目标的道路往往有好多条,选择其中的任意一条,都意味着作出了这样或那样的妥协。做出什么样的妥协最有利这往往取决于数据库的具体使用情况:什么类型的查询发生的最为频繁?数据需不需要频繁修改?