J'ai une table des profils d'utilisateurs. Chaque utilisateur peut avoir de nombreux profils et l'utilisateur a la possibilité d'arbriquer l'ordre de la manière dont ils seront affichés dans une grille. P>
Il existe 2 tables utilisateurs et profils (1: M) P>
J'ai ajouté une colonne code> Colonne sur la table des utilisateurs où seront des valeurs telles que 1,2,3 .. p>
Jusqu'à présent, cela semble être correct. Mais lorsqu'un utilisateur changera l'ordre du dernier enregistrement pour être le premier, je dois passer à tous les enregistrements et incrémenter leurs valeurs +1. Cela me semble assez moche. P>
Y a-t-il une solution plus pratique pour ce type de situation? P>
7 Réponses :
laisser des lacunes dans la séquence ou utiliser une décimale plutôt qu'un type de données entier. P>
Utilisez des chaînes (Varchar, texte). Les chaînes ont implicitement une "précision arbitraire" indéfinie. Stackoverflow.com/a/49956113/10608
En tant qu'utilisateur ajoute des profils, définissez chaque nouveau numéro de commande du nouveau profil sur le précédent +1000000. par exemple. Pour commencer avec: Lors de la réorganisation, définissez la commande du profil au milieu des deux, il se passe entre: p> Cela donne à la commande P1, P3, P2 P> P>
Que diriez-vous d'utiliser des points flottants pour la commande par colonne? De cette façon, vous pouvez toujours presser un profil entre deux autres, sans avoir à changer ces deux valeurs. Par exemple, si je veux placer le profil A entre profils B (ordervalue 1) et c (ordervalue 2), je peux affecter la commandevalue 1.5 à A. Pour le placer sur le dessus, où avant le sommet utilisé pour avoir OrderValue, vous pouvez utiliser OrderValue 0.5 P>
Il n'y a aucune raison d'avoir des entiers pour commander et aucune raison d'avoir des incréments de 1 entre l'ordre des profils. P>
Disons que vous avez 3 enregistrements, vous attribuez des numéros 1,2,3 pour eux. Ensuite, vous réorganisez une dernière pour être entre deux premiers et obtenir 1,5 numéro pour cela. Ensuite, répétez le processus et chaque fois que vous le ferez plus près de 1, comme 1,25, 1,125, etc. Jusqu'à ce que vous atteigniez la limite de précision, cela vient très bientôt, 50 itérations. Ensuite, vous avez des bugs méchants ... :(
Je pense que l'idée de laisser des lacunes entre les commandes est intéressante, mais je ne sais pas si c'est une solution "plus pratique" pour votre problème. P>
Je pense que vous feriez mieux de mettre à jour votre Cela ne devrait pas être que les données intensives pour énumérer l'ordre dans lequel ils l'ont mis et mettent à jour chaque enregistrement à la commande. P> par code> colonne. Parce que vous allez toujours devoir déterminer les lignes déplacées entre les états et sur quoi faire si deux statuts sont commutés en position (calculez-vous la nouvelle commande par valeur pour le premier puis le second). Que se passe-t-il si l'écart entre n'est pas assez grand? P>
La meilleure solution est une solution qui Si vos listes étaient très volumineuses (dans les dizaines de milliers), les considérations de performance peuvent entrer en jeu, mais je suppose que ces listes ne sont pas aussi longues. P>
+1 Lorsque la sémantique du problème correspond à celle de la solution, il y a moins d'endroits pour se cacher.
Si le jeu de données est petit (ce qui semble être le cas), je préférerais utiliser une liste normale d'entiers et les mettre à jour en lot lorsqu'un profil obtient une nouvelle position. Cela reflète mieux la fonctionnalité de l'application.
dans SQL Server, pour le tableau suivant user_profiles (user_id, profil_id, position) code>, j'aurais quelque chose comme ceci: P> --# The variables are:
--# @user_id - id of the user
--# @profile_id - id of the profile to change
--# @new_position - new position that the profile will take
--# @old_position - current position of the profile
select @old_position = position
from User_Profiles where
user_id = @user_id and profile_id = @profile_id
update p set position = pp.new_position
from User_Profiles p join (
select user_id, profile_id,
case
when position = @old_position then @new_position
when @new_position > @old_position then --# move up
case
when @old_position < position and
position <= @new_position
then position - 1
else position
end
when @new_position < @old_position then --# move down
case
when position < @old_position and
@new_position <= position
then position + 1
else position
end
else position --# the same
end as new_position
from User_Profiles p where user_id = @user_id
) as pp on
p.user_id = pp.user_id and p.profile_id = pp.profile_id
Je pense au lieu de garder l'ordre dans la colonne code> OrderBy CODE> Vous pouvez introduire le concept de liste de liaison à votre conception. Ajouter une colonne comme NextID qui contiendra le profil suivant de la chaîne. Lorsque vous interrogez la table code> code>, vous pouvez trier les profils de votre code (Java, C #, etc.) P>