J'essaie de comprendre comment stocker correctement les informations commandées dans une base de données relationnelle.
Un exemple:
Disons que j'ai une liste de lecture, composée de morceaux. Dans ma base de données relationnelle, j'ai une table de Playlists
, contenant des métadonnées (nom, créateur, etc.). J'ai également une table appelée Songs
, contenant une information sur la playlist_id
chanson, ainsi que sur la chanson (nom, artiste, durée, etc.).
Par défaut, lorsqu'un nouveau morceau est ajouté à une liste de lecture, il est ajouté à la fin. Lors de la commande sur Song-ID (ascendant), l'ordre sera l'ordre d'addition. Mais que se passe-t-il si un utilisateur doit pouvoir réorganiser des chansons dans la liste de lecture?
J'ai proposé quelques idées, chacune avec ses avantages et ses inconvénients:
- Une colonne appelée
order
, qui est un entier . Lorsqu'un morceau est déplacé, l'ordre de tous les morceaux entre son ancienne et sa nouvelle position est modifié pour refléter le changement. L'inconvénient de cela est que de nombreuses requêtes doivent être effectuées chaque fois qu'un morceau est déplacé, et l'algorithme de déplacement n'est pas aussi trivial qu'avec les autres options. - Une colonne appelée
order
, qui est un décimal (NUMERIC
). Lorsqu'un morceau est déplacé, une valeur à virgule flottante lui est attribuée entre les deux nombres adjacents. Inconvénient: les champs décimaux prennent plus d'espace et il peut être possible de manquer de précision, à moins que l'on prenne soin de redistribuer la plage après quelques modifications. - Une autre façon serait d'avoir un
previous
et unnext
champ qui référencent d'autres chansons. (ou sont NULL dans le cas de la première ou de la dernière chanson de la liste de lecture en ce moment; Fondamentalement, vous créez une liste liée ). Inconvénient: les requêtes comme «trouver le Xème morceau dans la liste» ne sont plus à temps constant, mais à temps linéaire.
Laquelle de ces procédures est la plus utilisée dans la pratique? Laquelle de ces procédures est la plus rapide sur des bases de données moyennes à grandes? Existe-t-il d'autres moyens de l'archiver?
EDIT: Par souci de simplicité, dans l'exemple, un morceau n'appartient qu'à une liste de lecture (relation plusieurs-à-un). Bien sûr, on pourrait également utiliser une table de jonction, donc song⟷playlist est une relation plusieurs-à-plusieurs (et appliquer l'une des stratégies ci-dessus sur cette table).
update songorder set order = order - 1 where order >= 12 & order <= 42; update songorder set order = 42 where id = 123;
- c'est deux mises à jour - pas trente. Trois si vous voulez mettre de l'ordre dans une contrainte unique.
Queries like 'find the Xth Song in the list' are no longer constant-time
est également vrai pour l'option 2.