2010-02-22 5 views
4

Je crée la base de données pour surveiller l'état des fonctionnalités des applications. La logique est la suivante:Problème de conception de la base de données SQL

Chaque application possède sa propre liste spécifique de fonctionnalités que je surveille. Chaque fonctionnalité appartient à une seule application. Il y a une table de fonctionnalité qui a une clé étrangère à l'application

Chaque application s'exécute sur une ou plusieurs machines. Chaque machine peut exécuter une ou plusieurs applications. Ceci est une connexion MTM, donc il y a des applications de connexion à la table ApplicationInstance avec des machines.

La surveillance actuelle consiste à interroger ApplicationInstance. S'il y a un problème, les informations à ce sujet vont à la table AppInstanceError, qui contient la clé étrangère à ApplicationInstance. Si la requête aboutit, nous obtenons une liste des statuts de chaque fonctionnalité. Nous avons donc une table FunctionalityStatus avec des clés étrangères à ApplicationInstance & Fonctionnalité.

Je pense que c'est une mauvaise conception - pourquoi avons-nous plusieurs références à l'application? Qu'est-ce qui garantit que les deux pointeront vers la même application? Ou y a-t-il un moyen d'assurer cela?

Donc ma proposition de correctif est de connecter FunctionalityStatus avec des clés étrangères aux machines & Fonctionnalité. Mais dans ce cas, ils définissent ApplicationInstance alors quelle est la garantie d'avoir ApplicationInstance pour chaque paire? Ne devraient-ils pas être connectés d'une manière ou d'une autre? Dans le monde réel, la connexion existe et est évidente, alors est-ce OK de ne pas l'avoir dans la base de données? Y a-t-il un moyen de résolution de ce problème ou d'assurer des connexions invisibles à partir de la conception de données?

Pour le rendre plus clair, je préparais la conception de DB que j'ai maintenant: DB design http://img6.imageshack.us/img6/7479/dbexample.png

La seule chose qui manque est une connexion de FunctionalityStatus à la machine. Je vois deux façons OW faire une telle connexion:

  1. Ajouter une clé étrangère à ApplicationInstance - alors mes doutes sont:
    • Comment faire en sorte que ApplicationId de fonctionnalité est le même que celui de ApplicationInstance?
    • Est-ce que cette duplication de données est vraiment nécessaire?
  2. Ajouter une clé étrangère à la machine - et doutes:
    • aura-t-il un record ApplicationInstance de propper pour chaque enregistrement FunctionalityStatus?
    • S'il existe une connexion évidente entre ApplicationInstance et FunctionalityStatus (mentionnée dans le premier doute) que ne pouvons-nous pas voir dans la base de données?
    • données Encore une fois la redondance becouse tous les enregistrements de ApplicationInstance sont (ou devraient être) visibles dans le tableau FunctionalityStatus

Ou peut-être tout le dessin est vissé et je dois trouver quelque chose de totalement autre?

+0

est le functionalityStatus lié à chaque instance de l'application ou à une application particulière? Donc, si une instance d'application est DOWN, considérez-vous que l'application entière est en panne ou juste une instance particulière? Pouvez-vous également expliquer ce qui serait inclus dans les tables de fonctionnalités? Certaines données pourraient aider à voir comment il est utilisé –

Répondre

1

Votre conception me semble bien. Je voudrais aller pour l'option 1, en ajoutant une clé étrangère de FunctionalStatus à ApplicationInstance.

Si vous voulez vous assurer que FunctionalStatus et ApplicationStatus se réfèrent à la même application, vous pouvez ajouter une nouvelle colonne FunctionalStatus.ApplicationId, et rendre la clé étrangère FunctionalStatus-ApplicationStatus comprennent ApplicationId. De même pour la clé étrangère de FunctionalStatus à Functionality.

En d'autres termes, quelque chose comme

CREATE TABLE application 
    (application_id   INT PRIMARY KEY 
    /* Other columns omitted */ 
    ); 
