標籤:重複 技術 com span 位元組 each ... 之間 lod
序號order從1開始的遞增整數,無間斷無重複
為保證序號不間斷、無重複,每次修改資料的序號後,都要對其他的資料序號進行順移。
同時移動多條資料是指保證序號不間斷、無重複的情況下,一次請求中:之後的資料移動不影響之前移動過的資料的序號。
移動流程:
把資料區塊從位置o移動到位置n,並添加1個鎖定塊和1個預留位(預留位=n),鎖定塊不再參與移動如果o>n:地區上移 把m和n(包括m、n)之間的資料(排除鎖定塊)下移1位 把預留位的資料下移1位,執行c次(c=預留位元量-1)如果o<n:地區下移 把m和n(包括m、n)之間的資料(排除鎖定塊)上移1位 把預留位的資料上移1位,執行c次(c=預留位元量-1)重複上面的步驟,直到所有資料被移動到指定的位置
:
去重說明:每移動一次會產生一個預留位,下次地區順移的時候可能會有資料被移動到預留位,這時候需要再次移動預留位上的資料,但是如果有多條相鄰的預留位,移動後還是在預留位上,所以最多需要移動c次,c=預留位元量-1。
下面是一個php執行個體:
//要移動的資料$rows = array( array( "id"=>3,/*唯一標識*/ "moveto"=>8/*目標位置*/ ), array( "id"=>4, "moveto"=>9 ), array( "id"=>12, "moveto"=>2 ) ...)$locked = array();//鎖定塊數組$lockedorder = array();//預留位元組foreach($rows as $row){ $o = $db->result("SELECT order FROM ".DB_TABLEPRE."user WHERE id=$row[$id] ");//資料原來的位置o $n = $row[moveto];//目標位置n $db->query("update user set order=$n WHERE id=".$row[$id]);//移動該條資料 if($n == $o){ //不用移動 }elseif($n > $o){ //地區上移 $db->query("update user set order=order-1 WHERE id NOT IN(implode(‘,‘,$locked)) AND order>=$o AND order<=$n "); //執行c次排重 foreach($locked as $temp){ $db->query("update user set order=order-1 WHERE id NOT IN(implode(‘,‘,$locked)) AND order>=$from AND order<=$n AND order IN(implode(‘,‘,$lockedorder))"); } }else{ //地區下移 $db->query("update user set order=order+1 WHERE id NOT IN(implode(‘,‘,$locked)) AND order<=$o AND order>=$n "); //執行c次排重 foreach($locked as $temp){ $db->query("update user set order=order+1 WHERE id NOT IN(implode(‘,‘,$locked)) AND order<=$o AND order>=$n AND order IN(implode(‘,‘,$lockedorder))"); } } $locked [] = $row[$id];//添加一個鎖定資料區塊 $lockedorder [] = $n;//添加一個預留位}
一次請求對多條資料進行排序的演算法(一)