php-experts.org - développement php et internet » MySQL https://www.php-experts.org Ressources sur le développement internet, PHP/MySQL, Ajax, marketing online, référencement... Sat, 19 Jun 2010 14:23:03 +0000 http://wordpress.org/?v=2.9.2 en hourly 1 CSV et MySQL : SELECT INTO OUTFILE et LOAD DATA INFILE https://www.php-experts.org/bases-de-donnees/mysql/csv-mysql-select-into-outfile-load-data-infile-206 https://www.php-experts.org/bases-de-donnees/mysql/csv-mysql-select-into-outfile-load-data-infile-206#comments Mon, 27 Apr 2009 01:05:07 +0000 Didier https://www.php-experts.org/?p=206 J’ai eu à me pencher sur les imports-exports sous MySQL. Mon but était de disposer de fichiers utilisables dans un format “humain” (comprendre: que les gens du marketing pouvaient exploiter avec leur cher Excel) sans pour autant passer par des scripts de conversion hasardeux et lourds pour le serveur. Il a donc fallu que je cherche les meilleures solutions pour pouvoir générer et importer des fichiers CSV dans MySQL,mon SGBDR favori. J’ai dû me servir du couple SELECT INTO OUTFILE pour les exports, et LOAD DATA INFILE pour les imports. Petit rappel syntaxique.

Exports CSV avec MySQL : SELECT INTO OUTFILE

Le principe de SELECT INTO OUTFILE est simple: réaliser un export de données en écrivant un resultset (résultats d’exécution d’une requête) directement dans un fichier CSV sur le serveur. Pour cela, l’utilisateur avec lequel vous vous connectez à MySQL doit avoir le priilège “FILE”. Autre remarque, vous ne pourrez en aucun cas écraser un fichier déjà existant sur le serveur (ceci pour la simple et bonne raison qu’il serait assez dommageable d’écraser, par exemple, votre fichier /etc/passwd).

Voici donc la syntaxe, finalement assez simple, de la fonction SELECT INTO OUTFILE :

  1. SELECT champ
  2. FROM TABLE
  3. WHERE champ = ‘valeur cherchée’
  4. INTO OUTFILE ‘/var/dump.csv’
  5. FIELDS
  6.     TERMINATED BY ‘;’
  7.     OPTIONALLY ENCLOSED BY ‘"’

Dans le fichier exporté, les champs ne sont pas délimités, sauf si vous utilisez FIELDS ENCLOSED BY. Le OPTIONALLY spécifie que seules les chaînes de caractères doivent être encadrées.
Le délimiteur par défaut est l’espace. Pour en utiliser un autre (virgule, point-virgule, tabulation, …) il faut utiliser la directive FIELDS TERMINATED BY. Evidemment, on peut utiliser des caractères spéciaux comme la tabulation ‘t’ ou le retour à la ligne ‘n’ (éventuellement CR+LF sous Windows, donc ‘rn’). Il existe aussi LINES TERMINATED BY pour contrôler le caractère de fin de ligne.

Du coup, en lançant sur la base de mon blog cette requête :

  1. mysql> SELECT ID,post_title,comment_count
  2. FROM `wp_posts`
  3. WHERE `post_status` = ‘publish’
  4.  ORDER BY `post_date` DESC LIMIT 3
  5. INTO OUTFILE ‘/tmp/blog_posts.dump’
  6. FIELDS
  7. TERMINATED BY ‘;’
  8. OPTIONALLY ENCLOSED BY ‘"’;

j’ai pu récupérer un fichier plat qui donnait :

  1. 179;"plugin : yURL ReTwitt";1
  2. 22;"5 plugins indispensables pour coder en PHP avec l’IDE Eclipse";0
  3. 138;"plugin : wp_list_sub_pages()";0

Soit, un joli fichier CSV bien propre, directement exploitable (pourquoi pas par Excel).

Imports de CSV dans MySQL : LOAD DATA INFILE

