2008-12-05 8 views
0

C'est quelque chose qui me fait douter pendant un certain temps, donc je pensais que ce serait une bonne idée de poster ici pour un aperçu, il y a un problème de modélisation de base de données relationnelle/douteModélisation des entités relationnelles Problème

Je la problème suivant:

J'ai des "questions" qui doivent être dans un "état" spécifique, et tous les changements d'état doivent être audités.

J'ai trouvé deux solutions à cela, mais je ne peux pas vraiment voir la différence entre eux, s'il y en a ... que pensez-vous.

Voici l'image avec les deux diagrammes.

EDIT:

Option A: table "questions" ne doivent pas contenir state_id et Question_State ne doivent pas contenir le champ "id". Désolé pour les erreurs.

EDIT2:

Merci pour tous les exemples réels du monde et perspicacité, mais cela était un problème académique, pas dans le monde réel :) liés.

Diagrams http://i38.tinypic.com/2v27epl.png

Répondre

5

Je pense que l'essentiel de ce que vous demandez est: Si l'état de la question soit fondée sur une table intermédiaire entre Questions et État qui a un composant temps (A) ou doit être plus statique, mais avec une table d'historique orientée journal sur le côté (B). (Note: Si vous vouliez faire une version pure de (A), alors Boofus a raison, vous ne mettriez probablement pas aussi bien le state_id dans le tableau Questions, car il est redondant, mais ce serait certainement gênant parce que cela rendrait beaucoup plus difficile les requêtes simples pour obtenir des questions dans un état particulier.) Donc, vous avez une version hybride ici.)

En général, si l'exigence de conserver des informations historiques sur l'état est vraiment juste à des fins d'audit. si l'application elle-même ne le demande pas régulièrement, il est probablement préférable d'utiliser l'option B, car c'est un peu plus simple (il n'y a vraiment qu'une seule table "Questions", avec une table de référence pour le états, et une table "log" pour les états précédents). Je pense que cela montre un peu mieux votre intention. Cependant, si la sémantique de l'application est plus complexe (par exemple, si vous avez des requêtes comme "afficher toutes les questions qui ont été à l'état X dans les dernières 24 heures ..."), alors une approche comme (A) pourrait avoir plus de sens. C'est essentiellement faire de l'état d'une question un fait dépendant du temps.Si vous faites cela, sachez que cela complique les choses - soit toutes vos requêtes sont plus difficiles et doivent prendre en compte le temps, soit vous devez garder l'état state_id sur Questions en synchronisation avec l'état le plus récent dans le tableau Questions. Si vous suivez cette route, appelez-la "current_state" ou quelque chose sur Questions, il est donc clair que c'est une sorte d'information dérivée.

0

Une fois que vous dessinez dans toutes les relations, ce sont les mêmes. Je ne comprends pas pourquoi vous avez state_id dans la table des questions - puisque vous avez la table historique, l'état de la table des questions est redondant et peut vous donner des données désynchronisées.

me semble que si vous voulez que l'état actuel sur une question, vous

SELECT state_id DE historique des question_id =? ORDER BY date DESC LIMIT 1

(ou toute autre méthode de votre goût de SQL utilise pour limiter à 1 ligne)

+0

Cela rend les requêtes comme "SELECT * FROM Questions WHERE status = 'X'" beaucoup plus difficile à écrire. –

0

En supposant que vous ayez de bonnes couches d'abstraction entre la base de données et votre OO, vous pouvez envisager de retirer la table d'état de la base de données et d'en faire une énumération dans une classe. Ce n'est pas nécessairement quelque chose qui doit être persistant.

Ensuite, ayez la colonne State dans la table Questions et la table d'audit.

+0

ce n'était pas la question mais merci quand même! –

0

Vous dites audité, ce qui implique que vous souhaitez simplement conserver des informations historiques à des fins de reporting. Dans ce cas, je suggérerais que le diagramme B est le plus clair, bien que vous deviez probablement marquer les relations un à plusieurs entre les questions historiques et historiques et historiques. En ce qui concerne les aspects pratiques, si les circonstances sont comme ci-dessus, je voudrais encapsuler la fonctionnalité d'insertion historique dans un déclencheur d'insertion/mise à jour sur Questions, et si le volume de la table Questions et/ou le nombre de changements d'état Pour être significatif je considérerais mettre la table historique dans une base de données différente. Cela facilite simplement la gestion de la base de données plus tard. Normalement, je me méfie des déclencheurs car une utilisation trop zélée peut conduire à des bases de données difficiles à maintenir (car ce n'est pas immédiatement évident), mais il s'agit d'un cas clair où ils sont bien adaptés et constituent un choix supérieur à l'utilisation. logique d'application. Incidemment, vos deux diagrammes impliquent qu'une question ne peut jamais entrer dans chaque état qu'une seule fois (à partir de votre PK) - vous devriez considérer si cela est correct car dans la plupart des applications du monde réel, des erreurs seront commises et des états inversés.

1

Vous pouvez parcourir le Web au sujet des "bases de données temporelles". Fondamentalement, stocker l'historique des changements de n'importe quelle variable soulève les mêmes problèmes, peu importe si la variable capture l'état de la question ou le poids de la personne ou quoi que ce soit. Deuxièmement, je pense que votre question concerne la conception de bases de données, et non la modélisation de données conceptuelles. Si je comprends bien, vous demandez quelle table est la meilleure. Troisièmement, j'aime mieux l'option B, mais cela dépend vraiment de ce que vous allez faire avec les données. La raison pour laquelle j'ai posé des questions sur la conception de bases de données par rapport à la modélisation conceptuelle est qu'il y a longtemps que j'ai adopté la pratique d'utiliser des «entités et relations» pour la modélisation conceptuelle associée à l'analyse de données. J'utilise les termes "tables, colonnes et lignes" lorsque je parle de la conception d'une base de données logique. Garder l'analyse et la conception séparées s'avère très utile dans les grands projets. Et ce n'est pas aussi facile à faire que ça en a l'air.

Vous devriez vraiment ajouter une flèche entre la table Historique et la table d'état dans le diagramme de l'option B. La façon dont le diagramme est présenté ressemble presque à une table disjointe. Ce n'est pas un problème dans cet exemple simple, mais si vous maintenez la même pratique lorsque vous mettez à l'échelle des bases de données avec des dizaines de tables, vous finirez par dérouter tout le monde qui regarde le diagramme.

0

Je n'ai pas compris, comme #Boofus, l'intérêt d'avoir un champ state_id dans la table Questions.

J'ai travaillé beaucoup avec de tels concepts «d'état» dans notre propre application.Dans la plupart des situations complexes, où nous devons suivre un historique de l'état complet et les situations où un objet peut avoir plusieurs états, nous utilisons le modèle suivant:

alt text

Pour de multiples situations de l'État, l'idée est de vérifiez si la valeur de end_date est null (une autre idée serait d'avoir un champ booléen isActiveState dans la table). Ne sous-estimez pas l'intérêt d'avoir cette configuration "à états multiples". Exemple:

Une question peut être

  • fermé et résolu

ou

  • fermé et non résolu.

Cela pourrait correspondre soit à 2 états différents:

  • A "fermé et résolu" Etat

ou

  • A "Fermé et non résolu" état

Mais je pense que la meilleure solution serait d'avoir à la fois un

  • A "ouvert/fermé" état

et

  • A "Résolu/Unsolved" état

Et de permettre que la question soit multipliée e states

Questions connexes