2009-10-15 7 views
0

Je travaille sur une application particulière. Sa structure de base est la suivante:Stockage des tâches dans la base de données

  • une base de données
  • une interface Web pour contrôler l'ensemble du système
  • un certain nombre d'applications clientes sur des machines distantes

Les clients sondage la base de données à intervalles réguliers intervalles, pour vérifier si tâches à effectuer. Une tâche est:

  1. Un nom officiel de la tâche (une chaîne), par exemple "run-régression test"
  2. Un certain nombre d'arguments. Pour simplifier, supposons que ce sont des chaînes. Il n'y a pas besoin de soutenir plus que, disons, dix arguments.

Si le client récupère une tâche, il analyse le nom et les arguments et exécute certaines actions.

Étant donné que toutes les informations d'état sont stockées dans la base de données, les tâches doivent également y être stockées. Ce que je ne sais vraiment pas, c'est comment le mettre en œuvre aussi proprement que possible. Chaque solution que je peux trouver semble presque comme un anti-pattern. On pourrait stocker dans une table unique comme celui-ci:

create table tasks (
    id int not null auto increment primary key, 
    name varchar(255), 
    arg1 varchar(255), 
    arg2 varchar(255), 
    ... 
) 

Je pensais aussi de le faire en utilisant deux tables:

create table tasks (
    id int not null auto_increment primary key, 
    name varchar(255) 
) 

create table task_args (
    id int not null auto_increment primary key, 
    task_id int, 
    arg varchar(255) 
) 

C'est un peu plus souple et plus facile à mettre en œuvre aussi bien. Cependant, il est impossible de dire quel argument parmi un certain nombre d'argumens est premier, lequel est second, etc. (peut être corrigé en ajoutant une colonne "sequence" à la table task_args).

Je suis sûr qu'il y a des façons meilleures et plus propres de faire ce que je veux. Peut-être que quelqu'un avec de meilleures compétences en conception d'applications peut me donner de l'inspiration.

Merci d'avance.

+0

Avant de pouvoir répondre à cette question, je voudrais savoir si le client exécute la tâche DB directement IE EXEC ("functionsX (param1, param2)")? Ou auront-ils besoin de recompiler leur application chaque fois qu'une nouvelle fonction est ajoutée, car ils vont "basculer" le type de fonction et appeler la fonction elle-même IE switch ("functionX") {case "functionX": functionX (param1, param2); Pause;} ? –

+0

Non, ils n'exécutent pas la tâche directement, j'aurais peut-être dû être plus clair à ce sujet. Le nom de la tâche est associé à un certain gestionnaire sur les clients. Par exemple, la tâche portant le nom "run-regression-test" et les arguments ("/ usr/local/src") peuvent signifier "exécuter le script regression-test.sh dans le répertoire/usr/local/src". – shylent

Répondre

2

Basé sur la colonne auto_increment, je suppose que votre base de données cible est MySQL. Dans PostgreSQL j'utiliserais probablement un tableau de varchars pour ceci. C'est plus pratique pour des choses comme ceci où les valeurs dans la liste ne sont pas des clés étrangères ou vous n'avez pas besoin de les interroger. Dans MySQL, vous ne pouvez pas le faire, et en utilisant argX colonnes ou sérialisation le tableau vous est tout simplement faux, donc j'utiliser ceci:

create table tasks (
    id int not null auto_increment primary key, 
    name varchar(255) 
); 

create table task_args (
    task_id int not null, 
    no int not null, 
    arg varchar(255), 
    primary key (task_id, no) 
); 

Pour obtenir tous les arguments pour une tâche que vous courriez SELECT arg FROM task_args WHERE task_id=? ORDER BY no.

+0

Vraiment, quelle honte. Pourquoi ai-je dû faire un gâchis hors de mon deuxième modèle (pas besoin d'une colonne distincte de pk id dans la table d'args)? Je ne le saurais jamais. Oui, le SGBD est, en effet, mysql. – shylent

+0

Vous avez besoin d'un PK séparé si les lignes ne sont pas ordonnées comme dans votre version. Ma version aura des lignes telles que (1, 1, 'arg1'), (1, 2, 'arg2'), etc. Les colonnes 'task_id' et' no' doivent toujours être uniques, donc vous pouvez tout aussi bien utilisez-les comme clé primaire (vous n'avez pas besoin d'un index supplémentaire sur 'task_id', dont vous auriez besoin autrement). –

1

Je dirais que cela dépend vraiment de la façon dont le client va analyser l'information et si vous préférez rendre les clients plus simples. Par exemple, si vous voulez que les clients soient simples, je suggérerais votre deuxième conception et ajouterais la colonne sequence. Ensuite, votre client n'a pas à tenter d'analyser les données, il sait déjà qu'il regarde un nombre entier (ou peut demander simplement assez).Cependant, si les clients sont déjà assez intelligents, ou s'ils sont écrits dans un langage qui rend difficile l'interface avec la base de données (C peut-être), je pourrais simplement stocker toute la "tâche de commande" comme une chaîne et avoir les clients l'analysent comme des jetons.

Il y a des inconvénients évidents pour les deux en fonction de la langue, mais je pense que votre décision finale se résume à l'endroit où vous voulez mettre la majorité de la logique.

+0

Bon point. Les clients vont être écrits en perl ou en python, je pense. Au moins, je suis sûr, que l'interaction avec la base de données ne sera pas un problème, donc pas besoin de stocker les tâches en tant que chaînes tokenized. – shylent

Questions connexes