Suppose I have some objects, and I want the user to be able to reorder them in any way they wish, say, by dragging them around. So I\'d have
You can user previous Id, every new insertion you set last inserted row ID as previous ID like this,
table, td {
border: .2px solid black
}
<table>
<tr>
<td>ID</td>
<td>NAME</td>
<td>PREV_ID</td>
</tr>
<tr>
<td>1</td>
<td>first_item</td>
<td><i><null></i></td>
</tr>
<tr>
<td>2</td>
<td>second_item</td>
<td>1</td>
</tr>
<tr>
<td>3</td>
<td>thid_item</td>
<td>2</td>
</tr>
</table>
any time you reordering easily insert with last row id, If you use next id every new insertion you need to update previous one, If you use sort order in any update you have to update multiple rows. Now postgreSQL recursive query available for selecting
The best way I've found to handle this is to have a floating point order field. When you move something between two other items, set that field to halfway between its neighbors.
This is cheap on both reads and writes. The only downside is the floats keep getting longer :)
Theoretically you could use an Order Statistic Tree if you want to get a specific element at a value, or just some kind of B-Tree in general to store the values. If they change, you are changing O(log n)
items in the worst case. If you have 30,000 items, you only need to change 4 or 5 or them to keep the order.
The "naive" approach you suggest is also the best practice!
Taking Tony Andrews' answer into consideration, you could alternatively store a "next" index with each entry. Then when you pull them all in, walk the array by following the chain. That makes moving an item easier, as you only have to touch maximum two rows.
The disadvantage with this approach is if you ever need a subset (e.g. the first 3 items) you still need to pull in all the items, or use a SQL loop. So it's between affecting all rows during update, or accessing all items during read. As ever, measure the speed and see which is better for your situation.
Looking at Tony Andrew's and Mark's answers in particular, it seems I really have only two alternatives:
Meta: All of these answers are good and correct, which one should I choose as correct?