2012-06-07 4 views
0

Je travaille sur la création d'un modèle de données pour stocker des données liées au suivi de production. Je travaille pour une firme d'ingénierie qui modélise et analyse des données pour nos clients. Il y a plusieurs étapes dans le processus et le processus est constamment mis à jour. J'essaie de modéliser les processus et d'inclure les processus parents et l'ordre séquentiel des processus.Conception de base de données pour les enregistrements séquentiels pouvant être mis à jour

Par exemple:

Process Table 
--------------------- 
ProcessID - uniqueidentifier 
ProcessName - varchar 
ProcessDescription - varchar 
... 

ProcessOrder Table 
--------------------- 
ProcessID - uniqueidentifier FK - Process 
ParentProcessID - uniqueidentifier FK - Process 
ProcessOrder - int 
... 

La colonne ProcessOrder dans le tableau ProcessOrder serait tout simplement stocker un nombre représentant l'étape séquentielle dans laquelle le processus parent qu'il représente. Par exemple, une procédure de modélisation comporte les étapes suivantes: créer un nouveau modèle vide, nommer un modèle, entrer des paramètres de modèle. Le Process Table ressemblerait à ceci:

ProcessID | ProcessName | ProcessDescription 
------------------------------------------------- 
UUID1  | Modeling | Create Model of Data 
UUID2  | New Model | create new empty model 
UUID3  | Name Model | name model 
UUID4  | Parameters | enter model parameters 

Le ProcessOrder Table ressemblerait à ceci:

ProcessID | ParentProcessID | ProcessOrder 
-------------------------------------------------- 
UUID2  | UUID1   | 1 
UUID3  | UUID1   | 2 
UUID4  | UUID1   | 3 

Le problème avec cette conception est que lorsque le flux de travail est mis à jour, l'ordre de processus changera et je aurai besoin pour mettre à jour l'enregistrement ProcessOrder pour le processus qui a changé et pour tous les enregistrements suivants avec le même ParentProcessID.

Existe-t-il un meilleur moyen de stocker ce type de données et maintenir la normalisation?

Répondre

0

Je pense que la solution est similaire à celle que je proposais à Advise on database design for a project lifecycle

Les données ci-dessus est pour les différentes valeurs d'état décrites dans l'exemple précédent. Ainsi, pour chaque projet client, vous avez les tableaux suivants:

a) Projet client - clientId - référence au client - Statut (FK à ProcessID) - Nom du projet, la description, la date a commencé

b) les changements d'état - qui suit les changements d'un statut à l'autre - projectID - ancien statut (FK à ProcessID) - nouveau statut (FK à ProcessID) - changement de date - notes (et d'autres colonnes comme l'approbation, etc.)

0

Le problème est similaire à la raison pour laquelle les LinkedLists ont de meilleures performances d'insertion (étant donné que vous avez déjà une référence au nœud où vous voulez insérer) par rapport à l'insertion dans une ArrayList.

Dans une ArrayList lors d'une insertion, vous devez déplacer tous les enregistrements pour faire de la place pour la nouvelle insertion. Cela peut prendre du temps O (N) en supposant N enregistrements (imaginez l'insertion au début de la liste).

Dans une LinkedList, il vous suffit de mettre à jour les nœuds au point où vous souhaitez effectuer l'insertion. Avec l'hypothèse ci-dessus, cela prendra O (1) fois que vous avez seulement besoin de mettre à jour le nœud Prev et Next.

Pour mettre en place une structure LinkedList dans une base de données, au lieu d'une colonne ProcessOrder, vous avez deux colonnes, PrevProcessID et NextProcessID.

Le problème survient lors de la sélection de cette option. L'approche naïve serait d'auto-rejoindre récursivement sur la table. Cela provoquera N jointures. Au lieu d'utiliser N jointures, n'utilisez pas de jointures et sélectionnez tous les processus avec l'ID parent.

Dans le code, ont un objet de processus avec les champs suivants: ParentProcessID ProcessID PrevProcessID NextProcessID

Lors de la lecture dans les enregistrements de la sélection, créer ces objets et de les stocker dans une table de hachage avec le ProcessID comme la clé. Cela prendra un temps O (N) pour faire une boucle dans l'instruction select.

Maintenant que les enregistrements se trouvent dans une table de hachage, vous pouvez facilement passer d'un noeud à l'autre en recherchant le paramètre NextProcessID (ou PrevProcessID) dans la table. L'utilisation de HashTable vous évite de faire N jointures et prend à la place le temps O (N) pour l'installation.

En comparant les deux approches

1) La solution actuelle que vous avez maintenant. C'est une solution de type ArrayList (pensez à ProcessOrder en tant qu'index). Les insertions prennent le temps O (N), tandis que vous gagnez du temps sur la lecture car vous n'avez pas besoin de configurer un HashTable. Toutefois, si vous parcourez déjà les enregistrements renvoyés pour configurer les objets d'entité, la durée de l'installation dans la solution LinkedList sera la même.

2) Ma solution proposée. C'est une solution de type LinkedList. Les insertions prennent O (1) en supposant que vous savez où vous voulez insérer. Le temps d'installation prend l'heure O (N).

Questions connexes