How to save a particular, mutable “order” into a database

后端 未结 9 934
北恋
北恋 2021-02-05 03:34

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

  • Cheese
  • Muffin
相关标签:
9条回答
  • 2021-02-05 04:05

    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>&lt;null&gt;</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

    0 讨论(0)
  • 2021-02-05 04:06

    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 :)

    0 讨论(0)
  • 2021-02-05 04:06

    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.

    0 讨论(0)
  • 2021-02-05 04:07

    The "naive" approach you suggest is also the best practice!

    0 讨论(0)
  • 2021-02-05 04:11

    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.

    0 讨论(0)
  • 2021-02-05 04:15

    Looking at Tony Andrew's and Mark's answers in particular, it seems I really have only two alternatives:

    • Saving a 'next' value, making the objects behave like a linked list (see Mark's answer)
      With this, changing the order is cheap, but I'd have to retrieve the items and then sort them by their 'next' value, which is expensive
    • Saving an 'order' value (see Tony Andrew's answer)
      This makes retrieving cheap but saving a new order potentially expensive, because in the worst case, I'd have to change all the order values. cletus points out that one could use a large number in the form of 2^n for the order multiplier.

    Meta: All of these answers are good and correct, which one should I choose as correct?

    0 讨论(0)
提交回复
热议问题