Le LOAD DATA INFILE, qui permet de faire l’exact inverse du INTO OUTFILE, est tout aussi simple à utiliser. Dans les bonnes conditions, c’est vraiment l’un des outils d’import MySQL les plus puissants.
Déjà, bonne nouvelle, la syntaxe des commandes qui permet à LOAD DATA INFILE de repérer les débuts et fin de champs (et de ligne) est la même que pour SELECT INTO OUTFILE. On retrouve donc sans surprise les FIELDS TERMINATED BY et autres joyeusetés.
Une gestion des doublons est aussi possible grâce aux mots-clefs IGNORE et REPLACE, qui parlent d’eux-même. Déclenchés en cas de doublon dans une clé (primaire ou unique), REPLACE effacera l’ancienne ligne pour la remplacer par la nouvelle. Attention donc, vous perdrez donc la pérennité de vos ID puisque ceux-ci changeront lors de l’import de données. IGNORE permettra simplement de conserver l’ancienne ligne, les nouvelles données n’étant pas écrites: vous conservez vos ID mais perdez le bénéfice de l’import sur cette ligne.
Vous pouvez aussi spécifier la liste des champs dans lesquelles les données doivent être stockées avec la syntaxe classique “(champ1, champ2, champ3)” (sans guillemets) en fin de commande.
Pour prendre un exemple, avec un fichier de la forme :

  1. 1;120;"texte1";
  2. 2;240;"texte2";

En imaginant qu’on ne veut garder que l’id (champ 1) et le texte (champ 3), et les insérer dans les champs correspondants de la table SQL “data”, on peut utiliser le paramètre @dummy pour demander au serveur d’ignorer l’un des champs du CSV. Cela nous donne une requête de la forme :

  1. LOAD DATA INFILE ‘/tmp/data.csv’
  2. INTO TABLE `data`
  3. FIELDS
  4. TERMINATED BY ‘;’
  5. OPTIONALLY ENCLOSED BY ‘"’
  6. (id, @dummy, texte)

Et si par malheur votre fichier commence par 2 lignes d’entête, pas de souci, vous pouvez présicer IGNORE 2 LINES dans la requête pour que soient ignorées les 2 premières lignes.

Et voila. Deux commandes, finalement pas bien complexes une fois qu’on les a prises en main, qui permettent de gérer efficacement les imports/exports de fichiers CSV sous MySQL. Pour faire suite à cet article, nous verrons bientôt comment optimiser la vitesse de vos INSERT dans MySQL.

]]>
https://www.php-experts.org/bases-de-donnees/mysql/csv-mysql-select-into-outfile-load-data-infile-206/feed 3
5 plugins indispensables pour coder en PHP avec l’IDE Eclipse https://www.php-experts.org/developpement-web/5-plugins-indispensables-pour-coder-en-php-avec-lide-eclipse-22 https://www.php-experts.org/developpement-web/5-plugins-indispensables-pour-coder-en-php-avec-lide-eclipse-22#comments Mon, 13 Apr 2009 11:55:21 +0000 Didier https://www.php-experts.org/?p=22 L’IDE Eclipse, conçu à l’origine pour développer en Java, s’est enrichi de fonctionnalités avancées, sous forme de plugins, qui lui permettent aujourd’hui de jouer dans la cours des grands des éditeurs de code PHP. Tour d’horizon de ceux que j’utilise.

1. Eclipse PDT

Vu ses parents, Zend et IBM, le projet Eclipse PDT est un “(Php) Development Tools framework” complet. Il étend les capacités natives de la plate-forme Eclipse pour permettre de développer calmement des applications solides en PHP. Pas vraiment besoin de le présenter, si ?
Eclipse PDT est téléchargeable en tant que plug-in ou en version “bundle” (PDT all-in-one), c’est à dire avec Eclipse et tous les composants de base. Ceci est très utile dans le cas d’une nouvelle installation.
Télécharger Eclipse PDT

Il existe d’autres plugins permettant d’ajouter à Eclipse le support du PHP, comme PHPEclipse ou Eclipse PHP IDE, développé par Zend.

2. RegEx Util

Editeur d’expressions régulières, toujours pratique de part le fait qu’il surligne les expressions qui matchent quand on sélectionne une partie du pattern. Il permet aussi de rationaliser ses expressions, notamment en utilisant les classes prédéfinies -comme [alphanum]

Site officiel : http://myregexp.com/eclipsePlugin.html
Update Site : http://regex-util.sourceforge.net/update/

RegexUtil pour Eclipse

RegexUtil pour Eclipse

3. SubClipse

SVN pour Eclipse avec Subclipse

SVN pour Eclipse avec Subclipse

Ajoute le support de SVN (SubVersion) à Eclipse. SVN est un système de gestion de versionning comme CVS intégrant quelques améliorations, comme la possibilité de déplacer et supprimer des fichiers, sans perdre leur historique.

