2009-02-02 6 views
0

Je suis en train d'écrire une application de planification pour ma femme, et j'ai rencontré la question suivante.Expression des contraintes de données dans SQL

J'ai un schéma qui peut être décrit en termes ActiveRecord comme tel:

  • Chaque ressource a et appartient à de nombreux événements s
  • Chaque événement a et appartient à un grand nombre ressource s, et a beaucoup timespan s
  • Chaque ti mespan appartient à un événement , et a trois attributs: jours, start-temps et fin du temps.

Je veux mettre les contraintes suivantes sur mes données:

 
    A. For each timespan, timespan.start-time ≤ timespan.end-time 
    B. For each event, for each t_a, t_bTIMESPANS(event), 
     either t_a = t_b 
      or t_a.day ≠ t_b.day 
      or t_a.end-time ≤ t_b.start-time 
      or t_a.start-time ≥ t_b.end-time 
    C. For each resource, for each e_a, e_bEVENTS(resource), 
     either e_a = e_b 
      or for each t_aTIMESPANS(e_a) and t_bTIMESPANS(e_b), 
       either t_a.day ≠ t_b.day 
        or t_a.end-time ≤ t_b.start-time 
        or t_a.start-time ≥ t_b.end-time 

(A) fait bien sûr plages temporelles formées, (B) fait des événements sûrs ne le font pas auto-conflit, et (C) s'assure que les ressources ne sont pas sur-programmées.

Actuellement, j'applique ces contraintes à la couche d'application, mais, dans l'intérêt de l'auto-apprentissage, je me demandais si je pouvais mettre ces contraintes dans la couche de base de données.

Existe-t-il un moyen d'exprimer ces contraintes dans SQL?

EDIT: Je trouve que ce que je voulais était la déclaration de SQL CREATE ASSERTION (au moins, pour ceux qui ne pouvaient pas être couverts par une simple CHECK), mais il ne semble pas comme les SGBDR supports il (at least, as of 2005)

+1

Vous planifiez votre femme? ;-) – Ben

+0

pour ma femme à utiliser: P – rampion

Répondre

2

A est facilement exprimé dans un CHECK CONSTRAINT sur votre table de temps, puisque chaque ligne peut vérifier elle-même la cohérence sans vérifier les autres lignes.

B et C sont plus complexes et nécessiteraient une information de lecture sur d'autres tables. Dans ce cas (au moins dans SQL Server), on pourrait utiliser une fonction définie par l'utilisateur (en lui passant les valeurs de la ligne courante) pour vérifier les autres tables ou utiliser un TRIGGER qui vérifie les autres tables. NB: Lors de l'écriture d'un tel déclencheur, rappelez-vous qu'un déclencheur se déclenche une fois pour une instruction SQL. Si cette instruction contient plusieurs lignes, la table INSERTED contiendra plusieurs lignes, qui doivent toutes être vérifiées pour correspondre à vos contraintes de domaine à l'aide d'une technique appropriée, par

BTW: Joe Celko avait un good article récemment sous contraintes.

+0

Merci! C'était très utile. – rampion

Questions connexes