2010-10-06 4 views
4

Je travaille sur un projet dans lequel nous devrons déterminer certains types de statuts pour un grand nombre de personnes, stockés dans une base de données. Les règles métier pour déterminer ces statuts sont assez complexes et peuvent changer.application de règles métier au niveau de la base de données

Par exemple,

if a person is part of group X 
and (if they have attribute O) has either attribute P or attribute Q, 
or (if they don't have attribute O) has attribute P but not Q, 
and don't have attribute R, 
and aren't part of group Y (unless they also are part of group Z), 
then status A is true. 

Multiplier par plusieurs statuts douzaines, voire des centaines de groupes et d'attributs. Les personnes, les groupes et les attributs sont tous dans la base de données.

Bien que cela sera consommé par une application Java, nous voulons également pouvoir exécuter des rapports directement sur la base de données, il serait donc préférable que l'ensemble des états calculés soit disponible au niveau des données. Notre plan de conception actuel consiste donc à avoir une table ou une vue constituée d'un ensemble de drapeaux booléens (hasStatusA? HasStatusB? HasStatusC?) Pour chaque personne. De cette façon, si je veux interroger tout le monde qui a le statut C, je n'ai pas besoin de connaître toutes les règles pour le calcul du statut C; Je vérifie juste le drapeau.

(Notez que, dans la vraie vie, les drapeaux auront des noms plus significatifs: isEligibleForReview ?, isPastDueForReview ?, etc.).

Donc a) est-ce une approche raisonnable, et b) si oui, quelle est la meilleure façon de calculer ces drapeaux?

Certaines options que nous envisageons pour les drapeaux de calcul:

  1. Faire l'ensemble des drapeaux vue, et calculer les valeurs de drapeau des données sous-jacentes en temps réel à l'aide de SQL ou PL-SQL (ce qui est une base de données Oracle). De cette façon, les valeurs sont toujours précises, mais les performances peuvent en souffrir, et les règles doivent être maintenues par un développeur.

  2. Faites en sorte que l'ensemble d'indicateurs soit composé de données statiques et utilisez un moteur de règles pour maintenir ces indicateurs à jour lorsque les données sous-jacentes changent. De cette façon, les règles peuvent être maintenues plus facilement, mais les drapeaux pourraient être inexacts à un moment donné. (Si nous allons avec cette approche, est-il un moteur de règles qui peuvent facilement manipuler des données dans une base de données de cette façon?)

+0

À quelle fréquence vos données seront-elles mises à jour? Parlons-nous de ce statut pourrait changer chaque minute, heure, jour, semaine? – JNK

+1

Votre exemple se lit comme Prolog. – Dave

+0

Les attributs peuvent changer quotidiennement; groupes peut-être mensuels. Statuts devraient idéalement être précis dans une minute ou deux d'un changement d'attribut. Les règles elles-mêmes devraient changer moins souvent; peut-être tous les quelques mois. –

Répondre

2

Dans un cas comme cela, je suggère d'appliquer question- Ward Cunningham vous demander « Quelle est la chose la plus simple qui pourrait fonctionner? ".

Dans ce cas, la chose la plus simple pourrait être de créer une vue qui regarde les données telles qu'elles existent et fait les calculs et les calculs pour produire tous les champs qui vous intéressent. Maintenant, chargez votre base de données et essayez-le. Est-ce assez rapide? Si oui, bien - vous avez fait la chose la plus simple possible et cela a bien fonctionné. Si ce n'est pas assez rapide, bon - la première tentative n'a pas fonctionné, mais vous avez les règles tracées dans le code de la vue. Maintenant, vous pouvez essayer la prochaine itération de "la chose la plus simple" - peut-être que vous écrivez une tâche de fond qui surveille les insertions et les mises à jour, puis saute dedans pour recalculer les drapeaux. Si cela fonctionne, bien et dandy. Sinon, passez à l'itération suivante ... et ainsi de suite.

Partagez et appréciez.

+0

Le rasoir d'Occam :) –

0

Je vous déconseille de définir les statuts en tant que noms de colonne, mais d'utiliser un identifiant et une valeur d'état. comme une table d'état client avec des colonnes d'ID et de valeur.

Je voudrais deux méthodes pour mettre à jour les statuts.Une procédure stockée qui a toute la logique ou des appels sépare les processus stockés pour comprendre chaque état. vous pouvez faire tout cela dynamique en ayant une fonction pour chaque évaluation d'état, et le proc stocké pourrait alors appeler chaque fonction. La 2ème méthode consisterait à avoir n'importe quel proc stocké, à mettre à jour les informations de l'utilisateur, à appeler un proc stocké pour aller mettre à jour tous les statuts des utilisateurs en fonction des données actuelles. Ces deux méthodes vous permettent d'avoir à la fois des mises à jour en temps réel pour les données qui ont changé et si vous ajoutez un nouveau statut, vous pouvez appeler la méthode pour mettre à jour tous les statuts avec une nouvelle logique.

Espérons que vous ayez un point de mise à jour des données utilisateur, tel qu'une mise à jour de l'utilisateur stockée proc, et que vous puissiez mettre la mise à jour de l'état stocké appel proc dans cette procédure. Cela évite également d'avoir à planifier une tâche toutes les n secondes pour mettre à jour les statuts.

0

Une option que je considérerais serait que chaque indicateur soit soutenu par une fonction déterministe qui renvoie la valeur mise à jour en fonction des données pertinentes.

La fonction peut toutefois ne pas fonctionner correctement si vous l'appelez pour plusieurs lignes à la fois (par exemple, pour la création de rapports). Donc, si vous êtes sur Oracle 11g, vous pouvez résoudre cela en ajoutant virtual columns (recherche de "colonne virtuelle") aux tables pertinentes en fonction de la fonction. La fonctionnalité Result Cache devrait également améliorer les performances de la fonction.

Questions connexes