Site officiel : http://subclipse.tigris.org/
Update Site (pour la branche 1.6) : http://subclipse.tigris.org/update_1.6.x

4. Remote System Explorer (RSE)

Permet notamment d’éditer ses fichiers directement via une connexion SSH. Je m’en sers pour les petites retouches de code PHP rapides qui ne peuvent “pas attendre”.

Site officiel : http://www.eclipse.org/dsdp/tm/tutorial/
Update Site : http://download.eclipse.org/dsdp/tm/updates

5. Azzuri Clay

azzurri clay

Azzurri Clay: bases de données sous Eclipse

Un peu difficile à prendre en mains, Azzuri Clay est un plugin commercial pour Eclipse qui permet d’ajouter un vrai support des bases de donnéees. Le système de licence adopté est un peu étrange: la version Pro ne peut être achetée qu’au Japon. Il n’en reste pas moins que l’édition classique, gratuite, est toujours intéressante.
La liste des SGBDR supportés est assez impressionnante vu qu’elle comprend, notamment, les classiques MySQL, PostGres, Oracle, MS SQL Server, DB2, Informix, mais aussi, beaucoup plus rare, SAP.

Pour se servir du Database Modeler d’Azzuri Clay, il faut créer un projet (ou utiliser un projet déjà existant) et faire File -> New -> Other -> Database Modeling -> Azzurri Clay Database Design Diagram.

Une fois cela fait, on peut créer ses premières tables, exporter les scripts SQL de création (selon le SGBDR choisi), et même faire du retro engineering sur des bases de données déjà crées.

Site officiel : http://www.azzurri.jp/en/clay/index.html
Update Site : http://www.azzurri.co.jp/eclipse/plugins

Références pour Eclipse

Installation minimale d’Eclipse, par Thierry Bothorel

]]>
https://www.php-experts.org/developpement-web/5-plugins-indispensables-pour-coder-en-php-avec-lide-eclipse-22/feed 3
Optimisation d’une requête SQL avec EXPLAIN et log_slow_queries https://www.php-experts.org/bases-de-donnees/mysql/autopsie-et-optimisation-dune-requete-sql-avec-explain-et-log_slow_queries-14 https://www.php-experts.org/bases-de-donnees/mysql/autopsie-et-optimisation-dune-requete-sql-avec-explain-et-log_slow_queries-14#comments Sat, 12 Jul 2008 17:22:34 +0000 Didier https://www.php-experts.org/?p=14 Depuis quelques temps, un serveur qui héberge quelques petits sites s’est mis à monter régulièrement en charge, sans augmentation de trafic, ni changements applicatifs. J’ai laissé traîner les choses, ne sachant pas d’où venait le souci.
Il aura fallu cinq minutes de travail et l’utilisation de la commande shell top, de la directive de configuration MySQL log_slow_queries et de la commande SQL EXPLAIN pour régler le problème de lenteur des sites.
Tout d’abord, un top a confirmé mes craintes : c’est bien le serveur MySQL qui était en cause, prenait beaucoup de mémoire RAM et de ressources processeur. Il y avait donc des requêtes SQL qui avaient besoin d’être optimisées.

J’ai édité le fichier de configuration de MySQL (/etc/mysql/my.cnf sous Linux Debian) pour y activer l’option log-slow-queries en modifiant les trois lignes suivantes :

  1. log_slow_queries = /var/log/mysql/mysql-slow.log
  2. long_query_time = 2
  3. log-queries-not-using-indexes

Je le répète, long_query_time = 2 signifie qu’on doit logger toutes les requêtes qui mettent plus de deux secondes à s’exécuter. Après un redémarrage du serveur (cette option ne peut malheureusement pas être changée à chaud), j’ai attendu la montée en charge suivante pour que MySQL (grâce à long_query_time) enregistre sagement toutes les requêtes mettant plus de 2 secondes à s’exécuter (log_query_time est exprimé en secondes et doit être un nombre entier compris entre 1 et 10), et celles qui n’utilisaient aucun index, dans le fichier /var/log/mysql-slow.log

Voici ce que j’y ai trouvé :

  1. # Query_time: 0  Lock_time: 0  Rows_sent: 5  Rows_examined: 17165
  2. SELECT * FROM chanson LEFT JOIN artiste ON artiste_ID = ID_artiste WHERE artiste_ID = 50 ORDER BY RAND() LIMIT 5;

