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

Merise Discussion :

Projet transporteurs Europe - conception BDD


Sujet :

Merise

  1. #61
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut Le tango des clés
    Bonsoir,



    Citation Envoyé par nike7414
    J'ai l'habitude d'utiliser MySQL depuis toujours et je ne saurais peut-être pas comment utiliser un autre SGBD pour le développer de mon site... C'est mon problème.
    D’accord, puisque vous êtes habitué à MySQL, on va évidemment continuer avec.



    Citation Envoyé par nike7414
    Quand vous dites qu'avec d'autres SGBD il n'y a pas de problème vous pensez au quel?
    Je pense par exemple aux clés primaires, quand celles-ci celles comportent plus d’un attribut. Avec MySQL (contrairement à PostgreSQL), la mise en oeuvre de l’auto-incrémentation n’est possible que pour les clés, ce qui a pour conséquence que celles-ci doivent être mono-attribut.


    Prenons le cas de la table PRICE.

    (1) Script avec PostgreSQL : la clé primaire est la paire {category_id, price_id} et l’attribut price_id est auto-incrémenté, ce qui nous évite d’avoir à le faire manuellement :

    
    CREATE TABLE price (
      category_id int NOT NULL,
      price_id serial NOT NULL,   -- (serial  pour  AUTO_INCREMENT)
      price_km DECIMAL(4,2) NOT NULL,
      price_minimum smallint NOT NULL,
      price_disposal smallint NOT NULL
      , CONSTRAINT price_pk PRIMARY KEY (category_id, price_id)
      , CONSTRAINT price_category_fk
           FOREIGN KEY (category_id) REFERENCES category (category_id)
    ) ;
    
    

    (2) Script équivalent avec MySQL :

    
    CREATE TABLE price (
      category_id INT NOT NULL,
      price_id INT NOT NULL AUTO_INCREMENT,
      price_km DECIMAL(4,2) NOT NULL,
      price_minimum TINYINT(4) NOT NULL,
      price_disposal TINYINT(4) NOT NULL
      , CONSTRAINT price_pk PRIMARY KEY (category_id, price_id)
      , CONSTRAINT price_category_fk
           FOREIGN KEY (category_id) REFERENCES category (category_id)
    ) ;
    
    
    => boum !

    Error Code: 1075. Incorrect table definition; there can be only one auto column and it must be defined as a key.

    Ce qui veut dire que price_id doit être clé. En conséquence, je suis parti dans un premier temps avec la configuration suivante, dans laquelle la paire {category_id, price_id} devient clé alternative et {price_id} clé primaire :

    
    CREATE TABLE price (
      category_id INT NOT NULL,
      price_id INT NOT NULL  AUTO_INCREMENT,
      price_km DECIMAL(4,2) NOT NULL,
      price_minimum TINYINT(4) NOT NULL,
      price_disposal TINYINT(4) NOT NULL
      , CONSTRAINT price_pk PRIMARY KEY (price_id)
      , CONSTRAINT price_ak unique (category_id, price_id)
      , CONSTRAINT price_category_fk
         FOREIGN KEY (category_id) REFERENCES category (category_id)
    ) ;
    
    
    Tout se passe bien, sauf que lorsque je code ceci :

    select 3.14 from price where category_id = 1 and price_id = 2 ;

    Alors un explain montre que MySQL se contrefiche de l’index hébergeant la clé alternative, bien qu’il en connaisse l’existence :

    
    table    type     possible_keys        key        key_len    rows    Extra
    price    const    PRIMARY, price_ak    PRIMARY          4       1         
    
    
    Il y aura certainement une légère perte de temps, dans la mesure où, à cause de category_id, MySQL devra accéder en plus aux données de la table.


    Mais tout rentre dans l’ordre si je conserve la paire {category_id, price_id} comme clé primaire et déclare {price_id} en tant que clé alternative :

    
    CREATE TABLE price (
      category_id INT NOT NULL,
      price_id INT NOT NULL  AUTO_INCREMENT,
      price_km DECIMAL(4,2) NOT NULL,
      price_minimum TINYINT(4) NOT NULL,
      price_disposal TINYINT(4) NOT NULL
      , CONSTRAINT price_pk PRIMARY KEY (category_id, price_id)
      , CONSTRAINT price_ak UNIQUE (price_id)
     , CONSTRAINT price_category_fk
           FOREIGN KEY (category_id) REFERENCES category (category_id)
    ) ;
     
    

    Le résultat de l’explain devient celui attendu :

    
    table    type     possible_keys        key        key_len     rows    Extra
    price    const    PRIMARY, price_ak    PRIMARY          8        1    Using index
    
    
    Toutefois, la clé alternative {price_id} est une surcharge inutile (les mises à jour n’aiment pas trop), et dont on se dispense dans le cas de PostgreSQL. Néanmoins, faisons contre mauvaise fortune bon cœur, je suppose que la table des prix sera moins chahutée que celle des réservations...


    Vous aurez noté l’ordre des attributs dans la clé primaire : {category_id, price_id}, alors que vous proposez {price_id, category_id}. J’ai le réflexe DB2 quant à l’effet « cluster », il faudra un jour que vous fabriquiez un prototype de performances pour juger de l’effet obtenu avec MySQL (dont, je le rappelle, je ne suis pas spécialiste...)

    En attendant, je vous propose de poursuivre avec {category_id, price_id}.



    Citation Envoyé par nike7414
    Aucun regret ! Supprimons region_code et dept_code.
    Ces attributs sont toujours présents dans votre dernier diagramme et dans votre dernier script SQL...



    Citation Envoyé par nike7414
    C'est une bonne idée de mettre les longitude et latitude dans la REGION_DEPARTEMENT.
    Dans votre dernier diagramme, ainsi que dans le script SQL, ces attributs sont toujours présents dans les tables city et departement (et absents dans la table REGION_DEPARTEMENT)...


    table category : avez-vous vraiment besoin du type MEDIUMTEXT pour l’attribut category_description ? Quelle taille maximale envisagez-vous ?


    Table type_place, colonne type_place_name : J’avais écrit : « je vire la clause « GENERATED ALWAYS AS () VIRTUAL », à moins qu’elle ne vous soit utile. Qu’en est-il ? »
    Ma question reste d’actualité...



    Citation Envoyé par nike7414
    Voici ce que ca donne ci-dessous avec DRIVER_CATEGORY en plus. Est-ce bien correct?
    Votre diagramme est correct, nonobstant les quelques remarques qui précèdent.


    Je poursuis mon exploration...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  2. #62
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut Catégories, tarifs, langues
    Bonsoir,


    Table PRICE :

    Permuter l’ordre des colonnes de la clé primaire, qui doit être (category_id, price_id).

    A propos du type TINYINT : que vous codiez TINYINT(4) ou TINYINT, c’est du pareil au même, vous ne pourrez pas avoir de valeur > 127. Vous pouvez pousser jusqu’à 255 à condition de coder TINYINT UNSIGNED.

    Table DRIVER_PRICE_FIXED :

    Attribut price_fixed : même remarque à propos de TINYINT.


    Table DISPOSAL_BOOKING :

    Attributs price TINYINT(5), flight_number : TINYINT(8) (!) même remarque...

    Table TRANSFER_BOOKING :

    Attribut flight_number : TINYINT(8) (!) même remarque (en notant au passage que VARCHAR pour price ça n’est pas conseillé...)

    Table PRICE_PLACE :

    L’index fk_price_place_price1_idx est redondant : le supprimer.

    Clé primaire et clés étrangères : ordre des attributs à modifier :

    
    -- -----------------------------------------------------
    -- Table price_place
    -- -----------------------------------------------------
    CREATE TABLE price_place (
      price_id INT NOT NULL,
      category_id INT NOT NULL,
      place_id INT NOT NULL,
      CONSTRAINT price_place_pk PRIMARY KEY (place_id, category_id, price_id),
      CONSTRAINT price_place_price_fk FOREIGN KEY (category_id, price_id)
        REFERENCES price (category_id, price_id),
      CONSTRAINT price_place_place_fk FOREIGN KEY (place_id)
        REFERENCES place (place_id)
      , INDEX price_place_place_fk_idx (place_id ASC)
    ) ;
    
    
    Table DRIVER : index redondant, à supprimer : driver_id_UNIQUE.

    Table DRIVER_CATEGORY :

    Index redondant, à supprimer : fk_driver_has_category_driver1_idx.

    Table DRIVER_PRICE : index redondant, à supprimer : fk_driver_price_price1_idx.

    Table DRIVER_VEHICLE_CATEGORY : index redondant, à supprimer : driver_vehicle_category_id_UNIQUE.

    Table DRIVER_PRICE_FIXED : index redondant, à supprimer : fk_driver_price_fixed_driver_category1_idx

    Table CATEGORY_CHARACTERISTICS : utilisons l’identification relative, comme pour PRICE :

    
    CREATE TABLE category_characteristics (
      category_characteristics_id INT NOT NULL AUTO_INCREMENT,
       VARCHAR(45) NOT NULL,
      category_characteristics_icone VARCHAR(100) NOT NULL,
      category_id INT NOT NULL,
      CONSTRAINT category_characteristics_pk PRIMARY KEY (category_id, category_characteristics_id),
      CONSTRAINT category_characteristics_ak UNIQUE (category_characteristics_id),
      CONSTRAINT category_characteristics_category_fk
        FOREIGN KEY (category_id) REFERENCES category (category_id)
        ON DELETE CASCADE
    ) ;
    
    
    L’option CASCADE permet de dire à MySQL qu’il peut supprimer sans état d’âme les caractéristiques d’une catégorie si l’on supprime celle-ci.


    En ce qui concerne les langues, on supprime les index inutiles et on utilise l’identification relative pour les traductions :

    
    -- -----------------------------------------------------
    -- Table language
    -- -----------------------------------------------------
    CREATE TABLE language (
      language_id INT NOT NULL AUTO_INCREMENT,
      language_name_vo VARCHAR(25) NOT NULL,
      PRIMARY KEY (language_id)
    ) ;
    
    -- -----------------------------------------------------
    -- Table level
    -- -----------------------------------------------------
    CREATE TABLE level (
      level_id INT NOT NULL AUTO_INCREMENT,
      level_value TINYINT NOT NULL,
      PRIMARY KEY (level_id)
    ) ;
    
    -- -----------------------------------------------------
    -- Table traduction
    -- -----------------------------------------------------
    CREATE TABLE traduction (
      traduction_id INT NOT NULL AUTO_INCREMENT,
      language_id INT NOT NULL,
      language_code CHAR(3) NOT NULL,
      language_name VARCHAR(25) NOT NULL,
      CONSTRAINT traduction_pk PRIMARY KEY (language_id, traduction_id),
      CONSTRAINT traduction_ak UNIQUE (traduction_id),
      CONSTRAINT traduction_language_fk
        FOREIGN KEY (language_id) REFERENCES language (language_id)
        ON DELETE CASCADE
    ) ;
    
    -- -----------------------------------------------------
    -- Table driver_language
    -- -----------------------------------------------------
    CREATE TABLE driver_language (
      level_id INT NOT NULL,
      driver_id INT NOT NULL,
      language_id INT NOT NULL,
      CONSTRAINT driver_language_pk PRIMARY KEY (driver_id, language_id),
      CONSTRAINT driver_language_driver_fk
        FOREIGN KEY (driver_id) REFERENCES driver (driver_id)
        ON DELETE CASCADE,
      CONSTRAINT driver_language_level_fk
        FOREIGN KEY (level_id) REFERENCES level (level_id),
      CONSTRAINT driver_language_language_fk
        FOREIGN KEY (language_id) REFERENCES language (language_id)
     , INDEX driver_language_level_idx (level_id ASC)
     , INDEX driver_language_language_idx (language_id ASC) 
    ) ;
     
    

    Voilà pour ce soir, demain je pense pouvoir passer aux clients...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  3. #63
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 55
    Points : 67
    Points
    67
    Par défaut
    Citation Envoyé par fsmrel Voir le message

    Mais tout rentre dans l’ordre si je conserve la paire {category_id, price_id} comme clé primaire et déclare {price_id} en tant que clé alternative :

    
    CREATE TABLE price (
      category_id INT NOT NULL,
      price_id INT NOT NULL  AUTO_INCREMENT,
      price_km DECIMAL(4,2) NOT NULL,
      price_minimum TINYINT(4) NOT NULL,
      price_disposal TINYINT(4) NOT NULL
      , CONSTRAINT price_pk PRIMARY KEY (category_id, price_id)
      , CONSTRAINT price_ak UNIQUE (price_id)
     , CONSTRAINT price_category_fk
           FOREIGN KEY (category_id) REFERENCES category (category_id)
    ) ;
     
    
    OK, je comprends, mais pouvez-vous m'expliquer comment je déclare {price_id} en tant que clé alternative dans MySQL Workbench? Je ne vois pas d'options...

    Citation Envoyé par fsmrel Voir le message
    Vous aurez noté l’ordre des attributs dans la clé primaire : {category_id, price_id}, alors que vous proposez {price_id, category_id}.
    J'ai changé l'ordre.



    Citation Envoyé par fsmrel Voir le message
    Ces attributs sont toujours présents dans votre dernier diagramme et dans votre dernier script SQL...

    Dans votre dernier diagramme, ainsi que dans le script SQL, ces attributs sont toujours présents dans les tables city et departement (et absents dans la table REGION_DEPARTEMENT)...
    Oui, en effet j'avais oublié de le changer dans mon workbench!

    Citation Envoyé par fsmrel Voir le message
    table category : avez-vous vraiment besoin du type MEDIUMTEXT pour l’attribut category_description ? Quelle taille maximale envisagez-vous ?
    Je me suis dit qu'il faudrait quand même que les chauffeurs puissent mettre une longue description pour présenter leurs services s'ils en ont beaucoup.

    Citation Envoyé par fsmrel Voir le message
    Table type_place, colonne type_place_name : J’avais écrit : « je vire la clause « GENERATED ALWAYS AS () VIRTUAL », à moins qu’elle ne vous soit utile. Qu’en est-il ? »
    Ma question reste d’actualité...
    En effet je l'avais coché par erreur dans mon worbench... Merci!






    Citation Envoyé par fsmrel Voir le message


    Table PRICE :

    Permuter l’ordre des colonnes de la clé primaire, qui doit être (category_id, price_id).

    A propos du type TINYINT : que vous codiez TINYINT(4) ou TINYINT, c’est du pareil au même, vous ne pourrez pas avoir de valeur > 127. Vous pouvez pousser jusqu’à 255 à condition de coder TINYINT UNSIGNED.

    Table DRIVER_PRICE_FIXED :

    Attribut price_fixed : même remarque à propos de TINYINT.


    Table DISPOSAL_BOOKING :

    Attributs price TINYINT(5), flight_number : TINYINT(8) (!) même remarque...

    Table TRANSFER_BOOKING :

    Attribut flight_number : TINYINT(8) (!) même remarque (en notant au passage que VARCHAR pour price ça n’est pas conseillé...)

    Table PRICE_PLACE :

    L’index fk_price_place_price1_idx est redondant : le supprimer.
    J'ai laissé TINYINT tout court pour tous les tinyint.
    J'ai supprimé index fk_price_place_price1_idx.


    Citation Envoyé par fsmrel Voir le message
    Clé primaire et clés étrangères : ordre des attributs à modifier :

    
    -- -----------------------------------------------------
    -- Table price_place
    -- -----------------------------------------------------
    CREATE TABLE price_place (
      price_id INT NOT NULL,
      category_id INT NOT NULL,
      place_id INT NOT NULL,
      CONSTRAINT price_place_pk PRIMARY KEY (place_id, category_id, price_id),
      CONSTRAINT price_place_price_fk FOREIGN KEY (category_id, price_id)
        REFERENCES price (category_id, price_id),
      CONSTRAINT price_place_place_fk FOREIGN KEY (place_id)
        REFERENCES place (place_id)
      , INDEX price_place_place_fk_idx (place_id ASC)
    ) ;
    
    
    Table DRIVER : index redondant, à supprimer : driver_id_UNIQUE.

    Table DRIVER_CATEGORY :

    Index redondant, à supprimer : fk_driver_has_category_driver1_idx.

    Table DRIVER_PRICE : index redondant, à supprimer : fk_driver_price_price1_idx.

    Table DRIVER_VEHICLE_CATEGORY : index redondant, à supprimer : driver_vehicle_category_id_UNIQUE.

    Table DRIVER_PRICE_FIXED : index redondant, à supprimer : fk_driver_price_fixed_driver_category1_idx
    J'ai supprimé les index en trop!


    Citation Envoyé par fsmrel Voir le message
    Table CATEGORY_CHARACTERISTICS : utilisons l’identification relative, comme pour PRICE :

    
    CREATE TABLE category_characteristics (
      category_characteristics_id INT NOT NULL AUTO_INCREMENT,
       VARCHAR(45) NOT NULL,
      category_characteristics_icone VARCHAR(100) NOT NULL,
      category_id INT NOT NULL,
      CONSTRAINT category_characteristics_pk PRIMARY KEY (category_id, category_characteristics_id),
      CONSTRAINT category_characteristics_ak UNIQUE (category_characteristics_id),
      CONSTRAINT category_characteristics_category_fk
        FOREIGN KEY (category_id) REFERENCES category (category_id)
        ON DELETE CASCADE
    ) ;
    
    
    L’option CASCADE permet de dire à MySQL qu’il peut supprimer sans état d’âme les caractéristiques d’une catégorie si l’on supprime celle-ci.
    A ce que je vois vous avez rajouté "category_id" comme clé primaire.
    Même question pour la clé alternative, comment je la rajoute sur mon MySQL Workbench? L'ordre la aussi est-il important?

    Nom : MySQL Workbench.jpg
