Friday, September 25, 2026
HomePythonThe right way to Effectively Reorder or Rerank Objects in Database

The right way to Effectively Reorder or Rerank Objects in Database


I used to be as soon as interested by Trello and Jira and questioned how they carried out the sorting performance of their drag & drop interface. You’ll be able to have one million objects/playing cards and each of those platforms will can help you change the order in a easy drag and drop method and effectively replace their place within the database.

How may I implement such a system? It was laborious to do analysis on this matter as a result of most queries returned outcomes from blogs that confirmed the way to implement a drag and drop part utilizing React DnD and comparable libraries however didn’t present the way to persist the brand new order in a database. Nonetheless, I saved on looking and was in a position to learn up on 3 completely different strategies and need to share them with you.

Drawback

Let’s arrange the issue that motivated this analysis. Think about you could have an inventory that has related objects. The db fashions would possibly look one thing like this:

class Checklist(fashions.Mannequin):
    identify = fashions.CharField(max_length=100)

class Merchandise(fashions.Mannequin):
    listing = fashions.ForeignKey(Checklist, related_name='objects', on_delete=fashions.CASCADE)
    identify = fashions.CharField(max_length=100)
    order = fashions.IntegerField(default=1)

Now think about you could have 10 objects and the order goes from 1-10 for these 10 objects. For simplicity’s sake, that is how they could appear like:

|order |  identify       |
|------|-------------|
| 1    | Merchandise No: 1  |
| 2    | Merchandise No: 2  |
| 3    | Merchandise No: 3  |
| 4    | Merchandise No: 4  |
| 5    | Merchandise No: 5  |
| 6    | Merchandise No: 6  |
| 7    | Merchandise No: 7  |
| 8    | Merchandise No: 8  |
| 9    | Merchandise No: 9  |
| 10   | Merchandise No: 10 |

Now, you might be are being requested to replace the order of the tenth merchandise to 2. The ensuing listing will look one thing like this:

|order |  identify       |
|------|-------------|
| 1    | Merchandise No: 1  |
| 2    | Merchandise No: 10 |
| 3    | Merchandise No: 2  |
| 4    | Merchandise No: 3  |
| 5    | Merchandise No: 4  |
| 6    | Merchandise No: 5  |
| 7    | Merchandise No: 6  |
| 8    | Merchandise No: 7  |
| 9    | Merchandise No: 8  |
| 10   | Merchandise No: 9  |

Now the issue is, how will you make this reordering working environment friendly? On this nieve instance, you’ll have to re-order every successive merchandise within the database and modify its order. It will result in 9 whole database requires modifying the order of merchandise 10 from 10 to 2.

For a small listing, this brute-force strategy would possibly work. At most you’ll have to replace the ordering of all of the objects between the present order place and the brand new order place. If that is the answer you need to go forward with, you may learn this submit on the Revsys weblog on the way to implement one thing like this in Django. Nevertheless, this answer is not going to scale so lets have a look at a couple of diffrent approaches to fixing this downside.

Method 1: Order objects in increments of 100

The primary strategy is to set the preliminary order worth in multiples of 100 (or every other giant quantity). That is how the default ordering will appear like:

|order |  identify       |
|------|-------------|
| 100  | Merchandise No: 1  |
| 200  | Merchandise No: 2  |
| 300  | Merchandise No: 3  |
| 400  | Merchandise No: 4  |
| 500  | Merchandise No: 5  |
| 600  | Merchandise No: 6  |
| 700  | Merchandise No: 7  |
| 800  | Merchandise No: 8  |
| 900  | Merchandise No: 9  |
| 1000 | Merchandise No: 10 |

When you need to modify the order of merchandise 10 and transfer it to place 2, you may merely replace the order worth to be between 100 and 200. It will end in an order worth of 150 for merchandise 10. This is not going to require any adjustments to the ordering of the remainder of the objects so long as the distinction between the order worth of adjoining objects is greater than 1.

That is what the newly ordered desk will appear like:

|order |  identify       |
|------|-------------|
| 100  | Merchandise No: 1  |
| 150  | Merchandise No: 10 |
| 200  | Merchandise No: 2  |
| 300  | Merchandise No: 3  |
| 400  | Merchandise No: 4  |
| 500  | Merchandise No: 5  |
| 600  | Merchandise No: 6  |
| 700  | Merchandise No: 7  |
| 800  | Merchandise No: 8  |
| 900  | Merchandise No: 9  |

This strategy permits us to reorder and place 100 objects between any 2 objects with default ordering earlier than it runs into issues. What would you do when two adjoining objects have an order distinction of only one? Let’s check out the subsequent strategy and see the way to get round this.

