2010-01-26 5 views
1

J'ai besoin de quelques suggestions pour implémenter une règle de gestion - que ce soit pour la garder en DB (en utilisant TRIGGERs) ou en code App.Une suggestion de niveau de conception SQL DB et App est nécessaire. Contrainte dans DB ou App?

--- Table structure:--- 

# ORG - Master table for Organizations 
# USER - Master table for Users (each user belongs to an Org so there's a field OrgId which is FK ro ORG) 
# SITE - Master table for Sites 

# ORGSITE - {OrgId, SiteId} links Site(s) with Org(s) 
# USERSITE - {UserId, SiteId} links Site(s) with User(s) 

La contrainte est que: « Un site est accessible à un utilisateur que si son accès à son organisation. »


Maintenant, il arrive dans l'application que sur day1 nous relions Site1 à org1 et nous sommes en mesure de relier Site1 à User1 (Utilisateur1 appartient à Org1). Le jour 2, je supprime la relation entre Site1 & Org1 de ORGSITE (cela nécessite que je supprime également la relation User1 & Site1 correspondante de la table USERSITE).

Ceci est géré depuis le code de l'application. Donc, maintenant ma question est là shud je garde la gestion des contraintes ci-dessus -

APPROCHE # 1:

Déployer Déclenche sur la table ORGSITE et table USER qui se chargera de l'activité pour:

  1. sur après pour supprimer ORGSITE (supprimer enregistrements USERSITE correspondants)

  2. Onafter mise à jour pour utilisateur (si l'utilisateur de Ou g est modifié puis supprimez tous ses enregistrements de USERSITE)

APPROCHE # 2:

Poignée tout à l'intérieur du code - appuyez sur les événements qui déclenchent les actions DB et supprimer des enregistrements de USERSITE (en tant que de besoin). Besoin de gérer via une transaction.

APPROCHE # 3:

Simplement, ajouter un nouveau OrgSiteId de champ dans la table de USERSITE qui est un FK ref à un 'Auto Increment PK: Id' de ORGSITE. Ensuite, je vais déployer la suppression en cascade pour le FKS USERSITE.OrgSiteId. Cela va gérer la plupart des choses et le rendre implicite!

Espérons que j'ai bien expliqué. L'APPROCHE N ° 3 va-t-elle vraiment marcher? Si non, quelle est votre préférence et pourquoi?

Nous vous remercions de votre temps.

+0

approche # 3, je pense que le FK peut le rendre beaucoup plus facile et fwd droit (elle impose la contrainte physique v.well). En particulier, le fait que je puisse avoir une relation FK n place (ce qui aide à accélérer l'accès aux données dans les tables JOIN) et gère également la contrainte via sa fonction de relation FK implicite 'suppression en cascade'. –

Répondre

4

Si vous pensez que quelqu'un aurait jamais exécuter une requête directement à partir de la DB (quelqu'un comme, par exemple, un DBA), alors vous devez le manipuler dans un déclencheur. Si vous le faites via l'application, vous devez toujours le faire à travers l'application.

+0

Pas de manipulation de données via DB - c'est fait à partir de l'application –

0

Vous pouvez utiliser des déclencheurs; C'est une option viable qui fonctionnerait. Personnellement, je n'utiliserais pas les suppressions en cascade, car cela peut être dangereux.

J'ai tendance à préférer l'option de code, car elle me permet de gérer les erreurs, de consigner et de vérifier les références. Vous avez une partie de cela dans les déclencheurs, mais c'est ma préférence personnelle. De plus, cela met la logique avec votre autre code de changement d'application, de sorte que toute la logique est dans un endroit, et non éclaté en application/base de données. Mais encore une fois, c'est une préférence personnelle pour moi; les déclencheurs sont une option parfaitement bonne et viable.

HTH.

3

Je suggère:

  • Supprimez la table de UserSite
  • Créer une vue appelée UserSite

    SELECT a.UserId, b.SiteID de l'utilisateur un LEFT JOIN b.OrgSite ON b.orgid = A.Org

Ceci retournera les sites que l'utilisateur peut voir, ou NULL s'il ou elle ne voit pas

+0

En effet c'est une bonne solution et FYI, j'ai déjà une vue en place qui «obéit» la même chose. Mais je ne peux pas ignorer l'incohérence des données alors que la seconde moitié de cette solution - je dois mettre en œuvre l'une de ces 3 approches –

+0

Vous ne savez pas ce que vous voulez dire? Une fois que vous supprimez les relations SITE et ORG dans la table OrgSite, la vue reflète automatiquement cela? Si je mal compris quelque chose, s'il vous plaît laissez-moi savoir ... – Sparky

+0

Bien sûr, la VIEW avoir des données cohérentes mais qu'en la table UserSite réelle? Il y aura toujours des disques 'orphelins' dont je ne veux pas. Parce qu'il peut être dangereux dans le cas où cette table est référencée séparément –

1

-ce que les orgs heirarchical? Y a-t-il un champ ORG.parent_org_id? Si c'est le cas, votre problème est un peu plus difficile, car vous avez probablement besoin d'une personne pour voir tous les SITE liés à leur organisation ou aux enfants de leur organisation (un peu comme les permissions de dossier dans un système de fichiers).

La solution de vue de Sparky pourrait encore travailler ci-dessus dans ce cas, si votre base de données prend en charge ou JOIN common table expressions récursive. La manière standard ANSI de le faire est avec les CTE (seulement supporté par SQL 2005 et plus tard et PostgreSQL je pense). Oracle et les autres DB ont une syntaxe non standard pour la même fonctionnalité de récursivité.

+0

Bon point! Mais non pour l'instant nous n'avons pas de hiérarchie pour User ou Org donc c'est plat. –

Questions connexes