Quasiment 20.000 lignes examinées (la totalité de la table) pour une requête qui en ramènera seulement 5, c’est beaucoup.

Je me suis connecté à phpMyAdmin, et j’ai utilisé la commande explain, en rajoutant simplement le mot EXPLAIN devant ma requête SQL :

  1. EXPLAIN SELECT *
  2. FROM chanson
  3. LEFT JOIN artiste ON artiste_ID = ID_artiste
  4. WHERE artiste_ID = 50
  5. ORDER BY RAND( )
  6. LIMIT 5;

La commande MySQL EXPLAIN permet de voir, notamment, les clés (index, primary, uniques…) utilisées pour aller chercher les résultats d’une requête, ainsi que le nombre de lignes parcourues.
Voici quel a été le résultat de la commande Explain :
MySQL Explain

J’ai ajouté un “ID_artiste = 50″ dans la clause WHERE, qui n’a rien changé. Explain renvoyait toujours “NULL” dans les Possible keys concernant la table Chanson. Après vérification, en effet, il n’y avait aucun index sur ce champ de la table, pourtant souvent utilisé dans mes clauses WHERE. Un ALTER TABLE `chanson` ADD INDEX(`artiste_ID`) plus tard, la création de l’index sur le champ de la base de données concernée a permis de changer le résultat de l’EXPLAIN sur la même requête SQL :
MySQL Explain
Plus que 76 lignes lues pour renvoyer la réponse, la requête n’apparaitra très certainement plus dans le slow_query_log.

En recommençant l’opération (toujours avec Explain) sur toutes les requêtes qui se trouvaient dans le fichier de log, j’ai trouvé plusieurs points à améliorer pour accroître les performances du serveur MySQL. Finis, les problèmes de montée en charge !

Pour en savoir plus :
Documentation officielle MySQL de la syntaxe de EXPLAIN

]]>
https://www.php-experts.org/bases-de-donnees/mysql/autopsie-et-optimisation-dune-requete-sql-avec-explain-et-log_slow_queries-14/feed 3
Coder un système d’authentification : Apache ET bases de données https://www.php-experts.org/developpement-web/php-developpement-web/coder-un-systeme-dauthentification-apache-et-bases-de-donnees-11 https://www.php-experts.org/developpement-web/php-developpement-web/coder-un-systeme-dauthentification-apache-et-bases-de-donnees-11#comments Wed, 09 Jul 2008 09:00:15 +0000 Didier https://www.php-experts.org/?p=11 Quand on veut gérer un système d’authentification en PHP pour un intranet (qui demande plus de rigueur et de sécurité qu’un site internet), on se retrouve à priori avec deux solutions valables: soit un formulaire relié à une base de données, le classique du Web/frontoffice, soit un fichier htpasswd, le classique du Backoffice, plus sûr mais moins flexible (notamment au niveau de l’ajout d’utilisateur ou de la gestion des droits d’accès). J’ai mis longtemps à me rendre compte qu’on pouvait mixer les deux pour avoir quelque chose de souple et de fiable.

En manipulant les headers Apache en PHP, on peut forcer le serveur à demander une authentification au visiteur, comme avec un .htaccess/htpasswd. Il suffit pour cela d’ajouter :

  1. header(‘WWW-Authenticate: Basic realm="Administration – Accès restreint"’);
  2. header(‘HTTP/1.0 401 Unauthorized’);

Quand on arrive sur la page, une “jolie” boite apparaît :
Exemple de boite de dialogue d\'authentification
C’est en faisant un var_dump($_SERVER) sur l’index du dossier qu’on remarque les deux variables qui vont nous servir : PHP_AUTH_USER et PHP_AUTH_PW. Celles-ci contiennent les valeurs des deux champs de la boîte de dialogue qu’Apache a fait remplir à votre visiteur. En y pluggant un système de login “classique”, qui va chercher une correspondance entre ces données et celles contenues dans une base de données, on se retrouve avec un module de login par headers http, envoyés par php, et couplé à une base de données dans laquelle on peut, notamment, stocker un niveau d’accès pour chaque utilisateur (et utiliser le Bit Bashing…)

]]>
https://www.php-experts.org/developpement-web/php-developpement-web/coder-un-systeme-dauthentification-apache-et-bases-de-donnees-11/feed 2