Affichages : 362
Taille : 74,2 Ko
    Nom : MySQL Workbench2.jpg
Affichages : 426
Taille : 68,1 Ko


    Citation Envoyé par fsmrel Voir le message
    En ce qui concerne les langues, on supprime les index inutiles et on utilise l’identification relative pour les traductions :

    [pre]

    -- -----------------------------------------------------
    -- Table language
    -- -----------------------------------------------------
    CREATE TABLE language (
    language_id INT NOT NULL AUTO_INCREMENT,
    language_name_vo VARCHAR(25) NOT NULL,
    PRIMARY KEY (language_id)
    ) ;

    -- -----------------------------------------------------
    -- Table level
    -- -----------------------------------------------------
    CREATE TABLE level (
    level_id INT NOT NULL AUTO_INCREMENT,
    level_value TINYINT NOT NULL,
    PRIMARY KEY (level_id)
    ) ;

    -- -----------------------------------------------------
    -- Table traduction
    -- -----------------------------------------------------
    CREATE TABLE traduction (
    traduction_id INT NOT NULL AUTO_INCREMENT,
    language_id INT NOT NULL,
    language_code CHAR(3) NOT NULL,
    language_name VARCHAR(25) NOT NULL,
    CONSTRAINT traduction_pk PRIMARY KEY (language_id, traduction_id),
    CONSTRAINT traduction_ak UNIQUE (traduction_id),
    CONSTRAINT traduction_language_fk
    FOREIGN KEY (language_id) REFERENCES language (language_id)
    ON DELETE CASCADE
    ) ;

    J'ai supprimé les index inutiles et j'ai rajouté le ON DELETE CASCADE là où il le fallait.
    Par contre pour l’identification relative pour les traductions je reste toujours un peu bloqué... L'ordre la aussi est-il important?

    Merci pour votre aide!


    Le nouveau script: choosedriver2.sql
    J'ai vu qu'on peut rajouter les TRIGGERS directement dans MySQL Workbench, donc c'est ce que j'ai fait, mais en générant le script ces triggers se rajoutent tout à la fin.

  4. #64
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir Nike,


    Avant que je ne crapahute dans la suite...



    Citation Envoyé par nike7414
    pouvez-vous m'expliquer comment je déclare {price_id} en tant que clé alternative dans MySQL Workbench? Je ne vois pas d'options...
    Il suffit de cocher la case « UQ » :





    On jette un coup d’œil aux index et on constate que MySQL Workbench a bien créé un index de type UNIQUE :





    Je préfère renommer l’index price_id_UNIQUE en PRICE_AK, ça ne mange pas de pain :





    Prudent, je vérifie l’ordre des attributs dans la clé primaire, et c’est pour constater que cet enfoiré a mis price_id en-tête (et en plus, lors du choix de price_id pour l’auto-incrémentation, cette andouille d’InnoDB a exigé que price_id soit le 1er dans l’en tête de la table, alors qu’un en-tête est un ensemble !Même pas grave, mais ces gens feraient bien de lire les ouvrages de Chris Date...) :





    Je remets dans l’ordre correct :





    =>





    Tant qu’à faire, je vire l’index inutile PRICE_CATEGORY_FK_idx :





    =>




    Voici ce que m’a pondu MySQL Workbench, brut de décoffrage :

    
    -- -----------------------------------------------------
    -- Table `PRICE`
    -- -----------------------------------------------------
    CREATE TABLE IF NOT EXISTS `PRICE` (
      `price_id` INT NOT NULL AUTO_INCREMENT,
      `category_id` INT NOT NULL,
      `price_km` DECIMAL(5,2) NOT NULL,
      `price_minimum` DECIMAL(5) NOT NULL,
      `price_disposal` DECIMAL(5) NOT NULL,
      PRIMARY KEY (`category_id`, `price_id`),
      UNIQUE INDEX `PRICE_AK` (`price_id` ASC),
      CONSTRAINT `PRICE_CATEGORY_FK`
        FOREIGN KEY (`category_id`)
        REFERENCES `CATEGORY` (`category_id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB;
    
    

    Et c’est manuellement que je remplace

    UNIQUE INDEX `PRICE_AK` (`price_id` ASC)

    Par :

    CONSTRAINT PRICE_AK UNIQUE (price_id)

    Pour InnoDB, c’est bonnet blanc et blanc bonnet, mais je suis chatouilleux, une table est un ensemble au sens de la théorie des ensembles, et le mot « index » qui relève de la quincaillerie n’a rien à y faire... Mais ça ne changera rien quant au comportement de la base de données, disons que c’est seulement une affaire de présentation.



    Citation Envoyé par nike7414
    Je me suis dit qu'il faudrait quand même que les chauffeurs puissent mettre une longue description pour présenter leurs services s'ils en ont beaucoup.
    Euh... Ouch... La table CATEGORY ne dépend pas des chauffeurs ! S’ils veulent présenter leurs services, la table DRIVER_CATEGORY peut faire office. Par ailleurs, s’ils racontent leur vie, la table risque l’obésité (et les performances d’en souffrir), auquel cas il serait préférable de mettre en oeuvre une table ad-hoc, attachée à DRIVER_CATEGORY, et hébergeant l’attribut category_description :

    [DRIVER_CATEGORY]-||—0|-[DESCRIPTION_SERVICE]



    Citation Envoyé par nike7414
    A ce que je vois vous avez rajouté "category_id" comme clé primaire.
    Même question pour la clé alternative, comment je la rajoute sur mon MySQL Workbench? L'ordre la aussi est-il important?
    category_id participe effectivement à la clé primaire. Pour faire ça on procède comme pour PRICE. L’ordre est important, car lors des jointures, pour conserver la performance, tout le monde doit respecter le même ordre, et la notion de clustering est très impliquée dans cette affaire, je vous renvoie à :

    Citation Envoyé par fsmrel
    l’effet « cluster », il faudra un jour que vous fabriquiez un prototype de performances pour juger de l’effet obtenu avec MySQL (dont, je le rappelle, je ne suis pas spécialiste...)
    Quand je parle de prototype de performances, il s’agit d’anticiper, conjecturer du top 10 ou 20 des requêtes les plus utilisées et les secouer, les rendre les plus efficaces qu’il soit possible, quitte à revoir le clustering, avant de mettre en production. Mieux vaut prévenir que guérir...



    Citation Envoyé par nike7414
    J'ai vu qu'on peut rajouter les TRIGGERS directement dans MySQL Workbench, donc c'est ce que j'ai fait, mais en générant le script ces triggers se rajoutent tout à la fin.
    Pas de problème ! Le tout est qu’ils existent avant qu’on ne commence les inserts, updates et delete pour les tables faisant l’objet de triggers...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  5. #65
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 55
    Points : 67
    Points
    67
    Par défaut
    Citation Envoyé par fsmrel Voir le message

    Il suffit de cocher la case « UQ » :

    On jette un coup d’œil aux index et on constate que MySQL Workbench a bien créé un index de type UNIQUE :


    Je préfère renommer l’index price_id_UNIQUE en PRICE_AK, ça ne mange pas de pain


    Prudent, je vérifie l’ordre des attributs dans la clé primaire, et c’est pour constater que cet enfoiré a mis price_id en-tête (et en plus, lors du choix de price_id pour l’auto-incrémentation, cette andouille d’InnoDB a exigé que price_id soit le 1er dans l’en tête de la table, alors qu’un en-tête est un ensemble !Même pas grave, mais ces gens feraient bien de lire les ouvrages de Chris Date...)

    Tant qu’à faire, je vire l’index inutile PRICE_CATEGORY_FK_idx
    OK j'ai compris!
    J'ai fait la même chose pour la table traduction et la table category_characteristics.
    En supprimant aussi les index inutiles de chaque, sans comprendre vraiment pourquoi ces index sont inutiles?

    Nom : MySQL Workbench3.jpg
Affichages : 366
Taille : 54,1 Ko
    Nom : MySQL Workbench4.jpg
Affichages : 310
Taille : 50,3 Ko



    Citation Envoyé par fsmrel Voir le message
    Euh... Ouch... La table CATEGORY ne dépend pas des chauffeurs ! S’ils veulent présenter leurs services, la table DRIVER_CATEGORY peut faire office. Par ailleurs, s’ils racontent leur vie, la table risque l’obésité (et les performances d’en souffrir), auquel cas il serait préférable de mettre en oeuvre une table ad-hoc, attachée à DRIVER_CATEGORY, et hébergeant l’attribut category_description
    Ah oui, pardon ! J'ai pas fait attention. En effet category_description sert uniquement à la description de la catégorie, donc ce sera à moi même de la mettre. J'ai donc remplacé MEDIUMTEXT par TINYTEXT. En fait ca sera deux lignes de texte, pas plus.

    Pour la description du chauffeur ca se fait dans la table DRIVER où j'ai mis "LONGTEXT".


    Citation Envoyé par fsmrel Voir le message
    Quand je parle de prototype de performances, il s’agit d’anticiper, conjecturer du top 10 ou 20 des requêtes les plus utilisées et les secouer, les rendre les plus efficaces qu’il soit possible, quitte à revoir le clustering, avant de mettre en production. Mieux vaut prévenir que guérir...
    En effet pour les top 10 des requêtes les plus utilisées il vaut mieux qu'elles soient bien performentes.

    Le script après les derniers changements: choosedriver2.sql

  6. #66
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir Nike,


    Citation Envoyé par nike7414
    En supprimant aussi les index inutiles de chaque, sans comprendre vraiment pourquoi ces index sont inutiles ?
    Prenons par exemple les cas de votre définition de la table CLIENT. Vous avez doté celle-ci d’un index « primaire », car les clanculs feignants exigent que nous définissions un tel index (concept physique) pour toute clé primaire (concept relationnel) :

    
    CREATE TABLE IF NOT EXISTS client
    (
            client_id INT NOT NULL AUTO_INCREMENT,
            ...
          PRIMARY KEY (client_id),
          UNIQUE INDEX client_id_UNIQUE (client_id ASC) 
    ) ;
    
    
    Mais on a là deux index strictement identiques : en supprimer un ne pénalise en rien les SELECT (et MySQL ne se servira jamais en l’occurrence du 2e index, le primaire suffisant largement à son bonheur), en revanche on va améliorer la performance des mises à jour car, par exemple l’ajout ou la suppression d’un client ne va secouer qu’un seul index au lieu de deux, et croyez-moi, mettre à jour un index ça coûte cher, à vos moments perdus vous pourrez-faire le test de ce que représente la mise en œuvre du 2e index.

    Prenons l’exemple de votre description précédente de la table PRICE :

    
    CREATE TABLE IF NOT EXISTS price (
      price_id INT NOT NULL AUTO_INCREMENT,
      category_id INT NOT NULL,
      price_km DECIMAL(4,2) NOT NULL,
      price_minimum TINYINT(4) NOT NULL,
      price_disposal TINYINT(4) NOT NULL,
      PRIMARY KEY (category_id, price_id),
      UNIQUE INDEX price_id_UNIQUE (price_id ASC),
      INDEX fk_price_category1_idx (category_id ASC),
      CONSTRAINT fk_price_category1
        FOREIGN KEY (category_id)
        REFERENCES category (category_id)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    
    
    Cette table est dotée de 3 index. Il y a l’index « primaire », de clé {category_id, price_id} : d’accord. Il y a l’index price_id_UNIQUE de clé {price_id} : d’accord. Il y a l’index fk_price_category1_idx, de clé {category_id} et plaqué sur la clé étrangère fk_price_category1 : quelles sont les conséquences de la suppression de cet index ? Comme ci-dessus, on améliore la performance des mises à jour, quant aux SELECT portant sur la clé étrangère, il n’y a pas de bobo, car MySQL se rabattra sur l’index primaire dont le 1er attribut de la clé est aussi category_id : pas de perte de performance donc.



    Citation Envoyé par nike7414
    Pour la description du chauffeur ca se fait dans la table DRIVER où j'ai mis "LONGTEXT".
    Je reprends ce que j’ai écrit dans mon message précédent, en adaptant à la table DRIVER :

    Si les chauffeurs racontent leur vie, la table DRIVER risque l’obésité (et les performances d’en souffrir énormément, vu le rôle plutôt central que joue cette table), auquel cas il serait préférable de mettre en oeuvre une table ad-hoc (appelons-la par exemple DRIVER_DESCRIPTION), attachée à DRIVER, et hébergeant l’attribut description, qui disparaît alors de la table DRIVER :


    [DRIVER]-||—0|-[DRIVER_DESCRIPTION]


    script SQL :

    
    CREATE TABLE driver_description (
      driver_id INT NOT NULL,
      description INT NOT NULL,
      PRIMARY KEY (driver_id),
      CONSTRAINT DRIVER_DESCRIPTION_DRIVER_FK
        FOREIGN KEY (driver_id)
        REFERENCES DRIVER (driver_id)
        ON DELETE CASCADE
        ON UPDATE NO ACTION
    ) ;
    
    
    A cette occasion, à propos de la table DRIVER, il faudrait raboter, ajuster au mieux la taille des attributs consommant des ressources. Par exemple, est-il nécessaire que l’attribut pass occupe 255 octets ? En codant VARCHAR(255), c’est un encombrement de 256 octets, même si Raoul n’utilise que 10 caractères pour son mot de passe... Un numéro de téléphone de 30 caractères, c’est quand même beaucoup, etc.

    Ce travail d’ajustement de la taille des attributs vaut bien sûr pour la table CLIENT, et même pour toutes les tables...


    A faire :

    Table category : supprimer l’index (en double) category_id_UNIQUE.

    Table driver_price : faire passer price_id à la fin de la liste des attributs de la clé primaire. En conséquence l’index fk_driver_price_price1_idx refait surface et l’index fk_driver_price_driver_category1_idx disparaît :

    
    Table CREATE TABLE driver_price (
      price_id INT NOT NULL,
      driver_id INT NOT NULL,
      category_id INT NOT NULL,
      PRIMARY KEY (driver_id, category_id, price_id),
      CONSTRAINT driver_price_price_fk
        FOREIGN KEY (price_id)
        REFERENCES price (price_id)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT driver_price_driver_category_fk
        FOREIGN KEY (driver_id, category_id)
        REFERENCES driver_category (driver_id, category_id)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION
     , INDEX fk_driver_price_price1_idx (price_id ASC) 
    ) ;
      
    

    Table price_place : supprimer l’index price_place_place_fk_idx et mettre en œuvre l’index fk_price_place_category_price_fk_idx :


    
    CREATE TABLE price_place (
      price_id INT NOT NULL,
      category_id INT NOT NULL,
      place_id INT NOT NULL,
      CONSTRAINT price_place_pk PRIMARY KEY (place_id, category_id, price_id),
      CONSTRAINT price_place_price_fk FOREIGN KEY (category_id, price_id)
        REFERENCES price (category_id, price_id),
      CONSTRAINT price_place_place_fk FOREIGN KEY (place_id)
        REFERENCES place (place_id)
     , INDEX fk_price_place_category_price_fk_idx (category_id, price_id) 
    ) ;
    
    

    Table region : supprimer l’index fk_region_region_departement1_idx

    Table driver_language supprimer l'index fk_driver_language_driver1_idx

    Table commission_payment : supprimer l’index redondant commission_payment_id_UNIQUE.

    Table disposal_booking : ajuster au mieux la taille des attributs. Permuter les attributs dans la clé primaire qui devient {client_id, id_disposal_booking} ; supprimer l’index fk_disposal_booking_client1_idx.

    Table transfer_booking : ajuster au mieux la taille des attributs. Permuter les attributs dans la clé primaire qui devient {client_id, id_transfer_booking} ; supprimer l’index fk_transfer_booking_client1_idx.

    Table promo : définir un index UNIQUE pour la clé alternative {promo_code} ; supprimer l'index promo_id_UNIQUE.

    Table client_promo : permuter les attributs de la clé primaire ; supprimer l'index fk_client_promo_client1_idx.

    Table client_promo_transfer_booking : clé primaire et clés étrangères à remettre à l’endroit :

    
    CREATE TABLE client_promo_transfer_booking (
      client_id INT NOT NULL,
      promo_id INT NOT NULL,
      id_transfer_booking INT NOT NULL,
      PRIMARY KEY (client_id, promo_id),
      CONSTRAINT client_promo_transfer_booking_client_promo_FK
        FOREIGN KEY (client_id, promo_id)
        REFERENCES client_promo (client_id, promo_id)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT client_promo_transfer_booking_transfer_booking_fk
        FOREIGN KEY (client_id, id_transfer_booking)
        REFERENCES transfer_booking (client_id, id_transfer_booking)
        ON DELETE CASCADE
        ON UPDATE NO ACTION
    ) ;
    
    

    TABLE driver_payment revue :

    
    CREATE TABLE driver_payment 
    (
      id_payment_onboard INT NOT NULL AUTO_INCREMENT,
      driver_id INT NOT NULL,
      card_onboard TINYINT(1) NOT NULL,
      vat_rate TINYINT(2) NOT NULL,
      PRIMARY KEY (driver_id, id_payment_onboard),
      INDEX fk_driver_payment_driver1_idx (driver_id ASC),
      UNIQUE INDEX id_payment_onboard_UNIQUE (id_payment_onboard ASC),
      CONSTRAINT fk_driver_payment_driver1
        FOREIGN KEY (driver_id)
        REFERENCES driver (driver_id)
        ON DELETE CASCADE
        ON UPDATE NO ACTION
    ) ;
    
    

    J’en suis là...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  7. #67
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 55
    Points : 67
    Points
    67
    Par défaut
    Citation Envoyé par fsmrel Voir le message

    Je reprends ce que j’ai écrit dans mon message précédent, en adaptant à la table DRIVER :

    Si les chauffeurs racontent leur vie, la table DRIVER risque l’obésité (et les performances d’en souffrir énormément, vu le rôle plutôt central que joue cette table), auquel cas il serait préférable de mettre en oeuvre une table ad-hoc (appelons-la par exemple DRIVER_DESCRIPTION), attachée à DRIVER, et hébergeant l’attribut description, qui disparaît alors de la table DRIVER :


    [DRIVER]-||—0|-[DRIVER_DESCRIPTION]


    script SQL :

    
    CREATE TABLE driver_description (
      driver_id INT NOT NULL,
      description INT NOT NULL,
      PRIMARY KEY (driver_id),
      CONSTRAINT DRIVER_DESCRIPTION_DRIVER_FK
        FOREIGN KEY (driver_id)
        REFERENCES DRIVER (driver_id)
        ON DELETE CASCADE
        ON UPDATE NO ACTION
    ) ;
    
    
    A cette occasion, à propos de la table DRIVER, il faudrait raboter, ajuster au mieux la taille des attributs consommant des ressources. Par exemple, est-il nécessaire que l’attribut pass occupe 255 octets ? En codant VARCHAR(255), c’est un encombrement de 256 octets, même si Raoul n’utilise que 10 caractères pour son mot de passe... Un numéro de téléphone de 30 caractères, c’est quand même beaucoup, etc.

    Ce travail d’ajustement de la taille des attributs vaut bien sûr pour la table CLIENT, et même pour toutes les tables...
    OK, merci pour les explications.
    Enfaite mon mot de passe se transforme en MD5, donc il peut être assez long. Voila pourquoi j'ai laissé 255 charactères. Vous en pensez quoi?

    Sinon j'ai rajouté la table driver_description

    Citation Envoyé par fsmrel Voir le message
    A faire :

    Table category : supprimer l’index (en double) category_id_UNIQUE.

    Table driver_price : faire passer price_id à la fin de la liste des attributs de la clé primaire. En conséquence l’index fk_driver_price_price1_idx refait surface et l’index fk_driver_price_driver_category1_idx disparaît :

    
    Table CREATE TABLE driver_price (
      price_id INT NOT NULL,
      driver_id INT NOT NULL,
      category_id INT NOT NULL,
      PRIMARY KEY (driver_id, category_id, price_id),
      CONSTRAINT driver_price_price_fk
        FOREIGN KEY (price_id)
        REFERENCES price (price_id)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT driver_price_driver_category_fk
        FOREIGN KEY (driver_id, category_id)
        REFERENCES driver_category (driver_id, category_id)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION
     , INDEX fk_driver_price_price1_idx (price_id ASC) 
    ) ;
      
    

    Table price_place : supprimer l’index price_place_place_fk_idx et mettre en œuvre l’index fk_price_place_category_price_fk_idx :


    
    CREATE TABLE price_place (
      price_id INT NOT NULL,
      category_id INT NOT NULL,
      place_id INT NOT NULL,
      CONSTRAINT price_place_pk PRIMARY KEY (place_id, category_id, price_id),
      CONSTRAINT price_place_price_fk FOREIGN KEY (category_id, price_id)
        REFERENCES price (category_id, price_id),
      CONSTRAINT price_place_place_fk FOREIGN KEY (place_id)
        REFERENCES place (place_id)
     , INDEX fk_price_place_category_price_fk_idx (category_id, price_id) 
    ) ;
    
    

    Table region : supprimer l’index fk_region_region_departement1_idx

    Table driver_language supprimer l'index fk_driver_language_driver1_idx

    Table commission_payment : supprimer l’index redondant commission_payment_id_UNIQUE.

    Table disposal_booking : ajuster au mieux la taille des attributs. Permuter les attributs dans la clé primaire qui devient {client_id, id_disposal_booking} ; supprimer l’index fk_disposal_booking_client1_idx.

    Table transfer_booking : ajuster au mieux la taille des attributs. Permuter les attributs dans la clé primaire qui devient {client_id, id_transfer_booking} ; supprimer l’index fk_transfer_booking_client1_idx.

    Table promo : définir un index UNIQUE pour la clé alternative {promo_code} ; supprimer l'index promo_id_UNIQUE.

    Table client_promo : permuter les attributs de la clé primaire ; supprimer l'index fk_client_promo_client1_idx.
    J'ai fait toutes ces modifs.


    Citation Envoyé par fsmrel Voir le message

    Table client_promo_transfer_booking : clé primaire et clés étrangères à remettre à l’endroit :

    
    CREATE TABLE client_promo_transfer_booking (
      client_id INT NOT NULL,
      promo_id INT NOT NULL,
      id_transfer_booking INT NOT NULL,
      PRIMARY KEY (client_id, promo_id),
      CONSTRAINT client_promo_transfer_booking_client_promo_FK
        FOREIGN KEY (client_id, promo_id)
        REFERENCES client_promo (client_id, promo_id)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT client_promo_transfer_booking_transfer_booking_fk
        FOREIGN KEY (client_id, id_transfer_booking)
        REFERENCES transfer_booking (client_id, id_transfer_booking)
        ON DELETE CASCADE
        ON UPDATE NO ACTION
    ) ;
    
    
    J'ai fait de même pour la table: client_promo_disposal_booking, mais je n'ai pas réussi à supprimer les index:

    CREATE TABLE IF NOT EXISTS `client_promo_transfer_booking` (
      `client_id` INT NOT NULL,
      `promo_id` INT NOT NULL,
      `id_transfer_booking` INT NOT NULL,
      PRIMARY KEY (`client_id`, `promo_id`),
      INDEX `fk_client_promo_has_transfer_booking_transfer_booking1_idx` (`client_id` ASC, `id_transfer_booking` ASC),
      INDEX `fk_client_promo_has_transfer_booking_client_promo1_idx` (`client_id` ASC, `promo_id` ASC),
      CONSTRAINT `fk_client_promo_has_transfer_booking_client_promo1`
        FOREIGN KEY (`promo_id` , `client_id`)
        REFERENCES `client_promo` (`promo_id` , `client_id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_client_promo_has_transfer_booking_transfer_booking1`
        FOREIGN KEY (`id_transfer_booking` , `client_id`)
        REFERENCES `transfer_booking` (`id_transfer_booking` , `id_transfer_booking`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    
    Comme vous voyez sur les screenshots:

    Nom : MySQL Workbench5_2.jpg
Affichages : 357
Taille : 59,7 Ko
    Nom : MySQL Workbench6.jpg
Affichages : 307
Taille : 60,2 Ko

    Les clés étrangères je ne vois pas comment on les remet à l'endroit.

    Citation Envoyé par fsmrel Voir le message
    TABLE driver_payment revue :

    
    CREATE TABLE driver_payment 
    (
      id_payment_onboard INT NOT NULL AUTO_INCREMENT,
      driver_id INT NOT NULL,
      card_onboard TINYINT(1) NOT NULL,
      vat_rate TINYINT(2) NOT NULL,
      PRIMARY KEY (driver_id, id_payment_onboard),
      INDEX fk_driver_payment_driver1_idx (driver_id ASC),
      UNIQUE INDEX id_payment_onboard_UNIQUE (id_payment_onboard ASC),
      CONSTRAINT fk_driver_payment_driver1
        FOREIGN KEY (driver_id)
        REFERENCES driver (driver_id)
        ON DELETE CASCADE
        ON UPDATE NO ACTION
    ) ;
    
    
    Les modifications sont faites!

    Voici le fichier SQL: choosedriver3.sql

  8. #68
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut Un exercice...
    Bonsoir Nike,



    Citation Envoyé par nike7414
    En fait mon mot de passe se transforme en MD5, donc il peut être assez long. Voila pourquoi j'ai laissé 255 caractères. Vous en pensez quoi?
    Je suis incompétent en matière de MD5, mais si c’est l’empreinte que vous stockez, d’après ce que j’ai compris, celle-ci occupe 128 bits, c'est-à-dire 16 octets. Au cas où un jour il faudrait un codage à 256 bits, on passe à 32 octets. En laissant à 255 octets, ça correspondrait à une empreinte plutôt commac...



    Citation Envoyé par nike7414
    Sinon j'ai rajouté la table driver_description
    Vous pouvez remplacer « ON DELETE NO ACTION » par « ON DELETE CASCADE » ; En effet, au cas où on supprime un chauffeur, sa description disparaît en même temps, ça fait du travail en moins pour vous, à savoir commencer par devoir supprimer la description avant le chauffeur (si tant est que vous ayez à supprimer un chauffeur...)



    Table price_place : là où vous avez « FOREIGN KEY (price_id , category_id) », on doit avoir « FOREIGN KEY (category_id, price_id). Même chose pour « REFERENCES price (price_id , category_id) ».

    Table disposal_booking : pickupdate n’est pas du type DATE ? pickuptime n’est pas du type TIME ?




    Citation Envoyé par nike7414
    J'ai fait de même pour la table: client_promo_disposal_booking, mais je n'ai pas réussi à supprimer les index
    J’observe que la table client_promo_transfer_booking a une clé étrangère fk_client_promo_has_transfer_booking_transfer_booking1 qui fait référence à la table transfer_booking d’une façon très folklorique :


    REFERENCES transfer_booking (id_transfer_booking, id_transfer_booking)


    Je subodore que l’outil part en sucette...


    Pour en avoir le cœur net, je remets tout à zéro en ce qui concerne la table client_promo_transfer_booking. Vous n’êtes pas obligé d’en faire autant, je pense que vous pouvez partir du point 9. Quoi qu’il en soit :

    1) La situation actuelle est la suivante :






    2) On revient à la case Départ, en supprimant les liens connectant client_promo_transfer_booking et transfer_booking d’une part et client_promo d’autre part :






    3) On connecte client_promo_transfer_booking sur client_promo en mode « New 1:1 Identifying Relationship » :






    4) On vérifie que la génération du CREATE TABLE est conforme (clé primaire et clé étrangère par rapport à client_promo). Quand c’est OK, on connecte client_promo_transfer_booking sur transfer_booking en mode « New 1:n Non-Identifying Relationship » :





    Dans la table client_promo_transfer_booking, l’attribut client_id1 fait double emploi avec client_id, mais il ne nous gêne pas et on lui réglera son compte plus tard.


    5) On s’intéresse à la clé étrangère CLIENT_PROMO_TRANSFER_BOOKING_TRANSFER_BOOKING_FK :






    On décoche client_id1, puis on coche client_id :







    7) Coté index, l’ordre des attributs n’est pas le bon, comme par hasard :






    8) On remet donc de l’ordre :





    Au résultat : ça déconne effectivement, la clé étrangère CLIENT_PROMO_TRANSFER_BOOKING_TRANSFER_BOOKING_FK c’est vraiment du grand n’importe quoi, on est vraisemblablement au delà de ce que sait faire l’outil...

    
    CREATE TABLE IF NOT EXISTS `CLIENT_PROMO_TRANSFER_BOOKING` (
      `client_id` INT NOT NULL,
      `promo_id` INT NOT NULL,
      `id_transfer_booking` INT NOT NULL,
      `client_id1` INT NOT NULL,
      PRIMARY KEY (`client_id`, `promo_id`),
      INDEX `CLIENT_PROMO_TRANSFER_BOOKING_TRANSFER_BOOKING_FK_idx` (`client_id` ASC, `id_transfer_booking` ASC),
      CONSTRAINT `CLIENT_PROMO_TRANSFER_BOOKING_CLIENT_PROMO_FK`
        FOREIGN KEY (`client_id` , `promo_id`)
        REFERENCES `CLIENT_PROMO` (`client_id` , `promo_id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `CLIENT_PROMO_TRANSFER_BOOKING_TRANSFER_BOOKING_FK`
        FOREIGN KEY (`id_transfer_booking` , `client_id`)
        REFERENCES `TRANSFER_BOOKING` (`id_transfer_booking` , `id_transfer_booking`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB;
    
    

    9) Même pas grave, on supprime la connexion entre client_promo_transfer_booking et transfer_booking, ce qui nous ramène à une situation dans laquelle l’attribut id_transfer_booking est affublé d’un losange bleu (attribut banal) :






    On évite cette fois-ci de connecter client_promo_transfer_booking sur transfer_booking en mode « New 1:n Non-Identifying Relationship », sinon on n’en sortira pas. On va agir manuellement.

    10) Suite à la déconnexion, on a bien perdu la clé étrangère CLIENT_PROMO_TRANSFER_BOOKING_TRANSFER_BOOKING_FK :






    11) On la recrée à la main, en fournissant d’abord son nom :





    12) Puis, suite à un double clic dans la cellule qui va bien (Referenced Table), on choisit la table référencée, à savoir transfer_booking :






    13) La table référencée est bien transfer_booking :






    14) Avec doigté, on sélectionne les attributs, référençants et référencés, dans le bon ordre tant qu’à faire... Allons-y d’abord avec client_id :





    15) On en fait autant pour l’attribut id_transfer_booking :







    16) Ça a l’air pas mal :






    17) Tout seul, comme un grand, l’outil a créé l’index qui va bien :






    On vérifie :

    
    CREATE TABLE IF NOT EXISTS `CLIENT_PROMO_TRANSFER_BOOKING` (
      `client_id` INT NOT NULL,
      `promo_id` INT NOT NULL,
      `id_transfer_booking` INT NOT NULL,
      `client_id1` INT NOT NULL,
      PRIMARY KEY (`client_id`, `promo_id`),
      INDEX `CLIENT_PROMO_TRANSFER_BOOKING_TRANSFER_BOOKING_FK_idx` (`client_id` ASC, `id_transfer_booking` ASC),
      CONSTRAINT `CLIENT_PROMO_TRANSFER_BOOKING_CLIENT_PROMO_FK`
        FOREIGN KEY (`client_id` , `promo_id`)
        REFERENCES `CLIENT_PROMO` (`client_id` , `promo_id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `CLIENT_PROMO_TRANSFER_BOOKING_TRANSFER_BOOKING_FK`
        FOREIGN KEY (`client_id` , `id_transfer_booking`)
        REFERENCES `TRANSFER_BOOKING` (`client_id` , `id_transfer_booking`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB;
    
    

    L’attribut client_id est bien partout à sa place, ouf ! On vire son clone client_id1 qui ne sert plus à rien.


    J’ai fait la totale, mais pour vous il suffira de prendre à partir du point 9.

    J’en resterai là pour ce soir...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  9. #69
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 55
    Points : 67
    Points
    67
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    Je suis incompétent en matière de MD5, mais si c’est l’empreinte que vous stockez, d’après ce que j’ai compris, celle-ci occupe 128 bits, c'est-à-dire 16 octets. Au cas où un jour il faudrait un codage à 256 bits, on passe à 32 octets. En laissant à 255 octets, ça correspondrait à une empreinte plutôt commac...
    OK, je comprends. J'ai donc mis CHAR(32) comme suggéré sur ce lien.


    Citation Envoyé par fsmrel Voir le message
    Vous pouvez remplacer « ON DELETE NO ACTION » par « ON DELETE CASCADE » ; En effet, au cas où on supprime un chauffeur, sa description disparaît en même temps, ça fait du travail en moins pour vous, à savoir commencer par devoir supprimer la description avant le chauffeur (si tant est que vous ayez à supprimer un chauffeur...)
    Ah D'accord! Justement je me posais la question pour "CASCADE"!


    Citation Envoyé par fsmrel Voir le message
    Table price_place : là où vous avez « FOREIGN KEY (price_id , category_id) », on doit avoir « FOREIGN KEY (category_id, price_id). Même chose pour « REFERENCES price (price_id , category_id) ».
    C'est modifié !

    Citation Envoyé par fsmrel Voir le message
    Table disposal_booking : pickupdate n’est pas du type DATE ? pickuptime n’est pas du type TIME ?
    Oui, désolé. C'est modifié.
    Pour l'adresse j'ai laissé VARCHAR(255), car on ne sait jamais avec les adresses...



    Citation Envoyé par fsmrel Voir le message
    J’observe que la table client_promo_transfer_booking a une clé étrangère fk_client_promo_has_transfer_booking_transfer_booking1 qui fait référence à la table transfer_booking d’une façon très folklorique :

    REFERENCES transfer_booking (id_transfer_booking, id_transfer_booking)

    Je subodore que l’outil part en sucette...

    Pour en avoir le cœur net, je remets tout à zéro en ce qui concerne la table client_promo_transfer_booking. Vous n’êtes pas obligé d’en faire autant, je pense que vous pouvez partir du point 9. Quoi qu’il en soit :
    Merci pour toutes ces explications!

    Le script avec les modifs: choosedriver3.sql

  10. #70
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir Nike,


    A quoi correspond la table user ? C’est une scorie à supprimer ?

    A quoi correspond la table email_sending ?


    Quelques aménagements à apporter :

    Table category_translated : injecter category_id dans la clé primaire ; supprimer l’index fk_category_translated_category1_idx :

    
    CREATE TABLE category_translated (
      category_translated_id INT NOT NULL AUTO_INCREMENT,
      category_id INT NOT NULL,
      category_translated_name VARCHAR(45) NOT NULL,
      category_translated_description MEDIUMTEXT NOT NULL,
      PRIMARY KEY (category_id, category_translated_id),
      UNIQUE INDEX idcategory_translated_id_UNIQUE (category_translated_id ASC),
      CONSTRAINT fk_category_translated_category1
        FOREIGN KEY (category_id)
        REFERENCES category (category_id)
        ON DELETE CASCADE
        ON UPDATE NO ACTION)
    
    

    Table client : virer l’index client_id_UNIQUE. Attribut email : 255 caractères pour une adresse de courriel, ça paraît beaucoup... (Même chose pour la table driver et quelques autres).

    Table client_photo : permuter les attributs dans la clé primaire. Virer l’index fk_client_photo_client1_idx.

    Table driver_photo : permuter les attributs dans la clé primaire. Virer l’index fk_user_photo_driver1_idx.

    Table driver_license_name : virer l’index driver_license_name_id_UNIQUE.

    Table driver_payment : virer l’index fk_driver_payment_driver1_idx.

    Table driver_license : renommer l’attribut driver_driver_id en driver_id ; permuter les attributs dans la clé primaire ; virer l’index fk_driver_license_driver1_idx.

    Table newpassword : virer l’index newpassword_id_UNIQUE.

    Table vote : virer l’index vote_id_UNIQUE.



    Citation Envoyé par nike7414
    Justement je me posais la question pour "CASCADE"!
    Le tables suivantes ont une clé étrangère référençant la table driver avec l’option CASCADE :

    driver_payment
    driver_language
    driver_description


    Les tables suivantes ont une clé étrangère référençant (directement ou indirectement) la table driver mais sans l’option CASCADE :

    driver_category
    driver_price (via driver_category)
    driver_vehicle_category (via driver_category)
    driver_photo
    driver_price_fixed (via driver_category)
    driver_license
    disposal_booking
    transfer_booking
    vote

    Supposons que l’on code CASCADE pour toutes ces tables : si on supprime le chauffeur Raoul (table driver), pas de problème, le ménage est propagé dans toutes les tables qui viennent d’être énumérées, et Raoul n’existe plus.

    Supposons maintenant que vous ayez des scrupules à ce que les données disparaissent par exemple de la table transfer_booking, donc que vous conserviez NO ACTION pour cette table : si on n’y trouve rien concernant Raoul, le ménage sera fait. Si on y trouve quelque chose, alors le NO ACTION interdira l’opération de suppression de Raoul, et les données de Raoul seront préservées dans toutes ces tables.

    Donc à vous de réfléchir et voir pour quelles tables il faut conserver NO ACTION...


    Pour reprendre par exemple le cas de la table region, il est normal qu’il y ait CASCADE entre region et region_departement (en effet une region est un region_departement), et NO ACTION entre region et country : a priori, il n’est pas question de supprimer un pays qui a des régions. Tout comme on ne peut pas supprimer un client qui a des factures non réglées...


    DEFAULT CHARACTER SET : vous utilisez soit latin1, soit utf8, il y a une raison pour cette alternative ?


    On y arrivera
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  11. #71
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 55
    Points : 67
    Points
    67
    Par défaut
    Citation Envoyé par fsmrel Voir le message
    Bonsoir Nike,


    A quoi correspond la table user ? C’est une scorie à supprimer ?

    A quoi correspond la table email_sending ?
    J'ai supprimé la table user. La table email_sending est une table où j'enregistrerai les adresses d'email d'envoie par defaut. Pour envoyer des mails automatiques aux chauffeurs et aux clients.

    Citation Envoyé par fsmrel Voir le message
    Quelques aménagements à apporter :

    Table category_translated : injecter category_id dans la clé primaire ; supprimer l’index fk_category_translated_category1_idx :

    
    CREATE TABLE category_translated (
      category_translated_id INT NOT NULL AUTO_INCREMENT,
      category_id INT NOT NULL,
      category_translated_name VARCHAR(45) NOT NULL,
      category_translated_description MEDIUMTEXT NOT NULL,
      PRIMARY KEY (category_id, category_translated_id),
      UNIQUE INDEX idcategory_translated_id_UNIQUE (category_translated_id ASC),
      CONSTRAINT fk_category_translated_category1
        FOREIGN KEY (category_id)
        REFERENCES category (category_id)
        ON DELETE CASCADE
        ON UPDATE NO ACTION)
    
    

    Table client : virer l’index client_id_UNIQUE. Attribut email : 255 caractères pour une adresse de courriel, ça paraît beaucoup... (Même chose pour la table driver et quelques autres).

    Table client_photo : permuter les attributs dans la clé primaire. Virer l’index fk_client_photo_client1_idx.

    Table driver_photo : permuter les attributs dans la clé primaire. Virer l’index fk_user_photo_driver1_idx.

    Table driver_license_name : virer l’index driver_license_name_id_UNIQUE.

    Table driver_payment : virer l’index fk_driver_payment_driver1_idx.

    Table driver_license : renommer l’attribut driver_driver_id en driver_id ; permuter les attributs dans la clé primaire ; virer l’index fk_driver_license_driver1_idx.

    Table newpassword : virer l’index newpassword_id_UNIQUE.

    Table vote : virer l’index vote_id_UNIQUE.
    OK c'est fait!
    Pour les emails j'avais lu à des endroits que c'est mieux d'utiliser varchar(255), donc j'ai pris ca. Mais effectivement je n'ai jamais vu d'adresses emails à 255... J'ai mis varchar(60).


    Citation Envoyé par fsmrel Voir le message

    Le tables suivantes ont une clé étrangère référençant la table driver avec l’option CASCADE :

    driver_payment
    driver_language
    driver_description


    Les tables suivantes ont une clé étrangère référençant (directement ou indirectement) la table driver mais sans l’option CASCADE :

    driver_category
    driver_price (via driver_category)
    driver_vehicle_category (via driver_category)
    driver_photo
    driver_price_fixed (via driver_category)
    driver_license
    disposal_booking
    transfer_booking
    vote

    Supposons que l’on code CASCADE pour toutes ces tables : si on supprime le chauffeur Raoul (table driver), pas de problème, le ménage est propagé dans toutes les tables qui viennent d’être énumérées, et Raoul n’existe plus.

    Supposons maintenant que vous ayez des scrupules à ce que les données disparaissent par exemple de la table transfer_booking, donc que vous conserviez NO ACTION pour cette table : si on n’y trouve rien concernant Raoul, le ménage sera fait. Si on y trouve quelque chose, alors le NO ACTION interdira l’opération de suppression de Raoul, et les données de Raoul seront préservées dans toutes ces tables.

    Donc à vous de réfléchir et voir pour quelles tables il faut conserver NO ACTION...
    Mais si on supprime le chauffeur Raoul de la table driver et qu'on garde NO ACTION pour la table transfer_booking on ne saura tout de même pas qui aurait effectué le transfert, car le chauffeur aura disparu de la table driver, non?


    Citation Envoyé par fsmrel Voir le message
    DEFAULT CHARACTER SET : vous utilisez soit latin1, soit utf8, il y a une raison pour cette alternative ?
    Oui c'est vrai et il n'y a aucune raison particulière.
    J'ai changé latin1 en utf8.
    Mais il y a des tables où il n'y a ni latin1, ni utf8... Il faut mettre quelque chose?

    Citation Envoyé par fsmrel Voir le message
    On y arrivera
    C'est vrai que c'est long! Autant que ca soit bien fait. Le plus précis les changements sont fait, le plus efficace la BDD sera.

    Voici le script: choosedriver3.sql

  12. #72
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut
    Bonsoir Nike,



    Citation Envoyé par nike7414
    Mais si on supprime le chauffeur Raoul de la table driver et qu'on garde NO ACTION pour la table transfer_booking on ne saura tout de même pas qui aurait effectué le transfert, car le chauffeur aura disparu de la table driver, non?
    Non, le chauffeur Raoul n’aura pas disparu ! Dès qu’une ligne d’une table T (ou autre) référençant la table driver directement ou via une autre table contient des données relatives à Raoul, la tentative de suppression de Raoul dans la table driver est rejetée au moindre NO ACTION rencontré dans T (ou autre). Donc si dans transfer_booking (ou autre) il y a des données relatives à Raoul, c’est le rejet de l’opération et la table driver n’est pas affectée, Raoul sera conservé dans la table driver, le SGBD aura crapahuté dans les tables pour vérifier et finalement procéder au rejet de l’opération.



    Citation Envoyé par nike7414
    J'ai changé latin1 en utf8.
    Je vous invite à lire attentivement ce qui est écrit dans la doc de MySQL à propos de utf8. Notamment il y est fortement recommandé de remplacer CHAR par VARCHAR !


    Citation Envoyé par nike7414
    Mais il y a des tables où il n'y a ni latin1, ni utf8... Il faut mettre quelque chose?
    Il y a un choix qui a été fait à l’installation de MySQL. Cela dit, en supposant que votre base de données (schéma) se nomme nike7414, vous pouvez ajouter l’instruction suivante en tête du script des CREATE TABLE :

    ALTER SCHEMA nike7414 character set utf8 ;

    Les tables pour lesquelles rien n’a été précisé dans le CREATE TABLE seront automatiquement en utf8. Je vous renvoie à la doc : Database Character Set and Collation.


    Dès que j’aurai une heure, je vérifierai le script SQL.
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  13. #73
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 55
    Points : 67
    Points
    67
    Par défaut
    Citation Envoyé par fsmrel Voir le message

    Non, le chauffeur Raoul n’aura pas disparu ! Dès qu’une ligne d’une table T (ou autre) référençant la table driver directement ou via une autre table contient des données relatives à Raoul, la tentative de suppression de Raoul dans la table driver est rejetée au moindre NO ACTION rencontré dans T (ou autre). Donc si dans transfer_booking (ou autre) il y a des données relatives à Raoul, c’est le rejet de l’opération et la table driver n’est pas affectée, Raoul sera conservé dans la table driver, le SGBD aura crapahuté dans les tables pour vérifier et finalement procéder au rejet de l’opération.
    Je comprends! C'est mieux de ne pas supprimer le chauffeur s'il est a effectué un transfert un une mise à disposition, donc garder NO ACTION pour les tables:
    disposal_booking
    transfer_booking



    Citation Envoyé par fsmrel Voir le message
    Je vous invite à lire attentivement ce qui est écrit dans la doc de MySQL à propos de utf8. Notamment il y est fortement recommandé de remplacer CHAR par VARCHAR !
    Ah, d'accord! Même quand il s'agit d'un CHAR(3) comme country_code ? Ou même de "gender" dans la table "driver" qui est en CHAR(1)?


    Citation Envoyé par fsmrel Voir le message
    Il y a un choix qui a été fait à l’installation de MySQL. Cela dit, en supposant que votre base de données (schéma) se nomme nike7414, vous pouvez ajouter l’instruction suivante en tête du script des CREATE TABLE :

    ALTER SCHEMA nike7414 character set utf8 ;

    Les tables pour lesquelles rien n’a été précisé dans le CREATE TABLE seront automatiquement en utf8. Je vous renvoie à la doc : Database Character Set and Collation.
    OK merci, je vois. Mais comment faire ceci pour que ca change tout automatiquement en tête du script des CREATE TABLE? J'ai tenté ceci, en ajoutant un script, mais sans succès:
    Nom : MySQL Workbench alter schema.jpg
Affichages : 358
Taille : 78,7 Ko

    Après changement pour VARCHAR et le rajoute de CASCADE dans les tables: choosedriver3.sql

  14. #74
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut SQL EDITOR
    Bonsoir Nike,


    J’ai regardé votre script : ça a l’air bon.



    Citation Envoyé par nike7414
    Même quand il s'agit d'un CHAR(3) comme country_code ? Ou même de "gender" dans la table "driver" qui est en CHAR(1)?
    3 * 3 = 9 ; 3 * 1 = 3 : c’est raisonnable ! Mais 255 * 3 ça le serait beaucoup moins...



    Citation Envoyé par nike7414
    Mais comment faire ceci pour que ca change tout automatiquement en tête du script des CREATE TABLE?
    Pourquoi ne pas utiliser SQL Editor ? Il existe pour Windows, Linux, Mac OS X.

    Au pire, vous ajoutez l’instruction manuellement à l’aide de votre éditeur de texte...

    A noter que SQL Editor vous permet de modifier les scripts sans problème, de les exécuter...


    Exemple (j’utilise Windows) : Partie PLACES (j’évite de créer toutes les tables en seul paquet, je créée ensuite la partie DRIVERS, puis la partie CLIENTS) :


    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  15. #75
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 55
    Points : 67
    Points
    67
    Par défaut
    Bonjour fsmrel,

    Citation Envoyé par fsmrel Voir le message
    J’ai regardé votre script : ça a l’air bon.
    OK, donc selon vous c'est fini? Tout est bon?!

    J'ai rajouté le script final: choosedriver3.sql

  16. #76
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut On croise les doigts...
    Bonsoir Nike,


    Avez-vous pu vous servir de SQL Editor ? Merci de me le dire.


    Je vais regarder votre dernier script.


    Déjà, vous pouvez supprimer les instructions du début, car elles peuvent laisser passer des erreurs :

    SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
    SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
    SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';

    Je rappelle ce que dit la doc :

    When a model is exported using the main menu item File, Export, Forward Engineer SQL CREATE Script, some server variables are temporarily set to enable faster SQL import by the server. The statements added at the start of the code are:

    SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
    SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
    SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';

    These statements function as follows:

    • SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;: Determines whether InnoDB performs duplicate key checks. Import is much faster for large data sets if this check is not performed.

    • SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;: Determines whether the server should check that a referenced table exists when defining a foreign key. Due to potential circular references, this check must be turned off for the duration of the import, to permit defining foreign keys.

    • SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';: Sets SQL_MODE to TRADITIONAL, causing the server to operate in a more restrictive mode.

    These server variables are then reset at the end of the script.

    Vous pouvez évidemment supprimer ces @OLD en fin de script.


    Pensez à ajouter une instruction SET default_storage_engine=InnoDB ; en début de script.

    Virez les ENGINE = InnoDB des CREATE TABLE, ainsi que les DEFAULT CHARACTER SET = utf8 et, si ça n’est pas vous qui les avez codés, les AUTO_INCREMENT = n.


    Constituez un jeu d’essai permettant de secouer la base de données, prototyper les performances de l’application (top 10 des requêtes a priori les plus sensibles...) C’est une partie qui n’est pas simple, car il va falloir que vous simuliez l’activité de N chauffeurs attaquant en même temps, par exemple, la table transfer_booking... Mais mieux vaut prévenir que guérir...


    On croise les doigts,

    François
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  17. #77
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 55
    Points : 67
    Points
    67
    Par défaut
    [QUOTE=fsmrel;8552456]Bonsoir fsmrel,


    Oui j'ai pu me servir de SQL Editor et supprimé les:


    SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
    SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
    SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';

    En début du script et ceux qui étaient à la fin du script.

    J'ai aussi rajouté SET default_storage_engine=InnoDB ; au début et supprimé:
    ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 AUTO_INCREMENT = n.
    qui se trouvaient à la fin de chaque CREATE TABLE.

    Voila choosedriver3.sql

    Merci pour votre aide! Je vais faire un jeu d'essai pour voir si ca fonctionne bien.

  18. #78
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut Mieux vaut prévenir que guérir...
    Bonsoir Nike,


    Avouez que SQL Editor est bien pratique !

    J’ai regardé le script, ça à l’air d’être OK.

    Courage pour le jeu d’essai et le prototypage, mais comme je l’ai dit, better prevent than cure, même si ça consomme du temps et de l’énergie, au moins on sait objectivement où l'on va...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

  19. #79
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 55
    Points : 67
    Points
    67
    Par défaut phpMyAdmin import error
    Bonsoir fsmrel,

    J'ai pas eu le temps de m'y consacrer depuis début mars, mais là en commencent avec le site j'ai déjà un problème en important le fichier sql dans mon phpMyAdmin.
    Le premier problème c'etait les "GO" à la fin des TRIGGER, donc je les ai supprimé et ca ne m'a pas refait l'erreur.

    L'erreur que j'ai là est celle ci "Table 'choosedriver.region_departement' doesn't exist", comment ca se fait?

    Nom : choosedriver_error.png
Affichages : 263
Taille : 34,6 Ko

  20. #80
    Expert éminent sénior
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 002
    Points : 30 905
    Points
    30 905
    Billets dans le blog
    16
    Par défaut import, phpMyAdmin
    Bonsoir Nike,


    Pendant toute la semaine j’ai été occupé à d’autres tâches. Avez-vous résolu votre problème ? Je ne connais pas phpMyAdmin, mais vous avez utilisé le verbe « importer ». Comme par ailleurs « GO » pose problème, c’est que phpMyAdmin a ses propres conventions... Plutôt qu’importer, il faudrait que vous fassiez carrément un copier/coller du fichier .sql et que vous l’exécutiez, histoire de voir ce que cela donne...

    Quand vous dites : « L'erreur que j'ai là est celle ci "Table 'choosedriver.region_departement' doesn't exist" », soit vous cherchez à créer le trigger avant la table, soit il y a eu erreur lors de la création de la table, soit la connexion n’est pas la bonne...
    (a) Faites simple, mais pas plus simple ! (A. Einstein)
    (b) Certes, E=mc², mais si on discute un peu, on peut l’avoir pour beaucoup moins cher... (G. Lacroix, « Les Euphorismes de Grégoire »)
    => La relativité n'existerait donc que relativement aux relativistes (Jean Eisenstaedt, « Einstein et la relativité générale »)

    __________________________________
    Bases de données relationnelles et normalisation : de la première à la sixième forme normale
    Modéliser les données avec MySQL Workbench
    Je ne réponds pas aux questions techniques par MP. Les forums sont là pour ça.

Discussions similaires

  1. Réponses: 4
    Dernier message: 18/09/2007, 22h02
  2. Epine de conception BDD : calculs de valeurs
    Par YeP dans le forum Modélisation
    Réponses: 5
    Dernier message: 16/08/2007, 18h55
  3. conception BDD immobiliere
    Par mealtone dans le forum Débuter
    Réponses: 4
    Dernier message: 14/06/2006, 17h34
  4. conception BDD
    Par Naruto_kun dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 28/04/2006, 17h46
  5. [Conception] BDD & PHP, néophite à besoin d'aide pour un site
    Par Cusack dans le forum PHP & Base de données
    Réponses: 17
    Dernier message: 14/02/2006, 20h53

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