<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Christophe Le Bot &#187; Bases de données</title>
	<atom:link href="http://blog.christophelebot.fr/category/developper/bases-de-donnees/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.christophelebot.fr</link>
	<description>Pratique de la conception numérique</description>
	<lastBuildDate>Tue, 15 Jun 2010 23:02:43 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Sauvons MySQL !</title>
		<link>http://blog.christophelebot.fr/2010/01/05/sauvons-mysql/</link>
		<comments>http://blog.christophelebot.fr/2010/01/05/sauvons-mysql/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 23:09:08 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Evénements]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Serveurs]]></category>
		<category><![CDATA[Veille économique]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>

		<guid isPermaLink="false">http://blog.christophelebot.fr/?p=612</guid>
		<description><![CDATA[
En janvier 2008, le rachat de MySQL AB par Sun fut un événement majeur et plutôt bien accueilli. Mais l&#8217;ambience était tout autre après le rachat de Sun par Oracle. J&#8217;émettais de fortes réserves sur la survie de MySQL dans le giron de l&#8217;ambitieuse société californienne.
Les craintes se sont confirmées et une grande bataille se [...]]]></description>
			<content:encoded><![CDATA[<div class="asset-frame"><a title="Sauvez MySQL !" href="http://www.helpmysql.org/fr/theissue/customerspaythebill"><img class="alignnone size-full wp-image-626" title="Save MySQL" src="http://blog.christophelebot.fr/wp-content/uploads/2010/01/helpmysql_Banner_320x240_EN.png" alt="Save MySQL" width="320" height="240" /></a></div>
<p>En janvier 2008, le <a title="Sun acquiert MySQL AB" href="/2008/01/17/sun-acquiert-mysql/">rachat de MySQL AB par Sun</a> fut un événement majeur et plutôt bien accueilli. Mais l&#8217;ambience était tout autre après le <a title="Oracle acquiert Sun" href="/2009/04/20/oracle-acquiert-sun/">rachat de Sun par Oracle</a>. J&#8217;émettais de fortes réserves sur la survie de MySQL dans le giron de l&#8217;ambitieuse société californienne.</p>
<p>Les craintes se sont confirmées et une grande bataille se joue en ce moment pour sauver MySQL. <a title="Help saving MySQL" href="http://monty-says.blogspot.com/2009/12/help-saving-mysql.html">Michael &laquo;&nbsp;Monty&nbsp;&raquo; Widenius, le créateur de MySQL, a lui-même tiré la sonnette d&#8217;alarme</a> en décembre et a anticipé les problèmes que vont rencontrer les utilisateurs de MYSQL.</p>
<p>Sans réponses claires et pérennes d&#8217;Oracle, la communauté s&#8217;organise et une pétition a été lancée pour convaincre les pouvoirs publics et les autorités de régulation des marchés d&#8217;étudier le cas de la fusion Oracle-Sun-MySQL. Libre à vous de décider de l&#8217;avenir de MySQL, mais le danger est, à mon avis, bien réel. J&#8217;attends d&#8217;être convaincu du contraire&#8230;</p>
<p>Pour en savoir plus : <a title="Pétition Save MySQL !" href="http://www.helpmysql.org/fr/theissue/customerspaythebill">Save MySQL !</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.christophelebot.fr/2010/01/05/sauvons-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Barcamp PHP toulousain : la synthèse</title>
		<link>http://blog.christophelebot.fr/2009/11/05/barcamp-php-toulousain-la-synthese/</link>
		<comments>http://blog.christophelebot.fr/2009/11/05/barcamp-php-toulousain-la-synthese/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 23:22:29 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Bonnes pratiques]]></category>
		<category><![CDATA[Développement web]]></category>
		<category><![CDATA[Evénements]]></category>
		<category><![CDATA[Génie logiciel]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[Inspiration]]></category>
		<category><![CDATA[Outils du développeur]]></category>
		<category><![CDATA[Programmation avancée]]></category>
		<category><![CDATA[Qualité]]></category>
		<category><![CDATA[Recherche et innovation]]></category>
		<category><![CDATA[Se former]]></category>
		<category><![CDATA[Serveurs]]></category>
		<category><![CDATA[Sécurité]]></category>
		<category><![CDATA[AFUP]]></category>
		<category><![CDATA[Barcamp]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tests]]></category>

		<guid isPermaLink="false">http://blog.christophelebot.fr/?p=570</guid>
		<description><![CDATA[
Jeudi dernier se tenait le Barcamp PHP Cheese &#38; Wine. Même si le vin et le fromage ont été très appréciés, nous n&#8217;étions pas venus (seulement) pour ça. Alors pour les absents qui ont eu tort de l&#8217;être, voici une petite synthèse de cette longue soirée.
Un vrai barcamp
Premier bon point : c&#8217;est un vrai barcamp [...]]]></description>
			<content:encoded><![CDATA[<div class="asset-frame"><img class="alignnone size-medium wp-image-531" title="Bacrcamp PHP Toulouse" src="http://blog.christophelebot.fr/wp-content/uploads/2009/10/barcampPHP01-06629-420x251.jpg" alt="Bacrcamp PHP Toulouse" width="420" height="251" /></div>
<p>Jeudi dernier se tenait le <a title="Barcamp PHP à Toulouse le 29 octobre" href="/2009/10/06/barcamp-php-linagora-toulouse/">Barcamp PHP Cheese &amp; Wine</a>. Même si le vin et le fromage ont été très appréciés, nous n&#8217;étions pas venus (seulement) pour ça. Alors pour les absents qui ont eu tort de l&#8217;être, voici une petite synthèse de cette longue soirée.</p>
<h3>Un vrai barcamp</h3>
<p>Premier bon point : c&#8217;est un vrai barcamp où les participants se présentent et définissent le contenu des ateliers. Tous les barcamps ne respectent pas cette règle de base&#8230; Xavier Gorse, président de l&#8217;<a title="Site officiel de l'AFUP" href="http://www.afup.org/">AFUP</a>, a donc joué le rôle de &laquo;&nbsp;maître de cérémonie&nbsp;&raquo; pour établir le programme d&#8217;après les souhaits de chacun  :</p>
<ul>
<li>PHP et sécurité</li>
<li>PHP 5.3</li>
<li>Déploiement d&#8217;applications PHP</li>
<li>PHP et les bases de données &laquo;&nbsp;NoSQL&nbsp;&raquo;</li>
<li>Outillage PHP</li>
<li>PHP et testing</li>
<li>Frameworks PHP</li>
</ul>
<p>Pour ma part, j&#8217;ai participé aux ateliers :</p>
<ul>
<li>Déploiement d&#8217;applications PHP</li>
<li>PHP et les bases de données &laquo;&nbsp;NoSQL&nbsp;&raquo;</li>
<li>PHP et testing</li>
</ul>
<p>Je limite donc mon article à ces sujets, sachant que d&#8217;autres synthèses ont déjà été publiées :</p>
<ul>
<li><a title="Synthèse du Barcamp PHP toulousain" href="http://www.raphael-rougeron.com/post/2009/11/02/Synth%C3%A8se-du-Barcamp-PHP-toulousain">Synthèse du Barcamp PHP toulousain</a>, par Raphaël Rougeron</li>
<li><a title="Synthèse du Barcamp PHP toulousain" href="http://methylbro.titaxium.org/post/2009/11/04/synthese-du-barcamp-php-toulousain">Synthèse du Barcamp PHP toulousain</a>, par Thomas Gasc</li>
</ul>
<h3>Déploiement d&#8217;applications PHP</h3>
<p>Cet atelier a mis en évidence la <strong>difficulté de déployer des applications web</strong> en général (technologies nombreuses et environnement hétérogène). Tous les outils existants ont été passés en revue, du paquet Linux (.deb) aux outils spécifiques à PHP (<a title="Projet PEAR" href="http://pear.php.net/">PEAR</a>, <a title="Projet Phing" href="http://www.phing.info/">Phing</a>, <a title="Phar sur php.net" href="http://php.net/manual/fr/intro.phar.php">Phar</a>) en passant par des intermédiaires parfois plus adaptés (makefile, <a title="Puppet" href="http://reductivelabs.com/products/puppet/">Puppet</a>, <a title="Capistrano" href="http://www.capify.org/">Capistrano</a>, <a title="Projet Apache Ant" href="http://ant.apache.org/">Ant</a>). Deux groupes de participants étaient clairement représentés, avec des besoins très différents :</p>
<ul>
<li><strong>Déploiement d&#8217;une solution sur un parc important et hétérogène</strong> (cas des éditeurs de solutions, comme <a title="Linagora" href="http://www.linagora.com/">Linagora</a> avec <a title="Site officiel OBM" href="http://pro.obm.org/">OBM</a>)</li>
<li><strong>Déploiement d&#8217;un projet sur-mesure sur un ou quelques serveurs, mais très fréquemment et avec des contraintes d&#8217;intégration de contenus externes</strong> (cas des agences web, avec plusieurs déploiements par jour).</li>
</ul>
<p>Dans le premier cas, la difficulté est d&#8217;identifier la configuration des serveurs cibles et de préparer les paquets d&#8217;installation correspondants (.deb pour chaque distribution Linux, .msi pour chaque version de Windows, etc.), tout en assurant la compatibilité des données sans toujours les connaître (tests de régression).</p>
<p>Dans le second cas, il faut savoir intégrer pendant le déploiement les données du site en exploitation (base de données, templates gérés par un web designer externe, etc.), avec d&#8217;éventuelles transformations (ETL, Extract Transform Load).</p>
<p>J&#8217;ai ajouté qu&#8217;un déploiement ne se limite pas à la livraison de la partie applicative mais doit aussi <strong>savoir traiter la mise à jour des outils liés au projet</strong> (plate-forme de gestion de tickets, extranet, feuille de route, tests, sauvegardes, alertes, etc.).</p>
<p>En dehors de <a title="Projet PEAR" href="http://pear.php.net/">PEAR</a>, trés utilisé et qui est un outil de déploiement à l&#8217;origine, j&#8217;ai une préférence pour <a title="Projet Apache Ant" href="http://ant.apache.org/">Ant</a> + <a title="Projet Phing" href="http://www.phing.info/">Phing</a> et <a title="Capistrano" href="http://www.capify.org/">Capistrano</a>.</p>
<h3>Bases de données &laquo;&nbsp;NoSQL&nbsp;&raquo;</h3>
<p>Là, on entre dans une autre dimension. Les bases &laquo;&nbsp;NoSQL&nbsp;&raquo; sont des <strong>bases de données non relationnelles</strong>. En gros, on ne retrouve pas le schéma habituel &laquo;&nbsp;tables contenant des champs et étant reliées entre elles&nbsp;&raquo;. L&#8217;avantage est d&#8217;<strong>obtenir des performances exceptionnelles sur des entrepôts de données énormes</strong>. Parmi les acteurs majeurs qui développent et utilisent des bases &laquo;&nbsp;NoSQL&nbsp;&raquo;, on peut citer : Google (projet Big Table qui a inspiré le <a title="Projet Apache Cassandra" href="http://incubator.apache.org/cassandra/">projet Cassandra</a>), Facebook ou Linkedin.</p>
<p>Si on revient à la dure réalité d&#8217;un acteur de dimension modeste, on constate que ces technologies émergentes et prometteuses sont encore très spécifiques. Les bases relationnelles ont de beaux jours devant elles. La difficulté est notamment de <strong>réintégrer dans l&#8217;application PHP ce qui fait la force des systèmes SQL</strong> : sélection, jointures, intégrité référentielle, etc. Le volet <em>testing </em>des projets en prend un coup&#8230;</p>
<h3>PHP et testing</h3>
<p>Atelier en petit comité (6 personnes), en concurrence déloyale avec l&#8217;atelier Frameworks qui a fait le plein ! Nous avons tenté de lister les types de tests liés à une application web, en dépassant autant que possible la simple vue du développeur :</p>
<ul>
<li>Tests unitaires (PHP et Javascript)</li>
<li>Tests fonctionnels</li>
<li>Tests d&#8217;IHM (via <a title="Selenium Core" href="http://seleniumhq.org/projects/core/">Selenium Core</a>, <a title="Selenium Remote Control" href="http://seleniumhq.org/projects/remote-control/">Selenium RC</a> et <a title="Selenium IDE" href="http://seleniumhq.org/projects/ide/">Selenium IDE</a>)</li>
<li>Tests de recette</li>
<li>Tests de non régression</li>
<li>Tests de performance</li>
<li>Tests de charge</li>
<li>Tests de conformité (normes, W3C, accessibilité, etc.)</li>
<li>Tests ergonomiques (tri par cartes, paper prototyping, tests utilisateurs, etc.)</li>
<li>A/B testing</li>
</ul>
<p>Les échanges sur nos expériences ont été très instructifs. Nous étions tous d&#8217;accord pour insister sur la définition précise des cas d&#8217;utilisation qui facilite la gestion des tests pendant toute la durée du projet<strong> avec le client</strong>. D&#8217;où une phase de spécifications sérieuse qui conditionne la qualité du travail livré. Certains tests peuvent faire l&#8217;objet de validation contractuelle, comme les wireframes issus de tests ergonomiques qui servent ensuite de feuille de route aux intégrateurs et développeurs.</p>
<p>La difficulté avec les tests, c&#8217;est de savoir placer le curseur pour ne pas s&#8217;y noyer. <strong>Il n&#8217;est pas réaliste d&#8217;appliquer les tests de façon exhaustive</strong>. C&#8217;est un idéal en contradiction avec les budgets et les délais imposés en pratique. Il faut donc savoir réaliser les bons tests, au bon endroit et au bon moment. Par exemple, sur le calcul des prix d&#8217;un panier de site e-commerce, sur l&#8217;intégration des données lors d&#8217;un couplage entre deux systèmes, sur l&#8217;ergonomie d&#8217;une interface riche, etc.</p>
<h3>En résumé</h3>
<p>Une excellente soirée qui a largement dépassée les 5 heures prévues ! L&#8217;accueil de <a title="Linagora" href="http://www.linagora.com/">Linagora </a>et de l&#8217;<a title="Site officiel de l'AFUP" href="http://www.afup.org/">AFUP</a> était parfait, l&#8217;ambiance très sympathique et le niveau des échanges très pointu. Il y a des gens qui savent faire des choses avec PHP en Midi-Pyrénées ! Je pense qu&#8217;on remettra ça sous peu. Prochaine étape : le <a title="Bargento 3" href="http://www.bargento.fr/">Bargento, lundi 9 novembre à Paris</a>. Je serai présent avec l&#8217;équipe de l&#8217;AFUP pour organiser et animer cette journée qui s&#8217;annonce exceptionnelle. Et à la suite, le <a title="Forum PHP 2009" href="http://afup.org/pages/forumphp2009/">Forum PHP 2009</a>, tout aussi exceptionnel. Sur ce coup-là, je déclare forfait. Il faut bien travailler un peu !</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.christophelebot.fr/2009/11/05/barcamp-php-toulousain-la-synthese/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Oracle acquiert Sun</title>
		<link>http://blog.christophelebot.fr/2009/04/20/oracle-acquiert-sun/</link>
		<comments>http://blog.christophelebot.fr/2009/04/20/oracle-acquiert-sun/#comments</comments>
		<pubDate>Mon, 20 Apr 2009 19:29:36 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Développer]]></category>
		<category><![CDATA[Evénements]]></category>
		<category><![CDATA[Exploiter]]></category>
		<category><![CDATA[Savoir]]></category>
		<category><![CDATA[Serveurs]]></category>
		<category><![CDATA[Veille économique]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Open source]]></category>
		<category><![CDATA[Sun]]></category>

		<guid isPermaLink="false">http://blog.christophelebot.fr/?p=504</guid>
		<description><![CDATA[
Le rachat de MySQL par Sun était déjà un événement pour moi l&#8217;an dernier. Alors je ne sais plus quels mots utiliser après le rachat de Sun par Oracle aujourd&#8217;hui&#8230;
Sachant comment finissent les entreprises qui passent entre les mains d&#8217;Oracle, il reste une sacrée incertitude sur certains projets (Java et MySQL pour commencer).
]]></description>
			<content:encoded><![CDATA[<div class="asset-frame"><img class="alignnone size-full wp-image-507" title="Oracle acquiert Sun" src="http://blog.christophelebot.fr/wp-content/uploads/2009/04/oracle-sun.png" alt="Oracle acquiert Sun" width="420" height="180" /></div>
<p>Le rachat de MySQL par Sun était déjà un <a title="Sun acquiert MySQL" href="http://blog.christophelebot.fr/2008/01/17/sun-acquiert-mysql/">événement pour moi</a> l&#8217;an dernier. Alors je ne sais plus quels mots utiliser après le <a title="Site officiel Sun" href="http://www.sun.com/">rachat de Sun par Oracle</a> aujourd&#8217;hui&#8230;</p>
<p>Sachant comment finissent les entreprises qui passent entre les mains d&#8217;Oracle, il reste une sacrée incertitude sur certains projets (Java et MySQL pour commencer).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.christophelebot.fr/2009/04/20/oracle-acquiert-sun/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Piloter et sécuriser ses bases de données avec MySQL Proxy</title>
		<link>http://blog.christophelebot.fr/2007/08/15/mysql-proxy/</link>
		<comments>http://blog.christophelebot.fr/2007/08/15/mysql-proxy/#comments</comments>
		<pubDate>Wed, 15 Aug 2007 10:06:46 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Développer]]></category>
		<category><![CDATA[Exploiter]]></category>
		<category><![CDATA[Outils du développeur]]></category>
		<category><![CDATA[Serveurs]]></category>
		<category><![CDATA[Services en ligne]]></category>
		<category><![CDATA[Sécurité]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.christophelebot.fr/2007/08/15/mysql-proxy/</guid>
		<description><![CDATA[


MySQL Proxy, proposé par MySQL AB, est le genre d&#8217;outils dont le rôle semble si évident qu&#8217;on se demande pourquoi il n&#8217;existait pas avant. Comme tout proxy, il récupère les requêtes destinées à la base de données, effectue des traitements et adresse une requête modifiée au serveur MySQL. Bien entendu, l&#8217;opération inverse est aussi gérée&#160;: [...]]]></description>
			<content:encoded><![CDATA[<div class="asset-frame">
<a href="http://forge.mysql.com/wiki/MySQL_Proxy" title="Site web MySQL Proxy"><img src='http://blog.christophelebot.fr/wp-content/uploads/2007/08/mysql-proxy.jpg' alt='MySQL Proxy' /></a>
</div>
<p><a href="http://forge.mysql.com/wiki/MySQL_Proxy" title="Site web MySQL Proxy">MySQL Proxy</a>, proposé par <a href="http://www.mysql.com/" title="Site web MySQL">MySQL AB</a>, est le genre d&#8217;outils dont le rôle semble si évident qu&#8217;on se demande pourquoi il n&#8217;existait pas avant. Comme tout proxy, il récupère les requêtes destinées à la base de données, effectue des traitements et adresse une requête modifiée au serveur MySQL. Bien entendu, l&#8217;opération inverse est aussi gérée&nbsp;: MySQL Proxy sait récupérer un résultat de requête et le transformer avant de l&#8217;adresser au client initial.</p>
<h3>Fonctionnalités</h3>
<p>Après cette petite présentation, on peut se demander pourquoi on aurait besoin d&#8217;un proxy, puisque les services applicatifs (s&#8217;ils sont correctement architecturés et codés&#8230;) devraient envoyer une requête optimisée au serveur MySQL. Une petite liste des fonctionnalités finit par convaincre de son intérêt&nbsp;:</p>
<ul>
<li>Analyse des requêtes</li>
<li>Filtrage et modification des requêtes et des résultats</li>
<li>Injection de requêtes</li>
<li>Load balancing</li>
<li>Exécution de scripts (basés sur le <a href="http://www.lua.org/" title="Site web Lua">langage LUA</a>)</li>
</ul>
<h3>Cas d&#8217;utilisation</h3>
<p>Dans la pratique, on peut imaginer les situations suivantes&nbsp;:</p>
<ul>
<li>Corriger les erreurs de syntaxe communes.</li>
<li>Garantir le fonctionnement d&#8217;anciennes applications utilisant des requêtes non supportées.</li>
<li>Supprimer du résultat un mot de passe demandé dans la requête.</li>
<li>Récupérer et fusionner avec le résultat des données externes à la base de données (fichiers, flux XML, RPC&#8230;)</li>
<li>Router les requêtes vers un autre serveur MySQL ou vers une autre base de données du même serveur.</li>
<li>Empiler un lot de requêtes et les contrôler avant de mettre à jour les tables.</li>
<li>Dupliquer les requêtes en temps réel sur deux bases différentes.</li>
<li>Exécuter un script shell avant ou après des modifications dans la base de données.</li>
<li>Interdire certains motifs de requêtes.</li>
<li>Verrouiller des tables selon le contexte.</li>
<li>Contrer les injections SQL non désirées.</li>
</ul>
<p>On le voit, les possibilités sont infinies et ne dépendent que des contextes de production et de l&#8217;imagination des développeurs. MySQL Proxy permet surtout d&#8217;éviter d&#8217;intégrer la gestion de l&#8217;exploitation des bases de données MySQL dans les services applicatifs. Voilà enfin une saine séparation du travail du développeur métier et de l&#8217;administrateur MySQL&nbsp;!</p>
<h3>Mise en oeuvre</h3>
<p>MySQL Proxy est encore en version alpha et son fonctionnement n&#8217;est garanti que pour les versions MySQL 5.0.x et ultérieures.</p>
<p>Pour découvrir ses possibilités, O&#8217;Reilly Network propose un didacticiel clair et très fourni&nbsp;: <a href="http://www.oreillynet.com/pub/a/databases/2007/07/12/getting-started-with-mysql-proxy.html" title="Lire l'article">Getting Started with MySQL Proxy</a>.</p>
<p>Source : <a href="http://linuxfr.org/2007/08/09/22813.html" title="Article MySQL Proxy sur Linuxfr.org">Linuxfr.org</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.christophelebot.fr/2007/08/15/mysql-proxy/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>ACID (Atomicity, Consistency, Isolation, Durability)</title>
		<link>http://blog.christophelebot.fr/2006/06/15/acid-atomicity-consistency-isolation-durability/</link>
		<comments>http://blog.christophelebot.fr/2006/06/15/acid-atomicity-consistency-isolation-durability/#comments</comments>
		<pubDate>Thu, 15 Jun 2006 11:48:47 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Bonnes pratiques]]></category>
		<category><![CDATA[Concevoir]]></category>
		<category><![CDATA[Développer]]></category>
		<category><![CDATA[Génie logiciel]]></category>

		<guid isPermaLink="false">http://blog.christophelebot.fr/2006/06/15/acid-atomicity-consistency-isolation-durability/</guid>
		<description><![CDATA[Alors que je suis en pleine période des acronymes de quatre lettres (CRUD et UDOD), je découvre ce matin un bon résumé d&#8217;ACID sur Le Journal du Net.
J&#8217;ajouterais à l&#8217;article de Xavier Borderie que ces quatre attributs d&#8217;une transaction de données (Atomicity, Consistency, Isolation, Durability) ne se limitent pas aux bases de données. Ils sont [...]]]></description>
			<content:encoded><![CDATA[<p>Alors que je suis en pleine période des acronymes de quatre lettres (<a title="CRUD" href="/2006/06/14/crud/">CRUD</a> et <a title="UDOD" href="/2006/06/15/udod-user-documentation-oriented-design/">UDOD</a>), je découvre ce matin <a title="ACID" href="http://developpeur.journaldunet.com/tutoriel/theo/060615-theo-db-acid.shtml">un bon résumé d&#8217;ACID sur Le Journal du Net</a>.</p>
<p>J&#8217;ajouterais à l&#8217;article de Xavier Borderie que ces quatre attributs d&#8217;une transaction de données (Atomicity, Consistency, Isolation, Durability) ne se limitent pas aux bases de données. Ils sont utiles dans bien d&#8217;autres contextes, comme par exemple la gestion d&#8217;un <a title="LDAP sur Wikipedia" href="http://en.wikipedia.org/wiki/Ldap">annaire LDAP</a> ou les transactions entre un repository <a title="Site officiel Subversion" href="http://subversion.tigris.org/">Subversion</a> et ses utilisateurs. Sauf à considérer qu&#8217;il s&#8217;agit là de bases de données au sens large et théorique&#8230;</p>
<p>Par contre, il y a un contexte où ACID mériterait d&#8217;être strictement appliqué, c&#8217;est celui des transactions entre un serveur et un navigateur web&nbsp;! Nous en sommes très loin car le socle technique n&#8217;a pas été prévu pour cela. Par exemple, on ne peut toujours pas savoir quand un utilisateur quitte un site ou une application web, ce qui est gênant quand l&#8217;application web fait des opérations par étapes successives avec confirmation de l&#8217;utilisateur pour chacune d&#8217;elles. Doit-on annuler les étapes précédentes&nbsp;? Si oui, sous quel délai&nbsp;? De plus, laisser une session ouverte sur le serveur représente un risque de sécurité.</p>
<p>On peut simuler la persistance des sessions et des objets par les cookies, mais la fiabilité n&#8217;est pas au rendez-vous (sauf en dérivant le navigateur par des extensions particulières, comme des applets Java). On peut faire un semblant d&#8217;atomicité en plaçant les pages web dans un buffer avant de les servir (pour éviter une validation d&#8217;un formulaire incomplet par exemple). On peut assurer la cohérence en contrôlant rigoureusement les requêtes HTTP. On peut gérer l&#8217;isolation par l&#8217;utilisation de &laquo;&nbsp;sémaphores maison&nbsp;&raquo;. Quant à la durabilité, je ne vois pas comment l&#8217;obtenir&#8230;</p>
<p>Il manque donc un maillon pour simplifier le développement et gérer la robustesse des applications web&nbsp;: si ACID est bien présent entre le serveur web (front office) et les entrepôts de données (SGBD, annuaires, systèmes de fichiers, échanges de données&#8230;), son absence entre le navigateur et le serveur web rend le développement et l&#8217;exploitation difficiles.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.christophelebot.fr/2006/06/15/acid-atomicity-consistency-isolation-durability/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Récupérer le dernier auto-incrément MySQL avec PHP</title>
		<link>http://blog.christophelebot.fr/2006/03/27/recuperer-dernier-auto-increment-mysql-avec-php/</link>
		<comments>http://blog.christophelebot.fr/2006/03/27/recuperer-dernier-auto-increment-mysql-avec-php/#comments</comments>
		<pubDate>Sun, 26 Mar 2006 22:14:37 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Développement web]]></category>
		<category><![CDATA[Développer]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.christophelebot.fr/2006/03/27/recuperer-le-dernier-auto-increment-mysql-avec-php/</guid>
		<description><![CDATA[Quand un script ajoute un enregistrement dans une table MySQL, il est parfois utile d&#8217;en mettre d&#8217;autres à jour. Et pour cela, on peut avoir besoin de récupérer le dernier identifiant d&#8217;auto-increment. La fonction PHP mysql_insert_id() le fera très bien&#8230; sous certaines conditions.
Petit rappel sur les connexions MySQL
Avant de faire l&#8217;opération, voici un petit rappel [...]]]></description>
			<content:encoded><![CDATA[<p>Quand un script ajoute un enregistrement dans une table MySQL, il est parfois utile d&#8217;en mettre d&#8217;autres à jour. Et pour cela, on peut avoir besoin de récupérer le dernier identifiant d&#8217;auto-increment. La fonction PHP <code>mysql_insert_id()</code> le fera très bien&#8230; sous certaines conditions.</p>
<h3>Petit rappel sur les connexions MySQL</h3>
<p>Avant de faire l&#8217;opération, voici un petit rappel du comportement des connexions MySQL ouvertes par PHP.</p>
<p>La plupart du temps, la connexion avec MySQL est établie par la fonction PHP <code>mysql_connect()</code>. Si un deuxième appel est fait avec les mêmes arguments, la première connexion sera à nouveau utilisée. Le paramètre <code>new_link</code> modifie ce comportement et permet à <code>mysql_connect()</code> d&#8217;ouvrir à chaque fois une nouvelle connexion, même si <code>mysql_connect()</code> a été appelée avec les mêmes paramètres.</p>
<p>Lorsque le script utilise une connexion persistante (par la fonction PHP <code>mysql_pconnect()</code>), le comportement est le même, à deux différences (importantes !) près&nbsp;:</p>
<ul>
<li>Lors de la connexion, la fonction essaie de trouver une connexion persistante déjà ouverte, avec le même nom d&#8217;utilisateur et le même mot de passe. Dans ce cas, son identifiant est retourné sans ouvrir de nouvelle connexion.</li>
<li>La connexion au serveur MySQL n&#8217;est pas coupée à la fin du script. Le lien est conservé pour un prochain accès, même si on utilise la fonction <code>mysql_close()</code>.</li>
</ul>
<p>Au passage, notez que les connexions persitantes ne fonctionnent qu&#8217;avec PHP en version module.</p>
<h3>Et l&#8217;auto-increment dans tout ça ?</h3>
<p>L&#8217;auto-increment sera retourné par la fonction PHP <code>mysql_insert_id()</code>, mais il y a des risques de ne pas récupérer celui que vous attendez&nbsp;!</p>
<p><code>mysql_insert_id()</code> retourne le dernier identifiant généré par un champ de type <code>AUTO_INCREMENT</code>, sur la connexion MySQL courante ou sur la connexion spécifiée par le paramètre <code>link_identifier</code>. Mais les surprises sont nombreuses&nbsp;:</p>
<ul>
<li>Si votre colonne <code>AUTO_INCREMENT</code> est une colonne de type <code>BIGINT</code>, la valeur retournée par <code>mysql_insert_id()</code> sera incorrecte. À la place, il faut utiliser la fonction MySQL <code>LAST_INSERT_ID()</code> directement dans une requête SQL.</li>
<li><code>mysql_insert_id()</code> ne fonctionne pas avec un <code>REPLACE</code>.</li>
<li>Si vous utilisez dans votre requête SQL un <code>INSERT IGNORE</code> en précisant un identifiant existant dans la table, l&#8217;enregistrement ne sera pas créé, ce qui est normal puisqu&#8217;il ne peut y avoir deux identifiants égaux. Par contre, <code>mysql_insert_id()</code> vous retournera l&#8217;auto-increment suivant, comme si l&#8217;enregistrement avait été ajouté&nbsp;!</li>
<li>Si vous faites des insertions multiples (par exemple, <code>INSERT INTO table1 (champ1, champs2) SELECT champ1, champs2 FROM table2 WHERE champ1=2</code>), <code>mysql_insert_id()</code> retournera l&#8217;identifiant du premier enregistrement ajouté&nbsp;!</li>
</ul>
<p>J&#8217;arrête là le massacre car il y a bien d&#8217;autres cas. Pour s&#8217;en sortir, il faut privilégier la fonction MySQL <code>LAST_INSERT_ID()</code> (placée directement dans une requête SQL) et verrouiller la table :</p>
<pre name="code" class="php">mysql_query("LOCK TABLES table_exemple WRITE");
mysql_query("SET AUTOCOMMIT = 0");
mysql_query("INSERT INTO table_exemple (champ1, champ2) VALUES  ('toto1','toto2')");
$mysql_id = mysql_query("SELECT LAST_INSERT_ID()");
mysql_query("COMMIT");
mysql_query("UNLOCK TABLES");</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.christophelebot.fr/2006/03/27/recuperer-dernier-auto-increment-mysql-avec-php/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Formatage d&#8217;une durée avec PHP</title>
		<link>http://blog.christophelebot.fr/2006/03/24/formatage-duree-php/</link>
		<comments>http://blog.christophelebot.fr/2006/03/24/formatage-duree-php/#comments</comments>
		<pubDate>Thu, 23 Mar 2006 23:31:52 +0000</pubDate>
		<dc:creator>Christophe</dc:creator>
				<category><![CDATA[Bases de données]]></category>
		<category><![CDATA[Développement web]]></category>
		<category><![CDATA[Développer]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.christophelebot.fr/2006/03/24/formatage-duree-php/</guid>
		<description><![CDATA[PHP regorge de fonctions et de variables pour gérer le temps. Pourtant, quand on souhaite afficher une durée entre deux dates, il n&#8217;y a aucune fonction spécifique&#160;! Voici comment s&#8217;en sortir.
Un peu de mathématiques
Le principe est d&#8217;utiliser un nombre entier, par exemple une durée exprimée en secondes. A vous de convertir la durée avec vos [...]]]></description>
			<content:encoded><![CDATA[<p>PHP regorge de fonctions et de variables pour gérer le temps. Pourtant, quand on souhaite afficher une durée entre deux dates, il n&#8217;y a aucune fonction spécifique&nbsp;! Voici comment s&#8217;en sortir.</p>
<h3>Un peu de mathématiques</h3>
<p>Le principe est d&#8217;utiliser un nombre entier, par exemple une durée exprimée en secondes. A vous de convertir la durée avec vos scripts PHP (la fonction <code>mktime()</code> est toute désignée).</p>
<p>Ensuite, quelques formules mathématiques simples donnent un tableau contenant toutes les valeurs de la durée dans les unités de temps que vous souhaitez utiliser&nbsp;:</p>
<pre name="code" class="php">$duration = 3695;

// Initialisation
$duration = abs($duration);
$converted_duration = array();

// Conversion en semaines
$converted_duration['weeks']['abs'] = floor($duration / (60*60*24*7));
$modulus = $duration % (60*60*24*7);

// Conversion en jours
$converted_duration['days']['abs'] = floor($duration / (60*60*24));
$converted_duration['days']['rel'] = floor($modulus / (60*60*24));
$modulus = $modulus % (60*60*24);

// Conversion en heures
$converted_duration['hours']['abs'] = floor($duration / (60*60));
$converted_duration['hours']['rel'] = floor($modulus / (60*60));
$modulus = $modulus % (60*60);

// Conversion en minutes
$converted_duration['minutes']['abs'] = floor($duration / 60);
$converted_duration['minutes']['rel'] = floor($modulus / 60);
$modulus = $modulus % 60;

// Conversion en secondes
$converted_duration['seconds']['abs'] = $duration;
$converted_duration['seconds']['rel'] = $modulus;

// Affichage
print_r( $converted_duration);</pre>
<p>Ce code affichera le résultat suivant&nbsp;:</p>
<pre name="code" class="php">Array
   (
      [weeks] => Array
         (
            [abs] => 0
         )

      [days] => Array
         (
            [abs] => 0
            [rel] => 0
         )

      [hours] => Array
        (
            [abs] => 1
            [rel] => 1
         )

      [minutes] => Array
         (
            [abs] => 61
            [rel] => 1
         )

      [seconds] => Array
         (
            [abs] => 3695
            [rel] => 35
         )
   )</pre>
<p>Vous obtenez un tableau avec le nombre de semaines, de jours, d&#8217;heures, de minutes et de secondes que vous pouvez ensuite utiliser pour l&#8217;affichage. Pour chaque unité de temps, la cellule <code>[abs]</code> du tableau stocke la durée totale, alors que la cellule <code>[rel]</code> stocke la durée restante (définie par le modulo).</p>
<p>Prendre la valeur absolue de la durée est capitale&nbsp;! En effet, sans <code>abs()</code>, la fonction <code>floor()</code> donnera des résultats faux avec un durée négative. C&#8217;est logique puisqu&#8217;elle retourne toujours l&#8217;entier inférieur d&#8217;un nombre réel. Si la durée vaut +4.4, vous obtenez +4. Si la durée vaut -4.4, vous obtenez -5&nbsp;!</p>
<h3>Et si j&#8217;utilise une base de données&nbsp;?</h3>
<p>Si vos dates à comparer viennent d&#8217;une base de données, la conversion en timestamp peut se faire directement dans la requête SQL. Avec MySQL, les champs de type <code>DATE</code>, <code>DATETIME</code> ou <code>TIME</code> sont convertis par la fonction <code>UNIX_TIMESTAMP()</code>. Au passage, attention à la limite des champs <code>TIME</code> (de &#8216;-838:59:59&#8242; à &#8216;838:59:59&#8242;)&nbsp;!</p>
<p>Si vous utilisez MySQL 5, la fonction <code>TIMESTAMPDIFF()</code> fera tout à votre place&#8230; sauf le formatage en PHP que je vous propose&nbsp;!</p>
<p>En guise de conclusion, consultez les pages PHP et MySQL concernant les fonctions de dates et d&#8217;heures qui vous épargneront des calculs inutiles&nbsp;:</p>
<ul>
<li><a title="PHP - Dates et heures" href="http://fr3.php.net/manual/fr/ref.datetime.php">PHP &#8211; XXII. Dates et heures</a></li>
<li><a title="Fonctions dates et heures MySQL" href="http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html">MySQL &#8211; Fonctions de dates et d&#8217;heures</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.christophelebot.fr/2006/03/24/formatage-duree-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
