update ... set position = (prev + next)/2;
To get better performance you can choose to use the float data type, but then you'd be limited to a fixed precision; sufficient for most cases, though.Also, you’ll still eventually need to go clean up the entire sequence because you’ll run out of gaps between adjacent numbers. Because of this, I’d probably rather use a more predictable type (like one of the integer types) and explicitly plan my cleanup schedule.
If you're using a numeric type, you get up to 16383 digits after the decimal. That's... Probably more precision than you'll be able to reasonably use up in almost any use case. Any time you're reordering in bulk, you're resetting the order value to a nice integer, so it would take many thousands of ad-hoc reordering operations near a single position to get it close to the precision limit, yeah?
https://www.postgresql.org/docs/current/datatype-numeric.htm...
------------
playlists {
id
}
------------
playlist_members {
id
playlist_id
prev_playlist_member_id
(and/or next_playlist_member_id)
song_id
}
------------
you could then just select * from playlist_members where playlist_id = ... and sort on the client side. you'd probably add an application limit where playlists have a max length of some kind.
re-orders can be done in a fixed number of row updates and typical application queries are still possible / fast.
playlists {
id
song_ids []
}-------------
and just store the ordering in an array. Some postgres drivers might start shitting the bed though at some gigantic array sizes, but a playlist probably has reasonable enough limits that you wouldn't have a big problem.
You could probably also sort in the database with a recursive cte or with PL/pgSQL.
I’ve never considered doing this though! I imagine I must’ve come across some problem where this would’ve been better than whatever I came up with.
Example constraint would be a unique index for the Playlist member table on the combination of Playlist id and previous Playlist member ID.