Method 2: Order objects utilizing a floating quantity

This strategy suggests to ditch integers and begin utilizing floating level numbers to maintain the order. It will end in such a desk construction:

|order |  identify       |
|------|-------------|
| 1.0  | Merchandise No: 1  |
| 2.0  | Merchandise No: 2  |
| 3.0  | Merchandise No: 3  |
| 4.0  | Merchandise No: 4  |
| 5.0  | Merchandise No: 5  |
| 6.0  | Merchandise No: 6  |
| 7.0  | Merchandise No: 7  |
| 8.0  | Merchandise No: 8  |
| 9.0  | Merchandise No: 9  |
| 10.0 | Merchandise No: 10 |

Now once you reorder and transfer Merchandise no 10 to place 2, it can get an order worth of 1.5. You’ll be able to carry on shifting objects round and there’ll at all times be room so as to add extra objects because the order is now a floating level quantity.

Fairly good strategy! This solves the earlier challenge the place we ran out of values to assign to the order key when adjoining values had an order distinction of only one. Nevertheless, the floats even have a restrict. I doubt you’ll encounter that restrict in commonest circumstances however it’s there and it’s good to pay attention to it. Most databases have their very own restrict for the way huge a float will be so I can’t go into an excessive amount of element.

There may be another strategy that overcomes these limitations.

Method 3: Order objects utilizing LexoRank

LexoRank is at present utilized by Jira for ordering and rating points. You’ll be able to learn this text to get some concept of the way it works inside Jira from an admin standpoint.

The phrase LexoRank will be divided into two elements:

  • Lexo: refers back to the phrase lexicographical which principally means alphabetical ordering.
  • Rank: refers back to the place of Jira points on a board’s backlog, on a kanban board itself or within the energetic dash on a scrum board.

It principally makes use of alphanumeric strings to maintain the order. By default, the objects could be ordered like this:

|order |  identify       |
|------|-------------|
| a    | Merchandise No: 1  |
| b    | Merchandise No: 2  |
| c    | Merchandise No: 3  |
| d    | Merchandise No: 4  |
| e    | Merchandise No: 5  |
| f    | Merchandise No: 6  |
| g    | Merchandise No: 7  |
| h    | Merchandise No: 8  |
| i    | Merchandise No: 9  |
| j    | Merchandise No: 10 |

If you wish to transfer merchandise 10 to place 2, you may merely append “a” on the finish. The up to date order will appear like this:

|order |  identify       |
|------|-------------|
| a    | Merchandise No: 1  |
| aa   | Merchandise No: 10 |
| b    | Merchandise No: 2  |
| c    | Merchandise No: 3  |
| d    | Merchandise No: 4  |
| e    | Merchandise No: 5  |
| f    | Merchandise No: 6  |
| g    | Merchandise No: 7  |
| h    | Merchandise No: 8  |
| i    | Merchandise No: 9  |

Now if you wish to transfer merchandise 9 to place 3, the up to date order would possibly resemble this:

|order |  identify       |
|------|-------------|
| a    | Merchandise No: 1  |
| aa   | Merchandise No: 10 |
| ab   | Merchandise No: 9  |
| b    | Merchandise No: 2  |
| c    | Merchandise No: 3  |
| d    | Merchandise No: 4  |
| e    | Merchandise No: 5  |
| f    | Merchandise No: 6  |
| g    | Merchandise No: 7  |
| h    | Merchandise No: 8  |

This fashion you may both carry on appending characters on the finish of the order worth or replace one of many characters everytime you need to modify the order. The precise LexoRank implementation just isn’t this straightforward however makes use of the identical idea. It offsets every new order worth and likewise makes use of buckets. These buckets come into play when particular person order values turn out to be too lengthy and have to be normalized. You’ll be able to learn this StackOverflow reply to get a greater sense of the way it works.

And that’s it! One factor I may have performed higher whereas doing this analysis is to seek for “rating” algorithms on prime of “ordering” algorithms. Which may have yielded higher outcomes a lot faster. If this submit helps you in any approach, please do let me know.

I plan on preserving future articles quick and to-the-point in order that I can preserve writing extra usually. An extended submit takes an excessive amount of time and requires a ton of modifying. I’ll preserve writing these as effectively however I don’t need most new concepts to finish up on my drafts folder and by no means see the sunshine of day. One such draft has been open in a separate tab on my laptop computer for greater than 2 months now 🙃 Want me luck and pray that I keep on with this new plan of publishing extra incessantly.

Additional studying

Here’s a listing of articles which may assist if you wish to learn extra on this matter:

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments