2010-01-12 10 views
0

J'ai une application web, dont l'une des fonctions est d'ajouter constamment des lignes à une grande table. Les lignes ressemblent à peu près à ceci:Lire de manière fiable à partir d'une table constamment ajoutée

id bigint not null primary key 
visited datetime not null 
ip_address 
# Other fields 

C'est une table de suivi, comme vous l'avez probablement deviné. L'utilisation de cette table est entièrement append-only, c'est-à-dire qu'il n'y a pas de ligne de modification après l'insertion de . Cependant, notre volume de données a considérablement augmenté et il est devenu nécessaire de traiter les statistiques séparément dans d'autres tables, plutôt que d'interroger les données et de les calculer immédiatement. Fondamentalement, j'ai écrit un programme autonome qui fait à peu près ce (pseudo-code)

while (true) { 
    Select rows from tracking table where id > last_id 
    Feed rows to stats processing thread 
    last_id = max(id from rows) 
    sleep some amount of time (~30sec is what I'm currently using) 
} 

Cependant, je suis inquiet, je manquerai les lignes. Une lacune dans les ID peut se produire car au moment où je sélectionne les lignes de la table de suivi, certains des ID de ligne ont été réservés, mais les données de ces transactions n'ont pas encore été validées, et sur la boucle suivante j'ai déjà déplacé sur les nouveaux ID.

Je me demandais comment concilier cela, car les données manquantes lors du calcul des statistiques n'est pas vraiment une option.

Voici les différentes options que je suis autour de: lancer

  1. Refonte la table ou une requête sur quelque chose comme le temps visité

  2. Ne pas utiliser un DB relationnelle, mais quelques-uns sorte de système de file d'attente de données?

  3. interroger la table sur un laps de temps, à savoir WHERE id> last_id et visité < NOW() - temps

Il est aussi possible qu'il y ait une option que je ne l'ai pas considéré. Quel est le meilleur moyen d'interroger la table pour ne manquer aucune donnée?

Répondre

0

est ici d'une manière que vous pourriez faire (quelque chose comme votre # 2):

  1. Répliquez vos données à une base de données « entrepôt » séparée.
  2. Effectuez un ETL afin que vos données soient normalisées dans votre entrepôt de façon plus optimale pour vos requêtes/analyses statistiques. Pour chaque type d'enregistrement, incluez une colonne supplémentaire qui servira de drapeau "status" indiquant si l'enregistrement a été lu par votre moteur d'analyse.
  3. Demandez à votre analyse de mettre à jour la colonne "lu" une fois qu'il a lu un enregistrement.
+0

Merci d'avoir pris le temps de répondre :) J'ai décidé de mettre en place une variante de votre réponse. Étant donné qu'une faible latence entre les données stockées et traitées est une priorité, je vais toujours lire la table d'origine (en ignorant la réplication et l'ETL), mais je garderai une autre table pour que le moteur d'analyse enregistre quel identifiant il a. vu. – Crast

+0

@Crast sonne bien, bonne chance! –