IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 PostgreSQL Discussion :

Contrainte sur une colonne


Sujet :

PostgreSQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2014
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2014
    Messages : 10
    Par défaut Contrainte sur une colonne
    Bonjour à tous,

    je vous présente rapidement mon problème puis je vous pose ma question.

    J'ai trois tables :
    • Utilisateurs avec l'uid et les pseudos des utilisateurs
    • Roles avec un identifiant (rid) et les noms de mes rôles
    • Utilisateurs_Roles une table de jonction entre les deux précédentes


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    CREATE TABLE IF NOT EXISTS Utilisateurs (
    	uid SERIAL,
    	username VARCHAR(45) NOT NULL,
    	...
    	PRIMARY KEY (uid),
    	UNIQUE (username)
    );
     
    CREATE TABLE IF NOT EXISTS Roles (
    	rid SERIAL,
    	nom VARCHAR(60) NOT NULL,
    	PRIMARY KEY (rid),
    	UNIQUE (nom)
    );
     
    CREATE TABLE IF NOT EXISTS Utilisateurs_Roles (
    	uid INT NOT NULL,
    	rid INT NOT NULL,
    	PRIMARY KEY (uid, rid),
    	FOREIGN KEY (uid)
    		REFERENCES Utilisateurs(uid)
    		ON DELETE CASCADE,
    	FOREIGN KEY (rid)
    		REFERENCES Roles(rid)
    		ON DELETE CASCADE		
    );
    Je souhaite créer une table 'classe' avec une contrainte sur la colonne uid
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    CREATE TABLE IF NOT EXISTS Classes (
    	id SERIAL,
    	nom VARCHAR(45),
    	profPrinc_id INT, 
    	PRIMARY KEY (id),
    	UNIQUE (nom),
    	FOREIGN KEY (profPrinc_id)
    		REFERENCES Utilisateurs(id)
    		ON DELETE SET NULL
    )
    J'aimerais que sur la clé profPrinc_id il y ait une contrainte pour qu'on ne puisse mettre que des uid d'utilisateurs ayant un certain rôle (exemple rid = 3).
    Ma première idée était d'introduire une sous-requête dans un CHECK sur profPrinc_id mais ce n'est apparemment pas possible (d'après mes recherches).

    Quelqu'un aurait-il une idée pour cela ? Ou faut-il que je déplace le problème dans mon php ?

    Merci par avance

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Par défaut
    Bonjour,

    utilisez des triggers : before insert / before update


    Regardez la doc pour des exemples

  3. #3
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 998
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 998
    Billets dans le blog
    6
    Par défaut
    C'est votre modélisation qui est foireuse. Si vous avez besoin de distinguer certains utilisateurs d'autres, alors il vous faut faire une spécialisation via l'héritage de données.

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  4. #4
    Membre habitué
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2014
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2014
    Messages : 10
    Par défaut
    Bonjour,

    merci pour vos réponses.
    Je ne connaissais par les triggers (pas encore), je vais aller y jeter un œil.

    @SQLPro : effectivement, je suis en train de re-réfléchir à ma modélisation, car elle ne me satisfait pas pleinement (c'est ma 1ère modélisation et je crois qu'il faut que je m'y repenche).

    Je vais me renseigner sur les deux notions dont vous me parlez (trigger et héritage) et peut-être reprendre ma modélisation.
    Ne vous sauvez pas, je reviens quand j'aurai terminé mes recherches et mes réflexions

  5. #5
    Membre Expert
    Avatar de alassanediakite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Mali

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 1 599
    Billets dans le blog
    8
    Par défaut
    Salut
    Je propose cette fonction...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    create or replace function fncheckrole(id int)returns boolean
    as
    $$
    begin
    return exists (select utilisateurs_roles.rid FROM 
      utilisateurs inner join   utilisateurs_roles on utilisateurs.uid = utilisateurs_roles.uid
      where utilisateurs_roles.rid=1 and utilisateurs.uid=$1 );
    end;$$ language 'plpgsql'
    et la contrainte...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ALTER TABLE classes
      ADD CONSTRAINT classes_profprinc_id_check CHECK (fncheckrole(profprinc_id) = true);
    Je vois que cette solution n'est pas très viable si le contenu de la table "role" est fréquemment changé.
    Si maitre SQLpro pouvait détailler un peu son propos nous en tirerons peut être plus de bénéfice.
    @+

  6. #6
    Membre habitué
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2014
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2014
    Messages : 10
    Par défaut
    Re-bonjour,

    bon, j'ai un peu potassé sur le sujet et notamment sur les héritages dont tu parles SQLPro (très bonne doc au passage).
    Du coup, je partirais plutôt vers une modélisation du type :

    Table générale des utilisateurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    CREATE TABLE IF NOT EXISTS Utilisateurs (
    	uid SERIAL,
    	username VARCHAR(45) NOT NULL,
    	nom VARCHER(45) NOT NULL,
    	prenom VARCHER(45) NOT NULL,
    	...
    	PRIMARY KEY (uid),
    	UNIQUE (username)
    );
    Puis une table par "rôle" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    CREATE TABLE IF NOT EXISTS Profs (
    	uid SERIAL,
    	PRIMARY KEY (uid),
    	FOREIGN KEY (uid)
    		REFERENCES Utilisateurs (uid)
    );
     
    CREATE TABLE IF NOT EXISTS Eleves (
    	uid SERIAL,
    	classe INT,
    	...
    	PRIMARY KEY (uid),
    	FOREIGN KEY (uid)
    		REFERENCES Utilisateurs (uid)
    );
     
    idem Parents
    Il faut donc que je mette en place les différents triggers pour vérifier l'existence de la clé Utilisateurs(uid) lors de l'ajout/modification d'un prof ou élève ou parent.
    Ainsi que le trigger permettant de ne pas supprimer un Utilisateurs(uid) si l'uid en question est utilisé dans une table fille.

    Du coup, ma table Classe peut pointer par une clé étrangère sur la table Profs, ce qui m'assure que la colonne ProfPrinc_id contient bien un uid prof :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    CREATE TABLE IF NOT EXISTS Classes (
    	id SERIAL,
    	nom VARCHAR(45),
    	profPrinc_id INT, 
    	PRIMARY KEY (id),
    	UNIQUE (nom),
    	FOREIGN KEY (profPrinc_id)
    		REFERENCES Profs (uid)
    		ON DELETE SET NULL
    );
    Deux questions :
    - @SQLPro : c'est moins foireux comme ça ? ;-)
    - Petite question, lors de l'ajout d'un prof ou d'un élève, est-il possible de créer automatiquement l'insertion dans la table Utilisateurs et dans la table Profs
    ou est-ce que je suis obligé de faire deux requêtes différentes (insert dans Utilisateurs puis insert dans Profs et mettre le tout dans une transaction pour éviter tout soucis) ?

    Merci encore

  7. #7
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Par défaut
    bonjour,

    Regardez du côté des RULE (spécifique à postgresql de mémoire), applicable sur une vue par exemple.


    Sinon au niveau de la modélisation, je ne pense pas que la classe doive être spécifiée au niveau de l'entité élève.

    On est dans une relation de type n/n logiquement, vu qu'un élève pourra faire différentes classes lors de sa scolarité et qu'une classe est composée de plusieurs élèves.

Discussions similaires

  1. Réponses: 7
    Dernier message: 10/09/2008, 15h53
  2. [C# 2.0] Suspendre une contrainte sur une colonne
    Par frechy dans le forum Windows Forms
    Réponses: 3
    Dernier message: 06/04/2006, 07h47
  3. SQLServer 2000: Liste des contraintes sur une colonne ?
    Par swirtel dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 08/11/2005, 16h13
  4. retrouver les contraintes sur une colonne
    Par kalari dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 18/10/2005, 17h03
  5. [SYBASE ASE] Rajouter une contrainte null sur une colonne
    Par Little_Goldo dans le forum Sybase
    Réponses: 1
    Dernier message: 09/02/2005, 10h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo