Fork me on GitHub

如何在数据库中存储有顺序的数据

      数据库中的记录都是按照集合的方式来组织的,一个记录集中的各个记录往往是无序的(或者有默认顺序,如按存入数据库的顺序,但不能绝对保证这种顺序)。如果在实际应用中,我们需要在数据库中存储类似于列表的有顺序的数据,此时该采取怎样的策略呢?

      一种直接而有效的方法是,在记录集(或表)中增加一个“顺序”列(或叫“索引”字段),对表进行存入、取出或者排序的操作时,都可以依据“索引”字段来完成,从而保证数据应有的正确顺序:

        content     order
        -------------------- 
           A         1 
           B         2 
           C         3 

      这种方法的原理非常简单,而且也确实直接有效,这一点在Best way to save a ordered List to the Database while keeping the ordering中得到了大家的认可。

      使用上述方法的一个问题是,如果想要在已有的有序记录之间插入一个新的记录,就需要刷新所有“索引”字段的值,即重新排序所有记录,以保证插入后的正确顺序,如果表中的记录很多,那么每插入一个记录时,就会带来巨大的重排消耗。

      一种解决(或者是缓解)这种“重排消耗”的方法是:不采用简单的整数值(如0,1,2,3,...)作为“索引”字段,而是采用类似于('a','aa','ab',...,'b','ba','bb',...,'c',...)的字符串。

      该方法(我姑且称之为“string approach”)的原理举例如下:

      (1)假设表中已存在依次按照'a'、'b'、'c'的顺序存入的数据A、B、C:

        content     order
        -------------------- 
           A         'a' 
           B         'b' 
           C         'c' 

      (2)在表中的A与B之间插入一个D,并设置对应的order字段为'aa',已有的A、B、C的order字段都可以保持不变:

        content     order
        -------------------- 
           A         'a' 
           D         'aa'     (new added)
           B         'b' 
           C         'c' 

      这种方法是我在Store ordered list in database (Gap approach)上看到的,其中还提到了另一种称为"gap approach"的方法:在“顺序”列中设置有跨度的(不连续的)字段值(如100,200,300,...),从而为后面插入的记录预留可用的“顺序”字段值:

        content     order          content     order
        --------------------       -------------------- 
           A         100              A         100 
           B         200              D         150 (new added)
           C         300              B         200 
                                      C         300 

      不管是“string approach”还是“gap approach”,随着插入记录的逐渐增多,一定程度后都会有一些限制。对于“string approach”而言,字符串可能变得过长;对于“gap approach”而言,预留的跨度区域总会用完。为了避免遇到这些限制,就需要我们定时地去整理表中的记录,对“顺序”字段重新进行统一编排规划,使得下一轮在表中插入新记录时,“顺序”字段的值也更简单有效,而不是冗长繁琐。

posted on 2011-10-23 21:19  RussellLuo  阅读(5076)  评论(0编辑  收藏  举报

导航