2010-05-06 9 views
0

J'ai une table qui reçoit des entrées d'un site Web, et comme ces entrées vont dans la base de données, elles doivent être assignées à la catégorie suivante sur une liste de catégories qui peuvent être changées à tout moment.Comment affecter une catégorie tournante aux entrées de la base de données dans l'ordre dans lequel les enregistrements sont entrés?

En raison de cette raison, je ne peux pas faire quelque chose de simple comme pour cartographier la première catégorie de 5 à ID 1, 6, 11, 16.

J'ai pris en compte dans la lecture de la liste des catégories actuellement peut-être, et en vérifiant la valeur du dernier inséré, puis en donnant au nouvel enregistrement la catégorie suivante, mais j'imagine que si deux demandes arrivent au même moment, je pourrais potentiellement leur attribuer à la fois la même catégorie plutôt que la séquence.

Alors, mon tour de la pensée actuelle est la suivante:

  • verrouiller les tables (catégories et enregistrements)
  • insérer la nouvelle ligne dans les dossiers
  • obtenir l'ID de la nouvelle ligne
  • select la rangée précédente à l'insertl (en utilisant par ordre décroissant auto_inc_name 0, 1)
  • prendre la catégorie de la ligne précédente, et de saisir le suivant dans la liste de chat
  • mise à jour de la nouvelle ligne insérée
  • déverrouiller la table

Je ne suis pas 100% sûr que cela fonctionnera bien, et il y a peut-être une façon de le faire beaucoup plus facile, donc je demande:

A. Est-ce que cela fonctionnera comme je l'ai décrit dans le problème original? B. Avez-vous une meilleure façon de le faire?

Merci ~

Répondre

1

je le ferais de façon plus simple ... il suffit de faire une table avec une entrée, "last_category" (non signé tinyint NOT_NULL). Chaque fois que vous faites un insert, incrémentez juste cette valeur, et réinitialisez si nécessaire.

+0

Okay donc ...deux formulaires Web entrent en jeu, ils interrogent tous les deux cette table et obtiennent la même réponse pour "la dernière catégorie assignée" et sa cassée. Je suppose que je peux encore juste bloquer les tables, mais c'est presque le même processus étant donné que je devrais rechercher les catégories à chaque fois - vous me sauvez l'étape de trouver la valeur du dernier record en introduisant une autre table. – Stomped

+0

Si vous êtes si inquiet au sujet des soumissions simultanées, vous pouvez faire exécuter la procédure entière en tant que procédure stockée; il veillera à ce qu'une transaction n'ait pas lieu avant que la précédente soit entièrement terminée. Aussi, vous avez raison d'avoir oublié le bit "changé à tout moment"; si c'est ce fluide, demandez-lui le nombre de catégories chaque fois qu'il met à jour pour s'assurer qu'il est incrémenté à une catégorie valide. – eykanal

0

Je ne suis pas sûr que je comprends votre problème, mais si je comprends bien vous voulez avoir quelque chose comme

category | data 
----------------- 
0  | lorem 
1  | ipsum 
....  | ... 
4  | dolor 
0  | sit 
...  | ... 

Que diriez-vous d'avoir une colonne auto_increment unique et laissez la catégorie être le MOD 5 de cette colonne ?

0

Si vous avez besoin d'un comportement correct à 100%, il semble que vous ayez besoin de verrouiller quelque chose quelque part afin que toutes vos insertions s'alignent correctement. Vous pourrez peut-être éviter de verrouiller la table de catégories si vous utilisez une instruction SQL unique pour insérer vos données. Je ne sais pas comment MySQL est différent, mais dans Oracle que je peux faire ceci:

insert into my_table (id, col1, col2, category_id) 
select :1, :2, :3, :4, c.id -- :1, :2, etc are bind variables. :1 corresponds to the ID. 
from 
    (select 
     id, -- category id 
     count(*) over (partition by 1) cnt, -- count of how many categories there are 
     row_number() over (partition by 1 order by category.id) rn -- row number for current row in result set 
    from category) c 
where c.rn = mod(:1, cnt) 

De cette façon, dans une déclaration insérer l'enregistrement suivant en fonction des catégories qui existaient à ce moment-là. L'insertion verrouille automatiquement la table my_table jusqu'à ce que vous validiez. Il saisit la catégorie en fonction du module de l'ID. This link vous montre comment faire un numéro de ligne dans mysql. Je ne suis pas sûr si count(*) requiert group by dans mysql; en oracle, il utilise une partition à la place pour compter l'ensemble des résultats.