Réorganiser id pour garder continuité ? [mysql] - SQL/NoSQL - Programmation
Marsh Posté le 06-11-2005 à 23:58:42
Juste après le
DELETE FROM siron_blog WHERE id= . $_GET['delete_post']
tu peux ajouter un
UPDATE siron_blog SET id=id-1 WHERE id > . $_GET['delete_post']
Sachant que c'est risqué en cas d'accès concurrents (faudrait locker la table).
Mais bon, est-ce vraiment important d'éviter les "trous"
Marsh Posté le 07-11-2005 à 07:49:48
En fait j'aimerais locker les trous parceque j'affiche un nombre limitté de post par page, et j'ai une page qui rassemble tout les titres des postes dipso, quand je clique sur un post il affiche la page concernée, et si y'a des trous dans les id ça me gêne un peu pour le calcul qui permet de définir à quelle page le pos est.
Citation : UPDATE siron_blog SET id=id-1 WHERE id > . $_GET['delete_post'] |
C'est un truc comme ça que je voulais faie en cogitant tout seul, mais bon, j'imaginais pas que c'étais si court (mais en même temps je connais pas mysql et je me basais sur des exemples).
C'est quoi un accès concurrents ?
Je serais le seul à manipulé cette table.
Comme ça :
Citation : mysql_query('DELETE FROM siron_blog WHERE id=' . $_GET['delete_post'] and 'UPDATE siron_blog SET id=id-1 WHERE id' > . $_GET['delete_post'] ); //On delete le post |
Marsh Posté le 07-11-2005 à 07:54:35
1) C'est très couteux.
2) C'est chiant à faire.
3) Tu peux toujours faire autrement.
Marsh Posté le 07-11-2005 à 07:56:03
2) Pourquoi (et quoi en fait qui est chiant) ?
3) Comment ?
Marsh Posté le 07-11-2005 à 07:59:36
2) Parce-que c'est toujours casse-pieds à écrire ce genre de fonctions...
3) Tu peux toujours compter le nombre de messages que tu as avant un message donné, c'est pas un soucis... D'ailleurs il doit bien y avoir une sorte de rownum, dans ton SGBD, qui te donneriait un indice "continu" sur lequel travailler..;
Marsh Posté le 07-11-2005 à 08:07:59
Effectivement, je pourrai rajouter une colonne avec un nombre qui représente le nombe de message, mais en cas de suppression je devrai quand même décrémenté les posts qui suivent, et je vois pas alors la différence avec l'id.
Et je dois pas savoir que uniquement le nombre de post, je dois aussi savoir la position de chaque post dans la table.
Et je sais pas si c'est moins lourd de décrémenter une fois les id ou de conter chaque fois le nombre de messsage.
Marsh Posté le 07-11-2005 à 08:35:44
Siron a écrit : Effectivement, je pourrai rajouter une colonne avec un nombre qui représente le nombe de message, mais en cas de suppression je devrai quand même décrémenté les posts qui suivent, et je vois pas alors la différence avec l'id. |
Quand tu supprimes un post tu relis le contenu de ta table derrière, non?
Siron a écrit : Et je dois pas savoir que uniquement le nombre de post, je dois aussi savoir la position de chaque post dans la table. |
...donc tu n'as pas compris ce que je voulais dire par rownum.
Tiens t'as un exemple de ce que c'est et d'un équivalent sous mysql là:
http://clue.denver.co.us/pipermail [...] 11251.html
Siron a écrit : Et je sais pas si c'est moins lourd de décrémenter une fois les id ou de conter chaque fois le nombre de messsage. |
Dépend du nombre de messages que tu as à décrémenter...ça peut être assez lourd...
Et compter des messages c'est qu'un select, ça ne bloque pas la table...
Marsh Posté le 07-11-2005 à 13:26:27
T'embête pas à compter laisser le bordel compter tout seul
Avec mysql t'as limit qui bosse pour toi, pourquoi tu te fais chier???
Marsh Posté le 07-11-2005 à 13:27:42
leflos5 a écrit : T'embête pas à compter laisser le bordel compter tout seul |
parce-que limit te dit pas pour un enregistrement donné combien yen a avant et combien yen a après, au hasard?
Marsh Posté le 07-11-2005 à 13:39:42
J'avais mal compris son truc JE pensais que c'était pour de la pagination pardon
En effet mysql_num_rows() pour le nombre total et après je vois pasz le soucis de savoir où on est dans un tableau pour faire un petit calcul
Marsh Posté le 07-11-2005 à 13:41:17
C'est toujours faisable de traiter ça à 100% en php, oui...
Marsh Posté le 07-11-2005 à 17:37:05
Hum, bien que je suis très contend d'avoir tant de réponse, j'ai peur de pas tout saisir.
A premiere vue, le fait de décrémenter les blogs post créés me convient pour le moment.
Mais comme je suis ouvert à l'apprentissage de mysql, j'aimerais que on m'explique :
Citation : |
Mais je supprime qu'une fois, alors que si je devais reconter, ce serait à chaque lecture.
c'est quoi pagination ?
A quoi sert mysql_num_rows() ?
J'ai pas trouvé de description sur internet.
La technique de décrémentation peut vraiment bloquer la table ? Même j'ai peu de chance d'avoir plein de post ?
Merci encore pour l'aide.
Marsh Posté le 08-11-2005 à 00:16:09
Siron a écrit : Hum, bien que je suis très contend d'avoir tant de réponse, j'ai peur de pas tout saisir.
|
JE pensais que tu voulais faire comme dans le forum, un affichage de numéro de page avec x threads par page ==>pagination
Tu te moques de moi pour internet http://www.google.fr/search?hl=fr& [...] %3Dlang_fr
Pourquoi pas ton truc mais recalculer tous les indices et faire je sais pas combien d'update pour la modif d'un tuple
Alors que t'es obligé de faire un selct donc t'as le nombre de tuple (mysql_num_rows) et tes résultats ils se trouvent où Donc t'as de toutes manières un index continu à la base Sauf si tu utilises un tableau associatif...
Marsh Posté le 08-11-2005 à 07:57:42
Citation : JE pensais que tu voulais faire comme dans le forum, un affichage de numéro de page avec x threads par page ==>pagination |
Ben c'est ce que je veux faire.
Et comme je suis pas fort en algorithme php, le seul que j'ai trouvé pour s'adapter au code que j'ai (qui n'est pas de moi), c'est un algorithme qui demande des id sans trou pour être honnête.
Et pour le moment ça marche bien même si c'est pas optimisé.
Sinon j'ai une autre question mais de php :
Quand je mets lien/index.php?post=$post&page=$page&contenu=$contenu ==> la derniere des trois valeurs ne passe jamais, alors que avec 2 c'est nickel.
c'est a cause d'une limitation à 2 variables par adresse ?
Marsh Posté le 08-11-2005 à 08:02:14
non, ya pas de limitation de ce genre, ça vient de toi.
Et réfléchis à un algo qui fonctionne avec des trous dans les id, c'est pas très compliqué et ça t'évitera un traitement lourd...
Marsh Posté le 08-11-2005 à 11:33:19
Pour une Pagination y a rien a faire c est une variable "page" dans l'URL pour stocker la page courante.
Un count pour le nombre total d'enregistrement en bdd
Une constante pour le nombre d'element par page.
Avec ces 3 trucs tu peux paginer tes resulter et peux importe k il y ai des trous ou pas
Marsh Posté le 08-11-2005 à 14:52:37
Siron a écrit :
|
un id comme son nom l'indique est un identifiant. Il ne doit pas etre modifié à tout bout de champ. C'est comme tu devais changer ton numero de carte d'identité parce que ton voisin est decedé.
Pour de la pagination, tu as la solution du limit. Si tu sais qu'elle page (numero) tu veux afficher, et le nombre de resultats par page, un simple LIMIT suffit
Code :
|
pour afficher la cinquieme page avec 25 resultats par page,tu auras:
Code :
|
Cette solution marche bien mais pour du petit volume, car pour retourner les 25 resultats, le requeteur doit determiner les 100 resultats précédents.
L'autre solution consiste à mettre un champ de position dans la table qui prend max +1 à chaque ajout, et decremente de 1 à chaque suppression si sa valeur est superieure à celle de l'element supprimé.
Marsh Posté le 08-11-2005 à 20:44:55
Mais le problème, c'est pour savoir la page à afficher en fonction du post à montrer, je dois savoir qu'elle est la position du post dans la base, et si l'id à des trous, il me faut donc autre chose.
Il existe une méthode pour savoir combient il y'a de post avant le post visé dans le tableau ?
Marsh Posté le 08-11-2005 à 21:02:21
ma seconde methode fonctionne. Sinon, c'est un compte. Ce n'est pas trop lourd si le champ compté est dans la clé.
Marsh Posté le 08-11-2005 à 21:50:15
$pages = mysql_query('SELECT COUNT(*) AS nb_messages WHERE $id < $idpostdemande FROM siron_blog');
ou $idpostdemande = post cible pour l'afficher.
Et un truc comme ça, ou il compte le nombre de postaavant le post à affiche, afin d'avoir un truc équivalent à son id si il n'y avait pas de trou, c'est pas bon ?
(je suis pas sur de la syntaxe)
cinocks, pour te dire, je suis incapable de vraiment mettre en oeuvre ce que tu me propose comme ça, car je ne connais que ce que j'ai déjà un peu manipulé en mysql dans des codes sources qui ne sont pas de moi.
Le seul truc que je cois pour ne pas devoir décrémenté mes id, c'est de pouvoir connaitre le nombre de post avant le post demandé.
Marsh Posté le 08-11-2005 à 22:27:29
le count fonctionne, par contre jamais de count(*). Ca empeche le moteur d'optimiser son execution de requete. Le but est qu'il n'y ait pas de lecture d'enregistrements. Mais uniquement d'index. Dans ton cas un
Code :
|
Et il faut qu'il y ait un index sur id_message.
par contre, ce n'est pas optimisé du tout. Un aggregat (count) n'est jamais tres bon dans une requete. C'est plutot une solution de depannage.
Marsh Posté le 08-11-2005 à 22:46:41
C'est quoi un index ?
Tu ne connais pas un truc qui permete de savoir le nombre de poste avant le post choisis ?
Marsh Posté le 08-11-2005 à 22:54:23
si la requete que je t'ai cité. Serieusement, fais une recherche Google pour voir comment fonctionne une base de données. Tu iras beaucoup plus vite en comprenant les notions indispensables
Marsh Posté le 09-11-2005 à 07:58:35
Voici le code qui est utilisé pour savoir le nombre de post dans la table.
Avec ce nombre on déduit après le nombre de page qu'il faudra pour tout afficher, et à quel page ce trouve un post cible.
Citation : $NewsParPage = 5; |
Ici le Count est utilisé, et comme le code est lancé à chaque affichage de post, je suppose que c'est très pas bon ?
Marsh Posté le 09-11-2005 à 08:06:56
il faut bien faire un count pour connaitre le nombre de posts si tu n'as pas de compteur gerer automatiquement.
Marsh Posté le 09-11-2005 à 13:05:20
cinocks a écrit : il faut bien faire un count pour connaitre le nombre de posts si tu n'as pas de compteur gerer automatiquement. |
Si la requête récupère tous les tuples concernés un mysql_num_rows() suffit pour pas polluer la requête
Siron, t'es pas un peu têtu
Si tu affiches tes sujets, tu vas les chercher dans la base, non? Donc tu fais comment pour gérer ça en PHP? T'as forcément un tableau que tu vides? Donc tu m'expliques comment tu fais pour pas être capable de connaitre le nombre de post précédents???
Marsh Posté le 09-11-2005 à 13:43:43
oui si tu recuperes tous les tuples. Mais c'est pas je ne me vois pas recuperer 100 000 enregistrements pour un sujet donné si je ne veux en afficher que 25, uniquement pour ne pas faire de requete de compte.
Marsh Posté le 09-11-2005 à 14:20:08
Je suis pas têtu, je suis ignorant.
mysql_num_rows() c'est pour savoir le nombre de ligne mysql affectées par une commande ?
Ca sert à quoi de savoir le nombre de ligne dans mon cas ?
J'ai juste un post cible, par page disont que j'affiche 5 posts, il calcule le nombre de page qu'il faudrait pour afficher tous les posts (nombre qui d'écouvre avec count), ensuite, avec la position du post dans la table (que je fais pour le moment avec les id (qui doivent donc être continues) il trouve la page à afficher, puis il affiche la page.
On me dit que c'est pas bien car il faut évité de modifier l'id.
J'ai une autre idée en tête ==> on trouve la position d'un post dans la table non pas par l'id mais en contant le nombre de post avant lui.
On me dit que c'est pas optimisé count.
je comprends pas ce que on me propose à la place.
Marsh Posté le 09-11-2005 à 14:30:02
ReplyMarsh Posté le 09-11-2005 à 14:32:37
Ah ça je suis d'accord Mais là appliqué à ce qu'il veut faire je suis pas sur qu'on parle de 100000 enregistrements, mais plutot quelques dizaines en tout
Et puis je voyais pas ça comme ça son truc: je comprends qu'il y a l'équivalent d'un post et qu'il veut un sommaire des posts avec leur page
Donc si on considère un petit volume autant utiliser du limit pour les pages et pour le calcul du numéro de page pour le sommaire il a tous les enregistrements (de ce que j'ai compris pas de pagination à cet endroit).
Si dès le départ on pense en million ok on stocke l'in fo quelque part mais bonjour les MAJ.
Et d'accord, un ID reste éternel Donc on y touche pas
Marsh Posté le 09-11-2005 à 14:34:31
Siron a écrit : Je suis pas têtu, je suis ignorant. |
Elle est foutue comment ta bd?
Marsh Posté le 09-11-2005 à 14:42:07
leflos5 a écrit : Ah ça je suis d'accord Mais là appliqué à ce qu'il veut faire je suis pas sur qu'on parle de 100000 enregistrements, mais plutot quelques dizaines en tout |
Je fonctionne ainsi pour mon forum. Pas de LIMIT. Il n'y update que lors d'une suppression de message. C'est sans impact pour moins de 10000 messages après celui supprimé. Au delà ca commence à faire de gros update. Auquel cas, je compte releguer ca en batch la nuit lors de grand calme. Tant que ce n'est pas fait il y aura une page avec un message de moins que sur les autres. Ce qui n'a aucune incidence sur les autres messages.
Marsh Posté le 09-11-2005 à 16:00:45
C'est ça ta seconde solution Cinocks ?
Citation : * SELECT COUNT(id_message) AS nb_messages WHERE id_message < $idpostdemande FROM siron_blog |
ou ça ?
Citation : * SELECT ... |
Ma base de donnée, ben heu, c'est une table qui possède 7 colonnes (je sais pas comment ça se dit dans le jargon) : id, titre, timestamp, style, remarque, text et img, rien de bien complexe en somme.
Et en effet, ma base de donnée, je risque pas d'avoir 500 enregistrement dedans.
Leflos5, effectivement, j'ai une sorte de sommaire à posts, quand on clique sur le lien d'un post, y'a la variable $id du post qui est transmise avec.
Le lien mêne vert une page qui récupere $id, compte le nombre de post de la base de donnée, définit le nombre de post avant le post choisi (c'est la que y'a ma méthode est pas très bonne), compte le nombre de page qu'il faut pour afficher tous les pots, puis avec un petit calcul, définit dans qu'elle page il faut afficher pour voir le post en question.
Marsh Posté le 09-11-2005 à 16:04:24
Euh ce sont 2 requetes differentes qui tu as quoté. Elles ne font pas du tout la meme chose. La premiere compte le nombre d'enregistrements d'id inferieur à celui passé en parametre. Et la seconde te retournes x enregistrements à partir du n-ieme parmi ceux trouvés.
Marsh Posté le 09-11-2005 à 17:41:32
Just, sinon la deuxième je l'utilise aussi pour afficher les messages, à quelque truc près :
Citation : $retour = mysql_query('SELECT * FROM siron_blog ORDER BY id DESC LIMIT ' . $premiereNews . ', ' . $NewsParPage); |
Marsh Posté le 09-11-2005 à 17:56:40
ReplyMarsh Posté le 09-11-2005 à 19:14:52
même si on veut effectivement tout sélectionner?
Marsh Posté le 09-11-2005 à 19:59:30
non. Car plus vite l'ordonnanceur sait ce qu'il doit retourner au final, moins il conservera de données inutiles.
Marsh Posté le 06-11-2005 à 23:29:47
Bonjours, je suis en train de remanier un code de blog.
Dans ce blog (en php et mysql) il y'a moyen de supprimer un post, donc il supprime la ligne de l'id, et donc si par exemple on supprime le post de l'id=5, ça donne id existante : 0, 1, 2, 3, 4, 6, 7, .... jusqu'au dernier post.
J'aimerais donc savoir si il y'a moyen de demander une réorganisation des id afin de décaller tous les posts crées après le post supprimé avec une décrémentation de leur id, afin de retrouver une continuité dans la liste des id existantentes ?
J'ai un peu gogité sur le problème, mais je ne me sent vraiment pas de taille pour codé un truc basé sur l'update des posts, en lui demandant de décrémenter tout les post concernés.
Voici le code qui permet de supprimer un post :
///////////////////////////////////////////////////
/// PREMIERE CONDITION: Si on va delete un post ///
/// OU: Si on a delete un post ///
///////////////////////////////////////////////////
if (isset($_GET['delete_post']))
{
if (isset($_POST['confirmation']) && $_POST['confirmation'] = vrai) //Si on a confirmé qu'il fallait delete
{
mysql_query('DELETE FROM siron_blog WHERE id=' . $_GET['delete_post']); //On delete le post
echo '<p align="center">Le post ' . $_GET['delete_post'] . ' a bien été <font color="#FF0000">supprimé</font><br>Retour au <a href="index.php?contenu=blog">Blog</a>';
}
else //Si ça n'a pas été confirmé, on affiche le formulaire de confirmation
{
?>
<form action="index.php?contenu=blog_gestion&delete_post=<? echo $_GET['delete_post']; ?>" method="post">
<p align="center">Voulez vous vraiment <font color="#FF0000">supprimer</font> ce post (ID: <? echo $_GET['delete_post']; ?> ) ?<p align="center">
<input type="hidden" name="confirmation" value="oui">
<input type="submit" value="Confirmer"><p align="center">
Retour au <a href="index.php?contenu=blog">Blog</a>
</form>
<?
}
////
} //Fermeture de la PREMIERE CONDITION: Si on désire delete un post
////
Merci d'avance pour les réponses.
Siron
Message édité par Siron le 06-11-2005 à 23:31:07