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

PHP & Base de données Discussion :

écriture en bdd extraordinairement lente [MySQL]


Sujet :

PHP & Base de données

  1. #41
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 098
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 098
    Points : 8 207
    Points
    8 207
    Billets dans le blog
    17
    Par défaut
    Je me suis probablement mal exprimé car ce que j'attendais pour la gestion du user n'était pas ce que tu as fait.
    Mon exemple porte sur la gestion du pays rattaché à l'utilisateur. Pour l'utilisateur et les autres tables et clefs étrangères le principe est le même.

    Sur le script collé
    -- Indentation incorrecte => Illisible
    -- Le $sql n'est pas bon, tu as fait un mix entre les colonnes des pays et les valeurs des utilisateurs
    -- Le foreach ($csv est à adapter, si tu l'exécutes ainsi ça va bloquer, voir ta classe de lecture CSV ou fgetcsv()
    -- Ligne 18 : tu accèdes à l'index des pays selon le nom du pays alors qu'on avait utilisé le code à 3 caractères non ?
    -- La ligne 21 est mauvaise, il faut pouvoir retrouver l'ID généré par MySQL selon le SESA, donc => $index_users[$csv_row->user_sesa] = $user_id;.
    -- Pareil pour la ligne 23

    Juste une remarque : ce code ne marchera que si les tables utilisées $index_XYZ existent
    À toi de les initialiser avant le parcours du CSV, comme dans l'exemple.

    et que dans ces tables, l'index mentionné existe aussi.
    D'où l'intérêt du isset() dans le foreach()




    Il faut aussi se poser la question de la réutilisation des identifiants du CSV autant que possible
    Par exemple si le "SESA" utilisateur est un identifiant numérique alors il n'y a pas grand intérêt d'avoir une clef primaire auto-incrémentée
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

  2. #42
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 383
    Points : 5 732
    Points
    5 732
    Billets dans le blog
    1
    Par défaut
    Je viens de mettre à jour le code du post #40 avant de lire le post #41 ; je regarde et le prend en compte.
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

    Si la discussion est résolue, merci de cliquer sur le bouton

  3. #43
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 383
    Points : 5 732
    Points
    5 732
    Billets dans le blog
    1
    Par défaut
    J'ai mis un certain et comme dans mon cas, plus la journée avance et moins je suis bon...


    voici ce que je propose :

    Code php : 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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    /*
     * d'abord, on initialise les tables $index_organization, $index_countries et $index_user avec le contenu de la bdd.
     * Ces inits sont à faire une seule fois, avant la lecture du CSV, pour ne pas le refaire à chaque lecture de ligne
     */
     
    //$index_organization
        $index_organization = [];
     
        $sql = <<<SQL
    SELECT OZ_ident, OZ_organization from OZ_organization
    SQL;
     
        $statement = $pdo->query($sql);
        $select_organization = $statement->fetchAll(PDO::FETCH_KEY_PAIR);
     
        foreach($select_organization as $organization_id => $organization_name){
            $index_organization[] = ['organization_id'=>$organization_id, 'organization_name'=>$organization_name];
            //syntaxe pas bonne je crois (merci de me corriger)
        }
     
    //$index_countries
        $index_countries = [];
     
        $sql = <<<SQL
    SELECT COU_ident, COU_country from COU_country  
    SQL;         //que 2 colonnes pour pouvoir utiliser FETCH_KEY_PAIR (la colonne COU_country a un index UNIQUE)
     
        $statement = $pdo->query($sql);
        $select_country = $statement->fetchAll(PDO::FETCH_KEY_PAIR);
     
        foreach($select_country as $country_id => $country_name){
            $index_country[] = ['country_id'=>$country_id, 'country_name'=>$country_name];
            //syntaxe pas bonne je crois (merci de me corriger)
    }
     
    //$index_users
        $index_users = [];
     
    $sql = <<<SQL
    SELECT US_ident, US_sesa from US_user
    SQL;              //que 2 colonnes pour pouvoir utiliser FETCH_KEY_PAIR (la colonne US_sesa a un index UNIQUE)
     
        $statement = $pdo->query($sql);
        $select_user = $statement->fetchAll(PDO::FETCH_KEY_PAIR);
     
        foreach($select_user as $user_id => $user_SESA){
            $index_user[] = ['user_id'=>$user_id, 'user_SESA'=>$user_SESA];
            //syntaxe pas bonne je crois (merci de me corriger)
     
    //on prépare l'INSERT
        $sql = <<<SQL
    INSERT INTO US_user (US_sesa, US_firstname, US_lastname, OZ_ident, COU_ident)
    VALUES (:sesa, :firstname, :lastname,:idoz,:idcou)
    SQL;
        $insert_user = $pdo->prepare($sql);
     
        // Les tables étant vides, les index sont vides
     
        //$index_users = [];
     
        while (($csv_row = fgetcsv(CSVParser::getHandle(), 0, CSVParser::getSeparator(),
                CSVParser::getEnclosure(),"")) !== false)
            { // Parcours du CSV
            if (!isset($index_users[$csv_row->user_sesa])) { // User pas encore indexé ?
                $insert_user->execute([ // On l'insère en base...
                ':sesa' => $csv_row->user_sesa,
                ':firstname' => $csv_row->user_firstname,
                ':lastname' => $csv_row->user_lastname,
                ':idoz' => $index_organization[$csv_row->organization_id],
                ':idcou' => $index_countries[$csv_row->country_id],
                ]);
                $user_id = $pdo->lastInsertId(); // ... on récupère l'ID généré ...
                $index_users[$csv_row->user_sesa] = $user_id; // ... et on indexe le nouvel ID selon le code du user
            } else { // Si pays déjà en base/indexé...
                $user_id = $index_users[$csv_row->user_sesa]; // ... on récupère simplement l'ID selon le code grâce à l'index
                // PHP
            }
            // À ce stade, dans tous les cas, on a la table US_user à jour
            // et $user_id prêt à être utilisé
            // ...
            }

    J'ai bien vu ta remarque pour ne pas créer un id auto-incrémenté si une autre colonne peut jouer ce rôle, mais je ne l'ai pas fait préférant adopter toujours la même règle (c'est plus simple).
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

    Si la discussion est résolue, merci de cliquer sur le bouton

  4. #44
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 098
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 098
    Points : 8 207
    Points
    8 207
    Billets dans le blog
    17
    Par défaut
    Tu initialises mal tes tableaux : l'ordre des colonnes sélectionnées est important pour le PDO::FETCH_KEY_PAIR, et pourquoi des foreach() ? fetchAll() et FETCH_KEY_PAIR font tout déjà
    De plus tu ne respectes pas la structure [valeur => id] => On doit retrouver l'ID selon une valeur du CSV, ex. ["Code pays sur 3 caractères" => "ID de COU_country"]
    Si tu dois produire des array_search() pour retrouver ta clef étrangère alors autant faire une requête SQL
    Et puis, garde la même nomenclatures pour tes index, là tu as un coup des tableaux aux pluriel ($index_countries), un coup au singulier ($index_organization) => On met tout au pluriel

    Bon, je te montre un exemple pour 3 tables. Stp, prend le temps d'étudier le script, et lis bien les commentaires.
    Le principe est de traiter tes tables 1 à 1, en commençant par celles qui n'ont pas de dépendances, puis de traitant celles dépendants des tables traitées précédemment
    Respecte le même principe pour les ajouts futurs, autrement ça ne fonctionnera pas.
    Je ne connais pas ton CSV, il faudra adapter selon ses colonnes, c'est précisé en commentaire.

    Désolé si ça plantouille par endroit, le script n'a pas pu être testé.

    Code php : 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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    ////////////////////////////////////////////////// GESTION DU PAYS ////////////////////////////////////////////////////
    // Création de l'index des pays
    $sql = <<<SQL
        SELECT
            -- Attention, ordre des colonnes important
            -- pour le résultat obtenu avec PDO::fetchAll(PDO::FETCH_KEY_PAIR)
            COU_country,    -- En 1er la colonne qui permettra d'indexer l'ID, ici idéalement le code pays sur 3 caractères
            COU_ident       -- En 2nd l'ID à retrouver
        FROM COU_country
        SQL;
    $index_countries = $pdo->query($sql)->fetchAll(PDO::FETCH_KEY_PAIR);
    // $index_countries contient les couples ["nom/code pays" => "ID"] ou un tableau vide si table vide
    // => On retrouve l'ID selon le nom/code du pays
     
    // Préparation de la requête d'insertion du pays
    $sql = <<<SQL
        INSERT INTO COU_country (COU_country_alpha3, COU_country, COU_region)
        VALUES (:code, :name, :region)
        SQL;
    $insert_country = $pdo->prepare($sql);
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     
    /////////////////////////////////////////////// GESTION DE L'UTILISATEUR //////////////////////////////////////////////
    // Création de l'index des utilisateurs
    $sql = <<<SQL
        SELECT
            -- Attention, ordre des colonnes important
            -- pour le résultat obtenu avec PDO::fetchAll(PDO::FETCH_KEY_PAIR)
            US_sesa,    -- En 1er la colonne qui permettra d'indexer l'ID
            US_ident    -- En 2nd l'ID à retrouver
        FROM US_user
        SQL;
    $index_users = $pdo->query($sql)->fetchAll(PDO::FETCH_KEY_PAIR);
    // $index_users contient les couples ["SESA utilisateur" => "ID"] ou un tableau vide si table vide
    // => On retrouve l'ID selon le SESA de l'utilisateur
     
    // Préparation de l'insertion de l'utilisateur
    $sql = <<<SQL
        INSERT INTO US_user (US_sesa, US_firstname, US_lastname, OZ_ident, COU_ident)
        VALUES (:sesa, :firstname, :lastname, :idoz, :idcou)
        SQL;
    $insert_user = $pdo->prepare($sql);
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     
    ///////////////////////////////////////////// GESTION DE L'ORGANISATION ///////////////////////////////////////////////
    // Création de l'index des organisations
    $sql = <<<SQL
        SELECT
            -- Attention, ordre des colonnes important
            -- pour le résultat obtenu avec PDO::fetchAll(PDO::FETCH_KEY_PAIR)
            OZ_organization,    -- En 1er la colonne qui permettra d'indexer l'ID
            OZ_ident            -- En 2nd l'ID à retrouver
        FROM OZ_organization
        SQL;
    $index_organizations = $pdo->query($sql)->fetchAll(PDO::FETCH_KEY_PAIR);
    // $index_organizations contient les couples ["nom organization" => "ID"] ou un tableau vide si table vide
    // => On retrouve l'ID selon le nom de l'organisation
     
    // Préparation de l'insertion de l'organisation
    // À FAIRE
    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     
    ////////////////////////////////////////////////// PARCOURS DU CSV ////////////////////////////////////////////////////
    $csv_file = 'fichier-source.csv';
    $csv_handler = fopen($csv_file, 'r');
    $csv_separator = ',';
    $csv_enclosure = '"';
    $csv_escape = '';
     
    if (fread($csv_handler, 3) !== "\xEF\xBB\xBF") { // 3 premiers octets ne correspondent pas au BOM ?
        // Si BOM absent on lit le fichier depuis le début
        rewind($csv_handler); // Retour au début du fichier
    } // Sinon on poursuit après le BOM
     
    $header = fgetcsv($csv_handler, 0, $csv_separator, $csv_enclosure, $csv_escape);
    // Je ne connaîs pas le nom de tes colonnes CSV, à adapter dans la boucle lors des accès $csv_entry->...
     
    while ($csv_entry = fgetcsv($csv_handler, 0, $csv_separator, $csv_enclosure, $csv_escape)) {
     
        // Pour pouvoir accéder aux colonnes du CSV en fait $csv_entry->column_name
        $csv_entry = (object)array_combine($header, $csv_entry);
     
        // Il faut commencer le traitement par les tables qui ne dépendent pas des tables précédentes
        // Sinon tu vas te retrouver avec des clefs inconnues
     
        //////////////// TRAITEMENT DU PAYS DU CSV
        // Commençons par la table des pays, qui ne dépend d'aucune autre table
        // J'imagine que ton CSV a une colonne "country_code"
        if (!isset($index_countries[$csv_entry->country_code])) { // Si pays pas encore indexé, et donc pas encore en base
            $insert_country->execute([ // On l'insère en base
                ':code' => $csv_entry->country_code,        // J'imagine que ton CSV a une colonne "country_code"
                ':name' => $csv_entry->country_name,        // J'imagine que ton CSV a une colonne "country_name"
                ':region' => $csv_entry->country_region,    // J'imagine que ton CSV a une colonne "country_region"
            ]);
            $country_id = $pdo->lastInsertId(); // Obtention de l'ID généré par MySQL lors de l'insertion
            $index_countries[$csv_entry->country_code] = $country_id; // Indexation de l'ID pays selon le code pays
        }  else {
            $country_id = $index_countries[$csv_entry->country_code];
        }
        // Arrivé ici on a $country_id valorisé, la table à jour, et l'index à jour
        // On poursuit avec une autre table indépendante, ou qui dépend de COU_country seule (puisque cette dernière est à jour)
     
        //////////////// TRAITEMENT DE L'ORGANISATION DU CSV
        // On poursuit avec l'organisation qui ne dépend d'aucune autre table
        if (!isset($index_organizations[$csv_entry->organization_name])) {
            $insert_organization->execute([':name' => $csv_entry->organization_name]);
            $organization_id = $pdo->lastInsertId();
            $index_organizations[$csv_entry->organization_name] = $organization_id;
        } else {
            $organization_id = $index_organizations[$csv_entry->organization_name];
        }
        // Arrivé ici on a $organization_id valorisé, la table à jour, et l'index à jour
        // On poursuit avec une autre table indépendante, ou qui dépend seulement de COU_country et/ou OZ_organization (puisque ces dernières sont à jour)
     
        //////////////// TRAITEMENT DE L'UTILISATEUR DU CSV
        // Imaginons que US_user n'a pas d'autres dépendances que le pays et l'organisation
        // C'est pour l'EXEMPLE de la réutilisation de $country_id et $organization_id
        // COMME TOUT LE RESTE IL FAUDRA ADAPTER
        if (!isset($index_users[$csv_entry->user_sesa])) {
            $insert_user->execute([
                ':sesa' => $csv_entry->user_sesa,
                ':firstname' => $csv_entry->user_firstname,
                ':lastname' => $csv_entry->user_lastname,
                // Et c'est là que tout se joue...
                // Utilisation des ID des clefs étrangères récupérées plus haut
                ':organization' => $organization_id,
                ':country' => $country_id,
            ]);
            $user_id = $pdo->lastInsertId();
            $index_users[$csv_entry->user_sesa] = $user_id;
        } else {
            $user_id = $index_users[$csv_entry->user_sesa];
        }
        // Arrivé ici on a $user_id valorisé, la table à jour, et l'index à jour
        // On poursuit avec une autre table indépendante ou dépendant selon des pays/organisation/utilsateur
     
        // ...
    }
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

  5. #45
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 383
    Points : 5 732
    Points
    5 732
    Billets dans le blog
    1
    Par défaut
    Bonsoir,

    je suis impressionné par ce que tu me proposes : moi, il m'aurait fallu des heures pour en faire autant (mais de toutes façons, j'en aurais pas été capable).

    pourquoi des foreach() ? fetchAll() et FETCH_KEY_PAIR font tout déjà
    car je ne connaissais pas du tout...

    J'ai vu ton post environ 2 heures après que tu l'ai écrit...Je regarderai demain matin (esprit plus clair), et pour mieux assimiler (car j'ai besoin de comprendre pour adapter), je le testerai petits bouts par petits bouts.

    A demain
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

    Si la discussion est résolue, merci de cliquer sur le bouton

  6. #46
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 383
    Points : 5 732
    Points
    5 732
    Billets dans le blog
    1
    Par défaut
    Je progresse très lentement mais au moins je recule pas (ce qui peut arriver si j'oublie de faire une sauvegarde et que je pourris le code...)

    J'ai pu tester le début de ta proposition :
    Code php : 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
            $ppp = new PDOPlusPlus();
            $pdo = $ppp->getPdo();
     
    // Création de l'index des pays
            $sql = <<<SQL
        SELECT
            -- Attention, ordre des colonnes important
            -- pour le résultat obtenu avec PDO::fetchAll(PDO::FETCH_KEY_PAIR)
            COU_country_alpha3,    -- En 1er la colonne qui permettra d'indexer l'ID, ici idéalement le code pays sur 3 caractères
            COU_ident       -- En 2nd l'ID à retrouver
        FROM COU_country
        SQL;
            $index_countries = $pdo->query($sql)->fetchAll(PDO::FETCH_KEY_PAIR);
    // $index_countries contient les couples ["nom/code pays" => "ID"] ou un tableau vide si table vide
    // => On retrouve l'ID selon le nom/code du pays
     
            // la requête d'insertion du pays
            $country = 'nom_pays';
            $country_alpha3 = 'ABC';
            $region = 'EMEA';   //obligé pour le test de mettre un nom connu à cause de la contrainte CHECK(COU_region IN ('ISMA','EMEA','NAM','other','China','APAC','India')) (les régions sont des régions du monde)
     
            $sql = <<<SQL
        INSERT INTO COU_country (COU_country_alpha3, COU_country, COU_region)
        VALUES ({$ppp($country_alpha3 )}, {$ppp($country)},  {$ppp($region)})
        SQL;
            $insert_country = $ppp->insert($sql);
    La classe PDOPlusPlus faisant automatiquement une préparation, je peux sauter cette étape. Par contre, n'ayant pas trouvé l'équivalent de PDO::FETCH_KEY_PAIR, je suis resté en PDO pour le SELECT.

    Pour l'instant, ton code me donne pleine satisfaction .
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

    Si la discussion est résolue, merci de cliquer sur le bouton

  7. #47
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 383
    Points : 5 732
    Points
    5 732
    Billets dans le blog
    1
    Par défaut
    Bonsoir,

    toujours aussi lent, donc encore loin d'avoir fini, mais une question. J'en suis à la création des tables avec les index. J'ai en tout 15 tables, donc il y aura 15 tableaux. La plupart du temps, il y a une colonne qui possède un index d'unicité, donc pour la valeur, je prend cette colonne.

    Si on prend le cas des pays, le code à 3 lettres étant unique, ça donne (au passage, j'ai adapté ton code à l'utilisation de la classe PDOPlusPlus) :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // Création de l'index des pays
            $sql = <<<SQL
    SELECT
        -- Attention, ordre des colonnes important
        -- pour le résultat obtenu avec PDO::fetchAll(PDO::FETCH_KEY_PAIR)
        COU_country_alpha3,    -- En 1er la colonne qui permettra d'indexer l'ID, ici idéalement le code pays sur 3 caractères
        COU_ident       -- En 2nd l'ID à retrouver
    FROM COU_country
    SQL;
     
            $stmt = $ppp->selectStmt($sql);
            $index_countries = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
    // $index_countries contient les couples ["code pays" => "ID"] ou un tableau vide si table vide
    // => On retrouve l'ID selon le code du pays

    Par contre, je dois gérer une table qui ne comporte aucune colonne ayant ce statut d'unicité (à part la clé primaire of course), donc là, je sais pas quoi faire. Voici cette table :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE LI_license(
       LI_ident INT UNSIGNED AUTO_INCREMENT,
       LI_activate_date DATE NOT NULL,
       LI_deactivate_date DATE,
       AP_ident INT UNSIGNED NOT NULL,
       US_ident INT UNSIGNED NOT NULL,
       PRIMARY KEY(LI_ident),
       FOREIGN KEY(AP_ident) REFERENCES AP_application(AP_ident),
       FOREIGN KEY(US_ident) REFERENCES USL_user_license(US_ident)
    );
    A noter que plusieurs licences peuvent très bien avoir les mêmes valeurs pour les 2 colonnes LI_activate_date et LI_deactivate_date. L'unicité sera obtenue si on considère la combinaison des 2 colonnes AP_ident et US_ident . Ces 2 identifiants portent sur les tables
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE AP_application(
       AP_ident INT UNSIGNED AUTO_INCREMENT,
       AP_application_name VARCHAR(50) NOT NULL,
       PL_ident INT UNSIGNED,
       PRIMARY KEY(AP_ident),
       UNIQUE(AP_application_name),
       FOREIGN KEY(PL_ident) REFERENCES PL_platform(PL_ident)
    );
    et
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE US_user(
       US_ident INT UNSIGNED AUTO_INCREMENT,
       US_sesa INT,
       US_firstname VARCHAR(50),
       US_lastname VARCHAR(50),
       OZ_ident INT UNSIGNED,
       COU_ident INT UNSIGNED,
       PRIMARY KEY(US_ident),
       UNIQUE(US_sesa),
       FOREIGN KEY(OZ_ident) REFERENCES OZ_organization(OZ_ident),
       FOREIGN KEY(COU_ident) REFERENCES COU_country(COU_ident)
    );
    Comment gérer ce cas, STP ? (Bien sûr, répond en PDO et je saurai adapter)
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

    Si la discussion est résolue, merci de cliquer sur le bouton

  8. #48
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 098
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 098
    Points : 8 207
    Points
    8 207
    Billets dans le blog
    17
    Par défaut
    toujours aussi lent
    Ce ne sont donc pas les SELECT qui te ralentissent ? Si oui ne continue pas sur la piste des index PHP, ça complique ton script pour rien.

    L'unicité sera obtenue si on considère la combinaison des 2 colonnes AP_ident et US_ident
    Je comprends que dans ton modèle un utilisateur ne peut avoir qu'1 licence par application

    La licence sera donc attribuée uniquement à l'utilisateur en cours dans ta boucle,
    donc il n'y aura pas besoin de réaccéder à cette licence dans un prochain tour de boucle,
    donc il n'y a pas besoin d'indexer le couple (utilisateur/application) => licence
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

  9. #49
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 383
    Points : 5 732
    Points
    5 732
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    je suis enfin dispo ! (j'habite en montagne et ce matin, ski de fond).

    J'ai pas tout compris. Néanmoins, tu dis pas besoin d'indexer le couple (utilisateur/application) => licence . Mais je pense que vu ma façon de faire, y a besoin de tout indexer. En effet, je disais qu'il y a 15 tables SQL. Il y a aussi 15 classes, qui sont instanciées à chaque ligne du CSV lue (presque car en réalité, il y a 2 types de CSV donc on instancie que les classes nécessaires). Ces classes comportent notamment 2 méthodes : seekId et save.
    Exemple pour une des classes (pas encore modifiée donc y a encore le SELECT que je vais remplacer) :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     public function seekId( ?string $name ): ?int
        {
            if (!$name) return NULL; //si NULL en entrée, return NULL
     
            $ppp = new PDOPlusPlus();
            $sql = <<<sql
    SELECT `AP_ident` FROM `ap_application` WHERE `AP_application_name` = {$ppp($name)}
    sql;
            return $ppp->select($sql)[0]['AP_ident'] ?? 0;
        }

    Code php : 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
    28
    29
    30
    31
    public function save( bool $appli_prd, ?string $name, ?int $id_platf, $ref_ppp) {
     
            try
            {
     
     /*
     * appli en bdd ou non ? Si non, insert
     */
                $appli_in_bdd = self::seekId($name);
                if (!$appli_in_bdd)
                {
                    if ($appli_prd)
                    {
                        $sql = <<<sql
    INSERT INTO `ap_application` (`AP_application_name`,`PL_ident`) VALUES (
    {$ref_ppp($name)}, {$ref_ppp($id_platf, 'int')}
    )
    sql;
                    }
     
                    $nb_lines = $ref_ppp->insert($sql);
     
                }
                return true;
        }
     
     
        catch (\Exception $e) {
            return false;
        }
        }
    Je ne vais faire le INSERT dans la méthode save que si la méthode seekId me retourne autre chose que 0 ; j'ai donc systématiquement besoin de la méthode seekId. C'est à l'opposé de ce que tu dis. Où est l'erreur ?
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

    Si la discussion est résolue, merci de cliquer sur le bouton

  10. #50
    Expert confirmé
    Avatar de laurentSc
    Homme Profil pro
    Webmaster débutant perpétuel !
    Inscrit en
    Octobre 2006
    Messages
    10 383
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Webmaster débutant perpétuel !
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2006
    Messages : 10 383
    Points : 5 732
    Points
    5 732
    Billets dans le blog
    1
    Par défaut
    Je n'ai plus ce problème de lenteur car je fais beaucoup de requêtes SQL (lors d'un INSERT, je stocke le ID (LASTINSERTID) dans un tableau PHP, donc quand j'en ai de nouveau besoin, au lieu de faire un SELECT, je lis juste ce tableau, ce qui est beaucoup plus rapide).
    Il vaut mieux viser la perfection et la manquer que viser l'imperfection et l'atteindre. - Bertrand Russell

    Si la discussion est résolue, merci de cliquer sur le bouton

+ Répondre à la discussion
Cette discussion est résolue.
Page 3 sur 3 PremièrePremière 123

Discussions similaires

  1. [MySQL] Erreur pour écriture dans BDD
    Par laissaAnn dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 03/05/2013, 15h47
  2. Accès en écriture à la BdD impossible
    Par tssr2008 dans le forum WebDev
    Réponses: 3
    Dernier message: 20/06/2008, 00h48
  3. Réponses: 5
    Dernier message: 18/07/2007, 11h38
  4. Réponses: 1
    Dernier message: 24/10/2006, 12h10
  5. Meilleur méthode d'écriture en bdd - optimisation
    Par maximenet dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 14/09/2006, 12h15

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