CREATE TABLE application_instance 
    (application_instance_id INT PRIMARY KEY 
    , application_id   INT REFERENCES application(application_id) 
    , machine_id    INT REFERENCES machine(machine_id) 
    /* Other columns omitted */ 
    ); 
CREATE TABLE functionality 
    (functionality_id  INT PRIMARY KEY 
    , application_id   INT REFERENCES application(application_id) 
    /* Other columns omitted */ 
    ); 
CREATE TABLE functionality_status 
    (functionality_status_id INT PRIMARY KEY 
    , application_id   INT REFERENCES application(application_id) 
    , functionality_id  INT /* Part of composite foreign key, see below */ 
    , application_instance_id INT /* Part of composite foreign key, see below */ 
    /* Other columns omitted */ 
    FOREIGN KEY (functionality_id, application_id) 
     REFERENCES functionality(functionality_id, application_id) 
    FOREIGN KEY (application_instance_id, application_id) 
     REFERENCES application_instance(application_instance_id, application_id) 
    ); 
0

Le plus gros problème que vous pourriez avoir est qu'il est toujours possible d'avoir les mêmes ID d'instance pour deux instances différentes de la même application sur la même machine. Le ne peut pas être en même temps, les ID d'instance sont réutilisés au fil du temps et il y a une petite chance que votre application obtienne le même à nouveau. Lorsque je fais ce genre de chose, j'attribue à chaque application un GUID au démarrage, ce qui rend impossible l'utilisation de deux applications avec le même GUID et j'utilise ensuite ce GUID pour les relations. Vous n'avez même pas besoin d'avoir les informations sur la machine dans la relation car chaque machine ne fera jamais le même GUID que n'importe quelle autre machine.

J'ai réalisé après avoir répondu que je n'ai pas vraiment répondu à votre vraie question. Si vous cherchez à voir si certaines fonctionnalités fonctionnent d'une certaine manière, il est préférable de les relier à la machine et à l'application où la fonctionnalité ne fonctionne pas comme vous le souhaitez ou si vous avez du mal à trouver celle qui fonctionne et laquelle un faux. Avoir trois tables une pour les machines, une pour les applications et une pour la fonctionnalité serait la meilleure conception de la base de données. Selon ce que vous faites, il peut être plus facile et plus rapide pour le logiciel de dupliquer toutes les informations de l'application et de la machine pour chaque ensemble de fonctionnalités, surtout si les informations sur la machine et l'application ne sont qu'un champ. Vous ne voulez vraiment pas ralentir la fonctionnalité pour la journalisation de cette information si vous pouvez l'aider, alors vous voulez l'avoir fait rapidement.

+0

Merci pour votre aide, mais je pense que vous avez mal compris ma question. J'ai posté une image contenant plus de détails, peut-être que cela clarifiera la question. – ssobczak

0

Si elle était moi c'est ainsi que je le ferais:

  1. Créer 5 tables, machine, application, la fonctionnalité, ApplicationPool et le journal.
  2. Mettez une colonne FK dans la fonctionnalité, qui est l'ID de l'application la fonctionnalité existe pour.
  3. ApplicationPool aurait une machine colonne ID, une colonne d'ID d'application, clé primaire qui est soit un GUID ou une identité ensemencée, un ID de ApplicationInstance qui être votre NomApplication + PK. Si vous pouvez c'est ce que j'utiliserais pour nommer vos applications vos machines.
  4. Enfin, je voudrais faire la table de journal et donner une colonne FK que référence le PK de ApplicationPool. Ensuite, chaque fois que vous avez enregistré quelque chose, vous pouvez l'ajouter à la table de journal et toutes vos informations sur l'application seront stockées séparément.

Si ce n'est pas proche laissez-moi savoir, car je pourrais avoir mal compris ce que vous cherchez.

+0

Ceci est une partie de la solution, mais vous avez manqué la partie sur deux tables de journal. J'ai posté une image, peut-être que ce sera plus descriptif que des mots. – ssobczak

Questions connexes