Je cherche le meilleur moyen de récupérer les enregistrements suivants et précédents d'un enregistrement sans exécuter une requête complète. J'ai mis en place une solution complète et j'aimerais savoir s'il existe de meilleures approches pour ce faire.
Imaginons que nous construisions un site web pour un marchand de légumes fictif. En plus de ses pages HTML, il souhaite publier chaque semaine une liste d'offres spéciales sur son site. Il souhaite que ces offres résident dans une véritable table de base de données et que les utilisateurs puissent trier les offres de trois manières différentes.
Chaque article doit également disposer d'une page détaillée contenant des informations textuelles supplémentaires sur l'offre et des boutons "précédent" et "suivant". Les boutons "précédent" et "suivant" doivent pointer vers les entrées voisines. en fonction du tri que l'utilisateur avait choisi pour la liste .
(source : <a href="http://www.pekkagaiser.com/stuff/Sort.gif?" rel="nofollow noreferrer">pekkagaiser.com </a>)
De toute évidence, le bouton "suivant" pour "Tomates, classe I" doit être "Pommes, classe 1" dans le premier exemple, "Poires, classe I" dans le deuxième, et aucun dans le troisième.
La tâche dans la vue détaillée est pour déterminer les éléments suivants et précédents sans lancer une requête à chaque fois. avec l'ordre de tri de la liste comme seule information disponible (disons que nous l'obtenons par un paramètre GET). ?sort=offeroftheweek_price
et ignore les implications en matière de sécurité).
De toute évidence, la première solution qui vient à l'esprit consiste à transmettre les ID des éléments suivants et précédents en tant que paramètre. Après tout, nous connaissons déjà les ID à ce stade. Mais ce n'est pas une option ici - cela fonctionnerait dans cet exemple simplifié, mais pas dans la plupart de mes cas d'utilisation réels.
L'approche que j'utilise actuellement dans mon CMS consiste à utiliser quelque chose que j'ai appelé "cache de tri". Lorsqu'une liste est chargée, je stocke les positions des éléments dans les enregistrements d'une table nommée sortingcache
.
name (VARCHAR) items (TEXT)
offeroftheweek_unsorted Lettuce; Tomatoes; Apples I; Apples II; Pears
offeroftheweek_price Tomatoes;Pears;Apples I; Apples II; Lettuce
offeroftheweek_class_asc Apples II;Lettuce;Apples;Pears;Tomatoes
évidemment, le items
est réellement remplie d'identifiants numériques.
Dans la page de détail, j'accède maintenant à l'élément approprié de la liste de contrôle. sortingcache
récupérer l'enregistrement items
l'éclater, rechercher l'ID de l'élément actuel et renvoyer le voisin précédent et le voisin suivant.
array("current" => "Tomatoes",
"next" => "Pears",
"previous" => null
);
Cette méthode est évidemment coûteuse, ne fonctionne que pour un nombre limité d'enregistrements et crée des données redondantes, mais supposons que dans le monde réel, la requête permettant de créer les listes est très coûteuse (elle l'est), qu'il est hors de question de l'exécuter dans chaque vue détaillée et qu'il n'est pas possible de l'utiliser. algunos la mise en cache est nécessaire.
Mes questions :
-
Pensez-vous que c'est une bonne pratique pour trouver les enregistrements voisins pour des ordres de requête variables ?
-
Connaissez-vous de meilleures pratiques en termes de performance et de simplicité ? Connaissez-vous quelque chose qui rende ce système complètement obsolète ?
-
En théorie de la programmation, existe-t-il un nom pour ce problème ?
-
Le nom "Cache de triage" est-il approprié et compréhensible pour cette technique ?
-
Existe-t-il des modèles reconnus et courants pour résoudre ce problème ? Comment s'appellent-ils ?
Nota: Ma question ne porte pas sur la construction de la liste, ni sur la manière d'afficher la vue détaillée. Ce ne sont que des exemples. Ma question porte sur le fonctionnalité de base de déterminer les voisins d'un enregistrement lorsqu'une nouvelle recherche est impossible, et le moyen le plus rapide et le plus économique d'y parvenir.
Si quelque chose n'est pas clair, veuillez laisser un commentaire et je le clarifierai.
Lancer une prime - il y a peut-être plus d'informations à ce sujet.
0 votes
J'aime le formatage des tableaux. Ça a dû prendre du temps ! (EDIT ! D'oh, c'est une image. Je me suis fait avoir !)
0 votes
@Jon ouais, c'est une astuce :) Mais Markdown semble supporter le HTML de base... J'essaierai cette voie la prochaine fois.
0 votes
@Pekka : Pas de tables, cependant. Il faut les construire à la manière de l'ASCII-Art.
0 votes
@Tomalak ahh, dommage ! Je vais faire une demande de fonctionnalité pour cela sur SO.
0 votes
@Pekka : Je ne me donnerais pas la peine, cela ne changera pas de sitôt. Si je ne me trompe pas, quelque part sur meta, Jeff a clairement indiqué que c'est comme ça qu'il l'aime. J'étais sur le point de faire un lien vers son post, mais je n'arrive pas à le trouver maintenant :-\.
0 votes
@Tomalak santé. Alors ce n'est pas la peine d'ouvrir une question.
1 votes
Il m'a fallu un certain temps pour comprendre quelle était la vraie question. Je pense que la situation est la suivante : un utilisateur est dans une vue détaillée et veut voir l'enregistrement suivant, où "suivant" dépend de l'ordre de tri précédemment sélectionné. Il serait inefficace de demander la liste triée, puis de demander les détails de l'enregistrement suivant. Au lieu de cela, vous souhaitez uniquement demander les détails de l'enregistrement suivant.
0 votes
@Tomalak Est-ce que c'est meta.stackexchange.com/questions/1777/ la question ?
1 votes
La façon dont vous souhaitez répartir les ressources n'est pas claire pour moi. La requête de la base de données ne doit-elle récupérer que 5 éléments consécutifs à la fois ? La requête de la base de données doit-elle tout récupérer, mais le tri est effectué plus tard sur le résultat (ce qui signifie que le serveur doit mettre le résultat en cache) ? Cela doit-il se faire sur le serveur ou sur le client (JavaScript) ?
0 votes
Pourquoi ne pas mettre en cache les identifiants du premier et des 50 enregistrements précédents dans Memcached ou autre ?
0 votes
Bien sûr, il suffit de dénormaliser. Maintenez votre base de données comme trois systèmes totalement séparés, complètement triés et distincts. Personne ne s'est soucié de la normalisation pendant 20, 30 ans.