Consider the following table:
Song
----
SongID GUID Primary Key
Name Varchar
dateAdded DateTime
I am creating a website that plays songs from the Song table. I want to generate a randomly ordered playlist for each visitor of the site that persists across requests without using any server-side storage (no session-style or database storage.) The player has Play, Next Song, and Previous Song buttons. What is the most efficient way to persist this data across requests? What is the most efficient query for this information? I have a solution (in mySql) that works, but I am looking to see if something more efficient works. Also, I don’t want to bias the answers into using my solution. Please include a query in your answer.
Update: Here’s the requirements that I followed, spelled out:
I think you need one more piece of information: a secondary song key of an integer position, in addition to your GUID (or you could replace it with this). Then, combined with a PRNG, you can do the most simple and quick lookup possible. Pseudocode:
This will get progressively slower on each next song and doesn’t allow wrapping by going backwards (without some creativity). If you find a suitable reversible PRNG (though uncommon among good PRNGs, AFAIK):
This handles deletions by skipping those songs (or if you never delete that’s not even an issue), but otherwise doesn’t change the order no matter how many are deleted. Insertions are handled by the song_index_from_seed function, by constraining the index so new songs are never ‘seen’. This is also an infinite loop if all the available songs have been deleted, but I think this code handles all other corner cases.
(Refactoring the next/prev versions to be simple wrappers around a common function isn’t hard, but left out here to increase clarity.)
I’ve effectively replaced your dateAdded with my position index, but this is an improvement, since you don’t need to keep deleted rows as dummies (but still cannot reuse their index) as you would if the position index was computed by ordering on dateAdded.
Using a PRNG like this seems naive, but works; and you’ll have to be careful that the chosen PRNG and song_index_from_seed combination behaves as you expect: it’s possible that some initial seeds appear to generate “non-random” playlists. (Not because they’re not random, but because listeners expect a mix of songs instead of just 4, 4, 9, 9, …)