<?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>Le blog de SQLpro &#187; bases de données</title>
	<atom:link href="https://blog.developpez.com/sqlpro/pcategory/bases-de-donnees/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/sqlpro</link>
	<description>Le SQL pour SQL Server, PostGreSQL et tous les autres SGBDR</description>
	<lastBuildDate>Thu, 15 Oct 2020 12:59:17 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>Modèle générique vs modèle spécifique</title>
		<link>https://blog.developpez.com/sqlpro/p13183/langage-sql-norme/modele-generique-vs-modele-specifique</link>
		<comments>https://blog.developpez.com/sqlpro/p13183/langage-sql-norme/modele-generique-vs-modele-specifique#comments</comments>
		<pubDate>Fri, 10 Aug 2018 08:04:43 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[bases de données]]></category>
		<category><![CDATA[Langage SQL (norme)]]></category>
		<category><![CDATA[Modélisation des donées]]></category>
		<category><![CDATA[comparaison]]></category>
		<category><![CDATA[enfant]]></category>
		<category><![CDATA[facilité]]></category>
		<category><![CDATA[famille]]></category>
		<category><![CDATA[générique]]></category>
		<category><![CDATA[héritage]]></category>
		<category><![CDATA[modélisation]]></category>
		<category><![CDATA[parent]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[qualité]]></category>
		<category><![CDATA[spécifique]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=842</guid>
		<description><![CDATA[Dans le cadre d&#8217;un héritage de données ayant de multiples enfants aux caractéristiques très diverses, est-il préférable de concevoir un modèle de données générique ou un modèle de données spécifique ? De nombreux jeunes développeurs pensent naïvement qu&#8217;un modèle générique est plus facile&#8230; Mais c&#8217;est souvent une erreur qu&#8217;il faudra payer au prix fort une [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Dans le cadre d&rsquo;un héritage de données ayant de multiples enfants aux caractéristiques très diverses, est-il préférable de concevoir un modèle de données générique ou un modèle de données spécifique ? De nombreux jeunes développeurs pensent naïvement qu&rsquo;un modèle générique est plus facile&#8230; Mais c&rsquo;est souvent une erreur qu&rsquo;il faudra payer au prix fort une fois l&rsquo;application fonctionnelle. Démonstration&#8230;<br />
<span id="more-842"></span><br />
Je suis partit initialement de ce post :</p>
<p><a href="https://www.developpez.net/forums/d1881400/bases-donnees/langage-sql/avis-l-architecture-base-donnees-choix-l-option/" rel="noopener" target="_blank">Avis sur l&rsquo;architecture de ma base de données (choix de l&rsquo;option)</a></p>
<p>La demande étant la suivante :</p>
<p><em>J&rsquo;ai 30 familles de critères. Chaque famille comporte un nombre variable de critères pour un total d&rsquo;environ 600 critères.<br />
Chaque critère appartient à une seule famille de sorte que les 600 sont à répartir dans les 30 familles.<br />
Ma question:<br />
&#8211; devrais-je créer <strong>une table par famille</strong> et insérer dans chaque table les critères qui lui appartiennent; (solution 1)<br />
ou alors:<br />
&#8211; créer <strong>une table contenant les 30 familles et une autre contenant les 600 critères</strong>. Ensuite, créer les relations qui lient chaque famille à ses critères et/ou inversement. (solution 2)</em></p>
<p>et ma réponse :</p>
<p><em>Pour qu&rsquo;une base réponde bien en terme de performances, on doit tout faire pour minimiser les IO.<br />
&#8211; Dans votre solution 1, les performances seront bonne si la plupart des requêtes portent sur plusieurs critères d&rsquo;une même famille<br />
&#8211; Dans votre solution 2, les performances seront bonne si la plupart des requêtes portent sur un seul critère.</em></p>
<p>Cependant un jeune internaute peu avisé, affirmait avec force que :</p>
<p><em>pour moi la solution 2 est la + simple à mettre en place.<br />
et le nombre d&rsquo;enregistrements ne justifie pas la solution 1..<br />
tout dépend de votre SGBD (pas précisé..), mais dans tous les cas, il suffit de mettre des ID numérique pour que les requêtes soient optimisées. Créez vos tables avec des id uniques (sous Oracle on peux utiliser les séquences) et vous aurez des traitements optimisées au mieux&#8230; mais bon, je vous rassure, sous Oracle, même avec des clefs en Varchar, pour 600 enregistrements, y a aucun pb..<br />
si je vois bien, vous aurez donc 3 tables avec les clef suivante :<br />
&#8211; FAMILLE (Pk : ID_FAMILLE)<br />
&#8211; FAMILLE_CRITERE (Pk : ID_FAMILLE, ID_CRITERE)<br />
&#8211; CRITERE (Pk : ID_CRITERE)<br />
Relations :<br />
¤ Famille &#8211;&gt; FAMILLE_CRITERES &lt;&#8212; CRITERE<br />
famille_critere ne contenant que le couple ID_FAMILLE, ID_CRITERE (on parle de table intermédiaire)  </em></p>
<p>Ce à quoi je répondais :</p>
<p><em>La solution 2 est correcte si vous ne requêtez JAMAIS plus d&rsquo;un critère à la fois. Elle est déjà moins performante à l’insertion/la mise à jour des données&#8230;<br />
La solution 2 est imbécile, complexe et peu performantes si vous avez plusieurs critères a rechercher&#8230;<br />
En sus, elle ne permet pas facilement de typer les informations, donc, vous aurez beaucoup de problématique de contrôle de qualité&#8230; et des performances catastrophiques</em></p>
<p><strong>DÉMONSTRATION</strong></p>
<p><strong>Partons d&rsquo;une table d&rsquo;animaux :</strong></p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> T_ANIMAL_ANM<br />
<span style="color: #66cc66;">&#40;</span>ANM_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">INT</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">,</span><br />
&nbsp;ANM_DATA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">CHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">8000</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #993333; font-weight: bold;">GO</span><br />
<br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_ANIMAL_ANM <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Mytilus Edulis'</span><span style="color: #66cc66;">&#41;</span></div></div>
<p><strong></strong><br />
<strong>█ █ █ 1ere solution : une seule table pour toute une même famille :</strong></p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> T_MOLUSQUE_MSQ<br />
<span style="color: #66cc66;">&#40;</span>ANM_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">INT</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #993333; font-weight: bold;">REFERENCES</span> T_ANIMAL_ANM <span style="color: #66cc66;">&#40;</span>ANM_ID<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp;MSQ_CARAPACE &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">32</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp;MSQ_SYMETRIE &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">32</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp;MSQ_COULEUR &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">32</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp;MSQ_DIAMETRE_MM &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FLOAT</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<p><strong></strong><br />
<strong>█ █ █ 2e solution (pour toutes familles), des tables &laquo;&nbsp;génériques&nbsp;&raquo; :</strong></p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> T_CARATERISTIQUE_CRT<br />
<span style="color: #66cc66;">&#40;</span>CRT_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">INT</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">,</span><br />
&nbsp;CRT_LIBELLE &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">256</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> T_VALEUR_VLR<br />
<span style="color: #66cc66;">&#40;</span>ANM_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">INT</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">REFERENCES</span> T_ANIMAL_ANM <span style="color: #66cc66;">&#40;</span>ANM_ID<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp;CRT_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">INT</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">REFERENCES</span> T_CARATERISTIQUE_CRT<span style="color: #66cc66;">&#40;</span>CRT_ID<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp;VLR_VALEUR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">256</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp;<span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span>ANM_ID<span style="color: #66cc66;">,</span> CRT_ID<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<p>Ajoutons les caractéristiques identiques à celle de la solution 1</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_CARATERISTIQUE_CRT <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">111</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Carapace'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_CARATERISTIQUE_CRT <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">222</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Symétrie'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_CARATERISTIQUE_CRT <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">333</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Couleur'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_CARATERISTIQUE_CRT <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">444</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Diamètre mm'</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<p><strong></strong><br />
<strong>█ █ █ Voici maintenant les insertions :</strong></p>
<p><strong>Pour la solution 1 :</strong></p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_MOLUSQUE_MSQ <span style="color: #66cc66;">&#40;</span>ANM_ID<span style="color: #66cc66;">,</span> MSQ_CARAPACE<span style="color: #66cc66;">,</span> MSQ_SYMETRIE<span style="color: #66cc66;">,</span> MSQ_COULEUR<span style="color: #66cc66;">,</span> MSQ_DIAMETRE_MM<span style="color: #66cc66;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">'Creatine'</span><span style="color: #66cc66;">,</span> &nbsp; <span style="color: #ff0000;">'Mono'</span><span style="color: #66cc66;">,</span> &nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">'Bleu'</span><span style="color: #66cc66;">,</span> &nbsp; &nbsp; &nbsp;<span style="color: #ff0000;">'82.5'</span><span style="color: #66cc66;">&#41;</span></div></div>
<p>Notez que nous n&rsquo;avons fait qu&rsquo;<strong>une seule requête</strong> d&rsquo;insertion avec correspondance caractéristique / valeur et typage des données</p>
<p><strong>Pour la solution 2 :</strong></p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_VALEUR_VLR <br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> CRT_ID<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<span style="color: #ff0000;">'Creatine'</span> <span style="color: #993333; font-weight: bold;">FROM</span> T_CARATERISTIQUE_CRT <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;CRT_LIBELLE <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Carapace'</span>;<br />
<br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_VALEUR_VLR <br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> CRT_ID<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<span style="color: #ff0000;">'Mono'</span> &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> T_CARATERISTIQUE_CRT <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;CRT_LIBELLE <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Symétrie'</span>;<br />
<br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_VALEUR_VLR <br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> CRT_ID<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<span style="color: #ff0000;">'Bleu'</span> &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> T_CARATERISTIQUE_CRT <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;CRT_LIBELLE <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Couleur'</span>;<br />
<br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_VALEUR_VLR <br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> CRT_ID<span style="color: #66cc66;">,</span> &nbsp; &nbsp;<span style="color: #ff0000;">'82,5'</span> &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> T_CARATERISTIQUE_CRT <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;CRT_LIBELLE <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Diamètre mm'</span>;</div></div>
<p>Pour stocker les mêmes informations, nous avons fait <strong>4 requêtes</strong> au lieu d&rsquo;une seule&#8230;.</p>
<p><strong>█ Comparons maintenant le coût des 2 solutions au niveau de l&rsquo;insertion :</strong></p>
<p><a href="http://blog.developpez.com/sqlpro/files/2018/08/Requetes-insertion-comparaison-couts.jpg"><img src="http://blog.developpez.com/sqlpro/files/2018/08/Requetes-insertion-comparaison-couts.jpg" alt="Comparaison des plans de requêtes pour l&#039;insertion" width="1190" height="897" class="alignnone size-full wp-image-857" /></a></p>
<p>Y&rsquo;a pas à tortiller 4 requêtes coutant deux fois plus cher qu&rsquo;une seule et unique requête cela est donc <strong>8 fois plus couteux</strong>&#8230;</p>
<p><strong>█ █ █ Voyons maintenant la facilité de requêtage :</strong></p>
<p>interrogation multicritères ET avec solution 1</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_ANIMAL_ANM <span style="color: #993333; font-weight: bold;">AS</span> A<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> T_MOLUSQUE_MSQ <span style="color: #993333; font-weight: bold;">AS</span> M<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ON</span> A<span style="color: #66cc66;">.</span>ANM_ID <span style="color: #66cc66;">=</span> M<span style="color: #66cc66;">.</span>ANM_ID<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;MSQ_CARAPACE <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Creatine'</span><br />
&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> &nbsp;MSQ_SYMETRIE <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Mono'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Double'</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> &nbsp;MSQ_COULEUR <span style="color: #993333; font-weight: bold;">LIKE</span> <span style="color: #ff0000;">'Bleu%'</span> <span style="color: #808080; font-style: italic;">--&gt; peut être Bleue, Bleu-marine...</span><br />
&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> &nbsp;MSQ_DIAMETRE_MM <span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #cc66cc;">75</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #cc66cc;">92</span>;</div></div>
<p>la requête fait <strong>8 lignes et 1 jointure</strong>. Elle en fera une de plus pour chaque critère supplémentaire avec juste quelques chose à rajouter à la clause WHERE&#8230;</p>
<p>interrogation multicritères ET avec solution 2</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_ANIMAL_ANM <span style="color: #993333; font-weight: bold;">AS</span> A<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> T_VALEUR_VLR <span style="color: #993333; font-weight: bold;">AS</span> V1 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ON</span> A<span style="color: #66cc66;">.</span>ANM_ID <span style="color: #66cc66;">=</span> V1<span style="color: #66cc66;">.</span>ANM_ID<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> T_CARATERISTIQUE_CRT <span style="color: #993333; font-weight: bold;">AS</span> C1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ON</span> V1<span style="color: #66cc66;">.</span>CRT_ID <span style="color: #66cc66;">=</span> C1<span style="color: #66cc66;">.</span>CRT_ID<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> T_VALEUR_VLR <span style="color: #993333; font-weight: bold;">AS</span> V2 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ON</span> A<span style="color: #66cc66;">.</span>ANM_ID <span style="color: #66cc66;">=</span> V2<span style="color: #66cc66;">.</span>ANM_ID<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> T_CARATERISTIQUE_CRT <span style="color: #993333; font-weight: bold;">AS</span> C2<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ON</span> V2<span style="color: #66cc66;">.</span>CRT_ID <span style="color: #66cc66;">=</span> C2<span style="color: #66cc66;">.</span>CRT_ID<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> T_VALEUR_VLR <span style="color: #993333; font-weight: bold;">AS</span> V3 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ON</span> A<span style="color: #66cc66;">.</span>ANM_ID <span style="color: #66cc66;">=</span> V3<span style="color: #66cc66;">.</span>ANM_ID<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> T_CARATERISTIQUE_CRT <span style="color: #993333; font-weight: bold;">AS</span> C3<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ON</span> V3<span style="color: #66cc66;">.</span>CRT_ID <span style="color: #66cc66;">=</span> C3<span style="color: #66cc66;">.</span>CRT_ID<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> T_VALEUR_VLR <span style="color: #993333; font-weight: bold;">AS</span> V4 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ON</span> A<span style="color: #66cc66;">.</span>ANM_ID <span style="color: #66cc66;">=</span> V4<span style="color: #66cc66;">.</span>ANM_ID<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">JOIN</span> T_CARATERISTIQUE_CRT <span style="color: #993333; font-weight: bold;">AS</span> C4<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">ON</span> V4<span style="color: #66cc66;">.</span>CRT_ID <span style="color: #66cc66;">=</span> C4<span style="color: #66cc66;">.</span>CRT_ID<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;C1<span style="color: #66cc66;">.</span>CRT_LIBELLE <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Carapace'</span><br />
&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> &nbsp;V1<span style="color: #66cc66;">.</span>VLR_VALEUR <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Creatine'</span> <br />
&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> &nbsp;C2<span style="color: #66cc66;">.</span>CRT_LIBELLE <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Symétrie'</span><br />
&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> &nbsp;V2<span style="color: #66cc66;">.</span>VLR_VALEUR <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Mono'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Double'</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> &nbsp;C3<span style="color: #66cc66;">.</span>CRT_LIBELLE <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Couleur'</span><br />
&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> &nbsp;V3<span style="color: #66cc66;">.</span>VLR_VALEUR <span style="color: #993333; font-weight: bold;">LIKE</span> <span style="color: #ff0000;">'Bleu%'</span><br />
&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> &nbsp;C4<span style="color: #66cc66;">.</span>CRT_LIBELLE <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Diamètre mm'</span><br />
&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> &nbsp;V4<span style="color: #66cc66;">.</span>VLR_VALEUR <span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #ff0000;">'75'</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #ff0000;">'92'</span></div></div>
<p>La requête fait <strong>26 lignes avec 8 jointures</strong>&#8230; Il faudra rajouter 6 lignes à chaque critère supplémentaire, dont 4 dans la clause FROM et 2 dans le WHERE, et encore, on ne sait pas dans la clause SELECT à quelle caractéristique se réfère chacune des valeurs&#8230; Il faudrait aussi customiser la clause SELECT&#8230;</p>
<p>Y&rsquo;a pas à tortiller la solution 1 est bien plus simple en matière d’écriture&#8230;</p>
<p><strong>█ Quelles sont les performances des requêtes de recherches des deux solutions ?</strong></p>
<p><a href="http://blog.developpez.com/sqlpro/files/2018/08/Requetes-selection-comparaison-couts.jpg"><img src="http://blog.developpez.com/sqlpro/files/2018/08/Requetes-selection-comparaison-couts.jpg" alt="Comparaison des plans de requêtes pour l&#039;extraction" width="2251" height="389" class="alignnone size-full wp-image-859" /></a></p>
<p><strong>Évidemment la première solution est 4,5 fois moins couteuse&#8230;</strong></p>
<p>Mais il y a pire&#8230; J&rsquo;ai du mettre des chiffres en chaine de caractères pour le diamètre (AND  V4.VLR_VALEUR BETWEEN &rsquo;75&rsquo; AND &rsquo;92&rsquo;). Si je tente de les typer en entier ou réel (AND  V4.VLR_VALEUR BETWEEN 75 AND 92), cela provoque une erreur d&rsquo;exécution (SQL Server) :<br />
<em>Msg*245, Niveau*16, État*1, Ligne*75<br />
Échec de la conversion de la valeur varchar &lsquo;Creatine&rsquo; en type de données int.</em><br />
Logique car pour effectuer une comparaison avec une valeur numérique, il faut convertir la colonne en numérique, mais comme il y a autres chose que de purs nombres (chaines de caractères) cela se passe mal.<br />
Bref certaines requêtes seront impossible à faire !</p>
<p>Plus catastrophique encore&#8230; mettre des index ne servira quasiment à rien ! En effet un index sur une chaine de caractères n’ordonne pas les valeurs de la même façon que s&rsquo;il s&rsquo;agissait de nombre&#8230;</p>
<p>En sus rien n&rsquo;interdira à quelqu’un de saisir 8,2 au lieu de 8.2 (une virgule au lieu d&rsquo;une point) comme diamètre, dans ce modèle inepte, alors qu&rsquo;avec le bon modèle les types sont respectés&#8230;. Si tel était le cas, la valeur ne pourra pas être retrouvée !!! Il existe bien évidemment une solution pour contourner, un tout petit peu, ce modèle pourri, pour le typage. Il consiste à rajouter autant de tables de valeurs que de type&#8230; Mais il n&rsquo;est pas possible de rajouter des contraintes spécifique à chaque type (par exemple vérifier qu&rsquo;une pourcentage est bien entre 0 et 100 &#8211; notion de domaine SQL), ni, bien entendu, de rajouter des contraintes multicritères (une valeur dépendant d&rsquo;une autre) comme c&rsquo;est le cas par exemple de la chronologie des temporels de type &laquo;&nbsp;début&nbsp;&raquo; et &laquo;&nbsp;fin&nbsp;&raquo;.<br />
Et dans tous les cas, les requêtes seront encore plus complexes à élaborer et les performances encore plus lamentables&#8230;</p>
<p><strong>En guise de conclusion</strong></p>
<p>Nous vous avons démontré les performances lamentable et la complexité horrifiante d&rsquo;un tel modèle&#8230;.</p>
<li>Complexité d&rsquo;insertion des données</li>
<li>Mauvaise performances à l&rsquo;insertion des données</li>
<li>Complexité d&rsquo;écriture des recherches</li>
<li>Mauvaise performances pour la recherches de données</li>
<li>Impossibilité de typer finement (notion de domaine)</li>
<li>Impossibilité de placer des contraintes multicritères</li>
<li>Difficultés pour l&rsquo;indexation</li>
<p><strong></strong><br />
<strong></strong></p>
<p>Mais comment se fait-il que des internautes osent affirmer de pareilles stupidités ?</p>
<p>Il est amusant de voir que certains développeur incultes affirment n&rsquo;importe quoi, par ignorance, ou par bêtise, ne prenant même pas la peine de tester ce qu&rsquo;ils disent&#8230; Ensuite ces mêmes développeurs, sans aucune expérience, iront vous raconter que les SGBDR c&rsquo;est pas performant&#8230; Ils vous vendrons alors du NoSQL, ce qui, dans beaucoup de cas, sera pire encore !</p>
<p>Comme disent les américains : &laquo;&nbsp;garbage in, garbage out&nbsp;&raquo; qui peut se traduire si tu fais de la merde en entrée, tu auras de la merde en sortie ! Autrement dit, si le modèle de données est inepte, la qualité des données sera pourrie et les performances lamentables&#8230;</p>
<p><strong>Décortiquons d&rsquo;ailleurs les affirmations de l&rsquo;internate que nous avons cité :</strong><br />
&laquo;&nbsp;<em>tout dépend de votre SGBD (pas précisé..), mais dans tous les cas, il suffit de mettre des ID numérique pour que les requêtes soient optimisées. Créez vos tables avec des id uniques (sous Oracle on peux utiliser les séquences) et vous aurez des traitements optimisées au mieux&#8230; mais bon, je vous rassure, sous Oracle, même avec des clefs en Varchar, pour 600 enregistrements, y a aucun pb..</em>&nbsp;&raquo;</p>
<p><strong>Première affirmation stupide</strong> : &laquo;&nbsp;<em>tout dépend de votre SGBD (pas précisé..)</em>&nbsp;&raquo;<br />
Comme nous sommes dans un forum sur les SGBDR, sachez cher monsieur, que tout les SGBDR fonctionnent de la même façon. Certains allant plus vite que d&rsquo;autre (une Ferrari va généralement plus vite qu&rsquo;une Peugeot), certains avec plus de qualité que d&rsquo;autres (une Rolls-Royce est généralement de meilleure qualité qu&rsquo;une Dacia).</p>
<p><strong>Seconde affirmation stupide</strong> : &laquo;&nbsp;<em>il suffit de mettre des ID numérique pour que les requêtes soient optimisées</em>&nbsp;&raquo;<br />
Si c&rsquo;était le cas alors, pas besoin d&rsquo;index ni de contraintes&#8230; On se demande donc pourquoi les éditeurs de SGBDR font de tels effort en R&amp;D pour trouver de nouvelles formes d&rsquo;index toujours plus performant&#8230;  Et la plupart des informaticiens ignorent que les contraintes permettent de mieux optimiser les plans de requête&#8230; Hélas ceci est très rarement enseigné par les professeurs des universités et encore moins ceux des écoles d&rsquo;ingénieurs&#8230; (je le sais pertinemment puisque j&rsquo;en étais un&#8230;).</p>
<p><strong>Troisième affirmation stupide</strong> : &laquo;&nbsp;<em>mais bon, je vous rassure, sous Oracle, même avec des clefs en Varchar</em>&nbsp;&raquo;<br />
Et bien, non, plus une clef est longue en nombre d&rsquo;octets, plus ses performances décroissent. Pour avoir la même longueur qu&rsquo;un entier auto incrémenté il faudrait se limiter à 4 caractères&#8230; En sus certaines phénomènes apparaissent avec des clefs non numériques et en particulier pour des clefs littérales :
<li>distribution peu aléatoire (parce que concentrées sur les 26 lettres et 10 chiffres parmi les 256 caractères disponibles) induisant des statistiques d&rsquo;optimisation mal réparties (histogrammes erratiques)</li>
<li>extra-overhead lié à la gestion de la collation (sensibilité ou non à la casse, aux accents&#8230;)</li>
<li>façon de stocker physiquement les VARCHAR induisant des octets suplementaires et de la fragmentaion en cas d&rsquo;UPDATE</li>
<p><strong></strong><br />
<strong></strong></p>
<p><strong>Quatrième affirmation stupide</strong> : &laquo;&nbsp;<em>sous Oracle, même avec des clefs en Varchar, pour 600 enregistrements, y a aucun pb..</em>&nbsp;&raquo;<br />
Nous avons déjà dit précédemment que les clef littérales (VARCHAR) étaient une plaie&#8230; Mais ce qui ne va pas dans cette phrase est le terme &laquo;&nbsp;<strong>enregistrement</strong>&laquo;&nbsp;&#8230; Cet internaute sait-il au moins que les SGBDR ne travaillent pas avec des &laquo;&nbsp;enregistrement&nbsp;&raquo; propre aux bases de données de type &laquo;&nbsp;fichier&nbsp;&raquo; comme c&rsquo;était las cas dans les années 50 à 70 ? Les SGBDR structurent les lignes des tables dans des pages qui sont modifiées en mémoire et non pas directement sur le disque (notion physique d&rsquo;enregistrement). Les pages étant physiquement écrites de temps à autres quand il y en a suffisamment à écrire par un processus asynchrone travaillant en tâche de fond.</p>
<p>Bref voici q&rsquo;un internaute ne connaissant ni la modélisation des données ni les technologies des SGDB, vient donner des conseils stupides hélas parfois repris dans certaines applications&#8230;.</p>
<p><strong></strong><br />
<strong></strong></p>
<p><strong>CQFD</strong></p>
<p><strong></strong><br />
<strong></strong></p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>
<p>L&rsquo;entreprise <a href="http://www.sqlspot.com">SQL Spot</a><br />
<strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a></p>
<p><img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL
Server" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Cosmos DB, la base NoSQL à tout faire !</title>
		<link>https://blog.developpez.com/sqlpro/p13182/bases-de-donnees/cosmos-db-la-base-nosql-a-tout-faire</link>
		<comments>https://blog.developpez.com/sqlpro/p13182/bases-de-donnees/cosmos-db-la-base-nosql-a-tout-faire#comments</comments>
		<pubDate>Mon, 06 Aug 2018 16:19:14 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[bases de données]]></category>
		<category><![CDATA[Amazon DynamoDB]]></category>
		<category><![CDATA[Cassandra]]></category>
		<category><![CDATA[Cosmos DB]]></category>
		<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[Document Stores]]></category>
		<category><![CDATA[Google Big Table]]></category>
		<category><![CDATA[Google Cloud]]></category>
		<category><![CDATA[Graph Database]]></category>
		<category><![CDATA[HBase]]></category>
		<category><![CDATA[Key-Value]]></category>
		<category><![CDATA[MarkLogic]]></category>
		<category><![CDATA[Memcached]]></category>
		<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[Neo4J]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[Oracle Berkely DB]]></category>
		<category><![CDATA[OrientDB]]></category>
		<category><![CDATA[Redis]]></category>
		<category><![CDATA[Wide Column]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=830</guid>
		<description><![CDATA[Vous en rêviez ? Cosmos DB l&#8217;a fait ! Une seul base de données, permettant à la fois et dans un même espace de stockage de combiner les différentes technologies des bases de données NoSQL&#8230; &#171;&#160;Wide Column&#160;&#187;, &#171;&#160;Graph Database&#160;&#187;, &#171;&#160;Key-Value&#160;&#187; et &#171;&#160;Document Stores&#160;&#187;, toutes ces technologies sont disponible dans une seule et même base de [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Vous en rêviez ? Cosmos DB l&rsquo;a fait ! Une seul base de données, permettant à la fois et dans un même espace de stockage de combiner les différentes technologies des bases de données NoSQL&#8230; &laquo;&nbsp;Wide Column&nbsp;&raquo;, &laquo;&nbsp;Graph Database&nbsp;&raquo;, &laquo;&nbsp;Key-Value&nbsp;&raquo; et &laquo;&nbsp;Document Stores&nbsp;&raquo;, toutes ces technologies sont disponible dans une seule et même base de données de nom Cosmos DB&#8230;<br />
<span id="more-830"></span><br />
Là ou certaines clients doivent jongler avec plusieurs SGBD pour satisfaire différentes facettes fonctionnelles, Cosmos DB fait la synthèses des plus importantes technologies utilisées de manière combinées dans un seul et même produit.</p>
<p>Je me suis amusé à comparer, via le célèbre site db-engines.com qui publie des résultats de collecte de données statistiques d&rsquo;utilisation, les différents graphes de popularité des produits concurrents de Cosmos DB et n&rsquo;ai retenu que les SGBD qui lui était encore supérieur&#8230; Force est de constater la progression fulgurante de Cosmos DB qui, en quelques mois à dépassé OrientDB, Oracle Berkely DB, CouchDB, Google Cloud, MarkLogic, Google Big Table&#8230;<br />
Et Cosmos DB talonne Cassandra, HBase, Neo4J, MongoDB, Memcached, Amazon DynamoDB et Redis.</p>
<p><strong>1 &#8211; Graphe de popularité Key-value stores</strong></p>
<p><a href="http://blog.developpez.com/sqlpro/files/2018/08/MS-Azure-Cosmos-DB-Key-Value-Stores-ranking-2018-08.jpg"><img src="http://blog.developpez.com/sqlpro/files/2018/08/MS-Azure-Cosmos-DB-Key-Value-Stores-ranking-2018-08.jpg" alt="MS Azure Cosmos DB Key-Value Stores ranking 2018-08" width="985" height="531" class="alignnone size-full wp-image-831" /></a></p>
<p>Cosmos DB progresse de 29 fois en 4 ans alors que Redis (leader) n&rsquo;a fais que 4,6 sur la même période !</p>
<p><strong>2 &#8211; Graphe de popularité Wide Columns stores</strong></p>
<p><a href="http://blog.developpez.com/sqlpro/files/2018/08/MS-Azure-Cosmos-DB-Wide-Column-Stores-ranking-2018-08.jpg"><img src="http://blog.developpez.com/sqlpro/files/2018/08/MS-Azure-Cosmos-DB-Wide-Column-Stores-ranking-2018-08.jpg" alt="MS Azure Cosmos DB Wide Column Stores ranking 2018-08" width="969" height="516" class="alignnone size-full wp-image-835" /></a></p>
<p>Cosmos DB progresse de 29 fois en 4 ans alors que Cassandra (leader) n&rsquo;a fais que 1,4 sur la même période !</p>
<p><strong>3 &#8211; Graphe de popularité Graph DBMS</strong></p>
<p><a href="http://blog.developpez.com/sqlpro/files/2018/08/MS-Azure-Cosmos-DB-Graph-DBMS-ranking-2018-08.jpg"><img src="http://blog.developpez.com/sqlpro/files/2018/08/MS-Azure-Cosmos-DB-Graph-DBMS-ranking-2018-08.jpg" alt="MS Azure Cosmos DB Graph DBMS ranking 2018-08" width="980" height="526" class="alignnone size-full wp-image-836" /></a></p>
<p>Cosmos DB progresse de 29 fois en 4 ans alors que Neo4j (leader) n&rsquo;a fais que 1,7 sur la même période !</p>
<p><strong>4 &#8211; Graphe de popularité Document Stores</strong></p>
<p><a href="http://blog.developpez.com/sqlpro/files/2018/08/MS-Azure-Cosmos-DB-Document-Stores-ranking-2018-08.jpg"><img src="http://blog.developpez.com/sqlpro/files/2018/08/MS-Azure-Cosmos-DB-Document-Stores-ranking-2018-08.jpg" alt="MS Azure Cosmos DB Document Stores ranking 2018-08" width="980" height="526" class="alignnone size-full wp-image-837" /></a></p>
<p>Cosmos DB progresse de 29 fois en 4 ans alors que MongoDB (leader) n&rsquo;a fais que 1,46 sur la même période !</p>
<p>Allez, je fais un pari&#8230; Avant 2 ans, Cosmos DB sera au pire, la seconde base en popularité dans chacune de ces 4 catégories avec comme unique &laquo;&nbsp;sparring partner&nbsp;&raquo; :</p>
<li>Redis pour la partie Key-Value</li>
<li>MongoDB pour la partie Document Stores</li>
<li>Neo4J pour la partie &laquo;&nbsp;graph database&nbsp;&raquo; (et là je pense que Cosmos DB va le doubler)</li>
<li>Cassandra pour la partie &laquo;&nbsp;Wide Column&nbsp;&raquo;</li>
<p>Je parie aussi pour la disparition, à plus ou moins long terme, de produits comme OrientDB, CouchDB et MarkLogic&#8230; </p>
<p>Donc rendez vous début août 2020&#8230;</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>
<p>L&rsquo;entreprise <a href="http://www.sqlspot.com">SQL Spot</a><br />
<strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a></p>
<p><img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL
Server" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Qui est leader dans les bases de données en 2016 ?</title>
		<link>https://blog.developpez.com/sqlpro/p13115/ms-sql-server/qui-est-leader-dans-les-bases-de-donnees-en-2016</link>
		<comments>https://blog.developpez.com/sqlpro/p13115/ms-sql-server/qui-est-leader-dans-les-bases-de-donnees-en-2016#comments</comments>
		<pubDate>Thu, 27 Oct 2016 14:43:33 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[bases de données]]></category>
		<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[SQL Server 2000]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[SQL Server 2012]]></category>
		<category><![CDATA[SQL Server 2014]]></category>
		<category><![CDATA[SQL Server 2016]]></category>
		<category><![CDATA[étude]]></category>
		<category><![CDATA[Gartner]]></category>
		<category><![CDATA[leader]]></category>
		<category><![CDATA[SGBD]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=675</guid>
		<description><![CDATA[Selon l&#8217;étude 2016 du groupe Gartner au sujet des bases de données opérationnelles d&#8217;entreprise (OPDBMS), Microsoft est le n°1 sur les deux axes de mesure : facilité d&#8217;utilisation et visionnaire. Microsoft détient l&#8217;un des systèmes de bases de données relationnelles les mieux conçu, les plus utilisés et le plus fiable avec SQL Server, incorporant un [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Selon l&rsquo;<a href="https://www.gartner.com/doc/reprints?id=1-3JD7HF0&amp;ct=161005&amp;st=sb" title="Magic Quadrant for Operational Database Management Systems 2016" target="_blank">étude 2016 du groupe Gartner au sujet des bases de données opérationnelles d&rsquo;entreprise (OPDBMS)</a>, Microsoft est le n°1 sur les deux axes de mesure : facilité d&rsquo;utilisation et visionnaire.</p>
<div id="attachment_677" style="width: 635px" class="wp-caption alignnone"><a href="http://blog.developpez.com/sqlpro/files/2016/10/Gartner-Magic-Quadrant_SGBD_2016.png"><img src="http://blog.developpez.com/sqlpro/files/2016/10/Gartner-Magic-Quadrant_SGBD_2016-1024x1024.png" alt="Source : Gartner - Magic Quadrant for Operational Database Management Systems 2016" width="625" height="625" class="size-large wp-image-677" /></a><p class="wp-caption-text">Source : Gartner &#8211; Magic Quadrant for Operational Database Management Systems 2016</p></div>
<p>Microsoft détient l&rsquo;un des systèmes de bases de données relationnelles les mieux conçu, les plus utilisés et le plus fiable avec <a href="https://www.microsoft.com/fr-fr/server-cloud/products/sql-server/" target="_blank">SQL Server</a>, incorporant un moteur <a href="https://msdn.microsoft.com/fr-fr/library/dn133186.aspx" title="SQL Server 2016 in memory" target="_blank">&laquo;&nbsp;in memory&nbsp;&raquo;</a> (IMDBMS).<br />
Mais il se trouve que Microsoft est aussi le numéro deux du cloud derrière Amazon (<a href="https://azure.microsoft.com/fr-fr/services/sql-database/" title="Azure Database, la solution &quot;cloud&quot; de SQL Server" target="_blank">Azure SQL Database</a>).<br />
Il offre aussi différentes technologies complémentaire de type NoSQL avec <a href="https://azure.microsoft.com/fr-fr/services/documentdb/" title="NoSQL avec Azure DocumentDB" target="_blank">Azure DocumentDB</a> (un SGBD de type &laquo;&nbsp;document&nbsp;&raquo;) et <a href="https://azure.microsoft.com/fr-fr/documentation/articles/storage-table-design-guide/" title="Base de données NoSQL sous forme de paires clé/valeur avec Azure Table" target="_blank">Azure Tables</a> (un SGBDR de type paire clef/valeur).<br />
Très présent dans le cloud, y compris de manière hybride (une base SQL Serveur locale peut avoir une partie de ses données dans le cloud via le concept de &laquo;&nbsp;<a href="https://msdn.microsoft.com/fr-fr/library/dn935011.aspx" title="SQL Server : concept de &quot;stretch tables&quot;" target="_blank">stretch tables</a>&laquo;&nbsp;), Microsoft offre aussi de nombreuses possibilité analytiques ou mobile.</p>
<p>Pour la troisième année consécutive Mictrosoft est numéro 2 en part de marché sur le plan financier, derrière Oracle dont le Gartner Group a remonté comme point négatif de l&rsquo;étude, les problèmes de coûts, de complexité de licences et noté un rapport qualité prix jugé négatif par les clients.</p>
<p>Mais ce qui fait la force de Microsoft depuis toujours, et celle en particulier de ses solutions de bases de données, c&rsquo;est la facilité d&rsquo;utilisation (l&rsquo;un des meilleurs scores de l&rsquo;étude) et de migration de version (80% des clients ont trouvés que la migration des bases était plus facile que prévue ou autant que prévu)&#8230;</p>
<p>Les seuls problèmes pointés du doigt de manière négatives par le Gartner Group sont exclusivement celles liées au marketing, canaux de vente et distribution des solutions Microsoft ou l&rsquo;éditeur reste encore perçut par certains comme un acteurs pour de petites solutions&#8230;<br />
Finalement aucune critique technique ni financière ne vient ternir l&rsquo;image d&rsquo;excellence de Microsoft dans le domaines des bases de données d&rsquo;entreprise ce qui tend à prouver que ce classement de leader est largement mérité !</p>
<p>***</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>
<p>L&rsquo;entreprise <a href="http://www.sqlspot.com">SQL Spot</a><br />
<strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a></p>
<p><img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL
Server" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Oracle vs SQL Server : les options payantes qui font la différence&#8230;</title>
		<link>https://blog.developpez.com/sqlpro/p13001/ms-sql-server/oracle-vs-sql-server-les-options-payantes-qui-font-la-difference</link>
		<comments>https://blog.developpez.com/sqlpro/p13001/ms-sql-server/oracle-vs-sql-server-les-options-payantes-qui-font-la-difference#comments</comments>
		<pubDate>Fri, 26 Feb 2016 09:06:50 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[comparaison]]></category>
		<category><![CDATA[fiabilité]]></category>
		<category><![CDATA[fonctionnalité]]></category>
		<category><![CDATA[Option]]></category>
		<category><![CDATA[prix]]></category>
		<category><![CDATA[securité]]></category>
		<category><![CDATA[SQL server]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=644</guid>
		<description><![CDATA[Le monde des utilisateurs de bases de données d&#8217;Oracle commence à se faire du soucis, car la firme ayant besoin d&#8217;argent (le cours de son action baisse inexorablement depuis de nombreux mois) elle cherche par tous les moyens à racler les fonds de tiroir auprès de ses clients. L&#8217;une de ses stratégies consiste à jouer [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Le monde des utilisateurs de bases de données d&rsquo;Oracle commence à se faire du soucis, car la firme ayant besoin d&rsquo;argent (le cours de son action baisse inexorablement depuis de nombreux mois) elle cherche par tous les moyens à racler les fonds de tiroir auprès de ses clients. L&rsquo;une de ses stratégies consiste à jouer sur les options payantes&#8230; Or il se trouve que chez SQL Server le concept d&rsquo;option payantes n&rsquo;existe pas&#8230; Cet article fait le point sur la pratique agressive d&rsquo;Oracle et compare les tarifs appliqués à Oracle à son principal adversaire, SQL Server de Microsoft.<br />
<span id="more-644"></span><br />
<strong>1 &#8211; Le problème</strong><br />
Dans un article de <a href="http://uk.businessinsider.com/oracle-customer-explains-audit-threats-2015-9?r=US&amp;IR=T" title="'I felt like we were being extorted': Customer says Oracle tried to strong-arm him into a cloud sale" target="_blank">&laquo;&nbsp;Business Insider&nbsp;&raquo; </a>, un client se plaignait qu&rsquo;Oracle menaçait de lui faire payer des sommes exorbitantes sauf s&rsquo;il se décidait a aller dans le cloud d&rsquo;Oracle. Pour arriver à faire cracher un volume exorbitant de licences, Oracle utilise une technique particulièrement tordue qui consiste à faire payer de nombreuses options, même si elles n&rsquo;ont jamais été utilisées en production&#8230;<br />
Explication :<br />
La base de données Oracle est dotée de nombreuses options, autrefois toutes payantes. Au fil du temps et des versions, certaines options sont devenues des fonctionnalités gratuites, sans que développeurs ni dba ne sachent vraiment lesquelles le sont et, celles qui ne le sont pas. Dans la pratique certains utilisateurs activent soit volontairement pour test, soit par inadvertance, des fonctionnalités dont quelques unes sont payantes. Malheureusement ceci est tracé et l&rsquo;activation d&rsquo;une telle fonctionnalité ouvre immédiatement droit au paiement supplémentaire même si on ne l&rsquo;utilise pas, Oracle arguant qu&rsquo;il ne lui est pas possible rétrospectivement de savoir si la fonctionnalité a été réellement utilisée, simplement testée voir même totalement inutilisée. De plus, au moment de l&rsquo;activation d&rsquo;une fonctionnalité payante, aucun message préventif n&rsquo;indique que l&rsquo;option fera l&rsquo;objet d&rsquo;une licence complémentaire ouvrant droit à subsides au profit d&rsquo;Oracle.<br />
Une fois le temps de l&rsquo;audit venu, Oracle n&rsquo;a plus qu&rsquo;a interroger les traces indélébiles de l&rsquo;activation de ces options et envoyer la note !</p>
<p><strong>2 &#8211; Pourquoi ?</strong><br />
Nous avons dit que la firme Oracle a besoin d&rsquo;argent&#8230; Il suffit de regarder les cours de bourse d&rsquo;Oracle pour constater son inexorable déclin. Dans le même temps, comparer ceux de son principal challenger Microsoft&#8230;<br />
<a href="http://blog.developpez.com/sqlpro/files/2016/02/Cours-action-Oracle-2015-2016.jpg"><img src="http://blog.developpez.com/sqlpro/files/2016/02/Cours-action-Oracle-2015-2016.jpg" alt="Cours action Oracle 2015 2016" width="314" height="214" class="alignnone size-full wp-image-645" /></a><a href="http://blog.developpez.com/sqlpro/files/2016/02/Cours-action-Microsoft-2015-2016.jpg"><img src="http://blog.developpez.com/sqlpro/files/2016/02/Cours-action-Microsoft-2015-2016.jpg" alt="Cours action Microsoft 2015 2016" width="316" height="214" class="alignnone size-full wp-image-646" /></a><br />
Comment Oracle en est-il arrivé là ? Il n&rsquo;y a pas que le prix exorbitant des licences qui font reculer les clients&#8230; D&rsquo;autres éléments clefs font rétrécir la part de marché d&rsquo;Oracle. Cela a commencé il y a plus de 10 ans, lorsqu&rsquo;est sortit la version 2005 de SQL Server de Microsoft. À l&rsquo;époque, Oracle se croyait &laquo;&nbsp;unbreakable&nbsp;&raquo;. Hélas plusieurs analystes montraient que sur le plan de la sécurité Oracle était bien moins bonne que celle de SQL Server, avec des bogues récurrents et un temps de correction anormalement lent (voir notamment <a href="https://www.nccgroup.trust/globalassets/our-research/uk/whitepapers/which_database_is_more_secure._oracle_vs_microsoft.pdf" title="Which database is more secure? Oracle vs. Microsoft" target="_blank">l&rsquo;étude de David Litchfield</a> de 2006). Sécurité qui ne s&rsquo;est pas améliorée hélas au fil du temps ou les comparaisons basées sur les failles (CVE : Common Vulnerabilities and Exposures) recensées par le NIST (National Institute of Standards and Technology) donne un avantage de plus en plus grand à SQL Server au détriment d&rsquo;Oracle sur le plan des failles de sécurité ! (voire <a href="http://www.theedison.com/pdf/Samples_MS_SQL_Server_2012_WP.pdf" title="Etude Edison comparatif oracle SQL Server" target="_blank">l&rsquo;étude Edison</a> de 2013)<br />
<div id="attachment_648" style="width: 540px" class="wp-caption alignnone"><a href="http://blog.developpez.com/sqlpro/files/2016/02/Etude-Litchfield-comparatif-de-sécurité-entre-Oracle-et-SQL-Server-de-2000-à-2006.jpg"><img src="http://blog.developpez.com/sqlpro/files/2016/02/Etude-Litchfield-comparatif-de-sécurité-entre-Oracle-et-SQL-Server-de-2000-à-2006.jpg" alt="Etude Litchfield - comparatif de sécurité entre Oracle et SQL Server de 2000 à 2006" width="1060" height="880" class="size-full wp-image-648" /></a><p class="wp-caption-text">Etude Litchfield &#8211; comparatif de sécurité entre Oracle et SQL Server de 2000 à 2006</p></div><br />
<div id="attachment_651" style="width: 510px" class="wp-caption alignnone"><a href="http://blog.developpez.com/sqlpro/files/2016/02/Etude-Edison-CVE-NIST-historique-vulnérabilités-Oracle-vs-SQL-Server.jpg"><img src="http://blog.developpez.com/sqlpro/files/2016/02/Etude-Edison-CVE-NIST-historique-vulnérabilités-Oracle-vs-SQL-Server.jpg" alt="Etude Edison - CVE NIST historique des vulnérabilités Oracle vs SQL Server" width="715" height="473" class="size-full wp-image-651" /></a><p class="wp-caption-text">Etude Edison &#8211; CVE NIST historique des vulnérabilités Oracle vs SQL Server</p></div><br />
Enfin, les enquêtes de satisfaction donnent un réel avantage à SQL Server (voir les enquêtes &laquo;&nbsp;<a href="http://reports.informationweek.com/abstract/81/12155/Business-Intelligence-and-Information-Management/Research:-2014-State-of-Database-Technology.html?download=true&amp;fwp=true#error" title="State on Database Technology 2014 - InformationWeek" target="_blank">State on Database Technology</a>&nbsp;&raquo; d&rsquo;Information Week ou encore les différentes <a href="http://itic-corp.com/blog/2011/02/itic-reliabiity-survey-oracle-users-anxiousangry-over-service-support-slippage/" title="ITIC Reliabiity Survey: Oracle Users Anxious/Angry Over Service, Support Slippage" target="_blank">études ITC</a>).<br />
<div id="attachment_654" style="width: 560px" class="wp-caption alignnone"><a href="http://blog.developpez.com/sqlpro/files/2016/02/InformationWeek-State-of-Database-Technologie-Mission-Critical.jpg"><img src="http://blog.developpez.com/sqlpro/files/2016/02/InformationWeek-State-of-Database-Technologie-Mission-Critical.jpg" alt="Bases de données les plus utilisées pour les missions critiques (source Information Week - State of Database Technologie 2016)" width="790" height="500" class="size-full wp-image-654" /></a><p class="wp-caption-text">Bases de données les plus utilisées pour les missions critiques (source Information Week &#8211; State of Database Technologie 2016)</p></div><br />
Quant au cout global d&rsquo;utilisation, il est depuis bien longtemps en faveur de SQL Server (simplicité des commandes, facilité de l&rsquo;IHM, documentation exceptionnelle&#8230;) malgré les nombreux papiers dont Oracle inonde le web afin de tenter de prouver le contraire ! Il suffit de demander à des dba ayant la double casquette ce qu&rsquo;ils en pense&#8230; (voire par exemple <a href="http://thuvienso.edu.vn/microsoft-sql-server-and-oracle-database-a-comparative-study-on-total-cost-of-administration-tca/" title="Microsoft SQL Server and Oracle Database: A Comparative Study on Total Cost of Administration (TCA)" target="_blank">l&rsquo;étude Alinean</a> de 2015).</p>
<p>Outre ces éléments il y a un facteur majeur qui rentre en ligne de compte sur le long terme. <strong>Le cloud</strong> (infonuagique) !&#8230; Larry Ellison y a longtemps été peu favorable et indécis. Le résultat est sans appel. Microsoft y existe et s&rsquo;en trouve être un des leader derrière Amazon. Oracle n&rsquo;existe pas sur ce marché. Les enquêtes du Gartner Group (Magic Quadrant pour le cloud) le montre bien&#8230;<br />
<div id="attachment_657" style="width: 529px" class="wp-caption alignnone"><a href="http://blog.developpez.com/sqlpro/files/2016/02/Gartner-2014-MQ-CLOUD.jpg"><img src="http://blog.developpez.com/sqlpro/files/2016/02/Gartner-2014-MQ-CLOUD.jpg" alt="Gartner Magic Quadrant 2014 for Cloud Infrastructure as a Service" width="519" height="524" class="size-full wp-image-657" /></a><p class="wp-caption-text">Gartner Magic Quadrant 2014 for Cloud Infrastructure as a Service</p></div><div id="attachment_658" style="width: 526px" class="wp-caption alignnone"><a href="http://blog.developpez.com/sqlpro/files/2016/02/Gartner-2015-MQ-CLOUD.jpg"><img src="http://blog.developpez.com/sqlpro/files/2016/02/Gartner-2015-MQ-CLOUD.jpg" alt="Gartner Magic Quadrant 2015 for Cloud Infrastructure as a Service" width="516" height="520" class="size-full wp-image-658" /></a><p class="wp-caption-text">Gartner Magic Quadrant 2015 for Cloud Infrastructure as a Service</p></div></p>
<p><strong>2 &#8211; Des pratiques scandaleuses</strong><br />
Dans l&rsquo;article de Business Insider une pratique s&rsquo;apparente à du chantage. Oracle consent à réduire l&rsquo;addition, si le client passe dans le cloud. Or nous venons de le voir, les clients sont loin de se précipiter dans l&rsquo;infonuagique à la sauce Oracle, lui préférant de loin Amazon lorsqu&rsquo;ils restent Oracleur ou Azure lorsqu&rsquo;ils passent à SQL Server.<br />
Un autre article (&laquo;&nbsp;<a href="http://www.lemondeinformatique.fr/actualites/lire-comment-se-deroule-un-audit-logiciel-avec-oracle-tres-mal-chez-mars-63664.html" title="Comment se déroule un audit logiciel avec Oracle" target="_blank">Comment se déroule un audit logiciel avec Oracle&#8230;</a>&nbsp;&raquo; du Monde Informatique) montrent à quel point les pratiques d&rsquo;Oracle sont scandaleuses et frisent le hors la Loi&#8230; &laquo;&nbsp;<em>Oracle réclame des informations qu’elle n’est pas supposée demander contractuellement sur les serveurs sur lesquels ne tournent pas de logiciel Oracle et sur le personnel de Mars qui n’utilise pas les logiciels d’Oracle</em>&laquo;&nbsp;. Imaginez quelles sont les implications d&rsquo;une telle intrusion dans vos serveurs ou auprès de vos employés !<br />
D’où les conseils distillés par certains juriste et économistes, d&rsquo;intégrer les risques de coûts associés aux audits d&rsquo;Oracle comme charges supplémentaire aux offres commerciales, ce qui a pour effet de gonfler la note finale d’acquisition des licences Oracle !</p>
<p><strong>3 &#8211; les options payantes</strong><br />
Je me suis livré à une comparaisons des options payantes dans oracle et gratuites dans SQL Server. Microsoft n&rsquo;offre d&rsquo;ailleurs pas d&rsquo;options payantes, mais les fonctionnalités dépendant des versions (comme dans Oracle d&rsquo;ailleurs). De plus, il existe de nombreux outils complémentaires gratuits pour SQL Server disponible sur le site web communautaire codeplex.<br />
Voici un tableau résumant la chose :<br />
<div id="attachment_660" style="width: 710px" class="wp-caption alignnone"><a href="http://blog.developpez.com/sqlpro/files/2016/02/Tableau-option-Oracle-SQL-Server.jpg"><img src="http://blog.developpez.com/sqlpro/files/2016/02/Tableau-option-Oracle-SQL-Server.jpg" alt="Comparaison des fonctionnalités Oracle (payantes) et SQL Server (gratuites)" width="1405" height="941" class="size-full wp-image-660" /></a><p class="wp-caption-text">Comparaison des fonctionnalités Oracle (payantes) et SQL Server (gratuites)</p></div></p>
<p><strong>4 &#8211; Le prix&#8230;</strong><br />
De la même manière, j&rsquo;ai étudié le montant comparatif des licences à payer pour l&rsquo;équivalence d&rsquo;Oracle avec SQL Server, basé sur la version Enterprise. Le résultat est édifiant&#8230;<br />
Prix des options Oracle (21 juin 2016) &laquo;&nbsp;Processor Licence&nbsp;&raquo; :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Active Data Guard &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 11 500 $<br />
Database In-Memory &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;23 000 $<br />
Diagnostics Pack &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 7 500 $<br />
Tuning Pack &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;5 000 $<br />
Partitionning &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 11 500 $<br />
Advanced compression &nbsp; &nbsp; &nbsp; &nbsp;11 500 $<br />
OLAP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;23 000 $<br />
Advanced Analytics &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;23 000 $<br />
Spatial &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 17 500 $<br />
Multitenant &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 17 500 $<br />
TOTAL : &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;139 500 $</div></div>
<p><strong><br />
Prix des licences Oracle édition Enterprise : 47 500 $</strong><br />
Le prix des licences Oracle s&rsquo;établie pour 2 processeurs. Par exemple sur une machine quadriprocesseur ayant des CPU comportant 12 coeurs, le facteur de licence est donc de 24 (4 x 12 / 2).</p>
<p><strong>Prix des licences SQL Server édition Enterprise : 27 496 $</strong><br />
Le prix des licences SQL Server s&rsquo;établie pour 4 processeurs. Par exemple sur une machine quadriprocesseur ayant des CPU comportant 12 coeurs, le facteur de licence est donc de 12 (4 x 12 / 4).</p>
<p>Comparaison basé sur le prix au processeur : (47 500 / 2) / (27 496 / 4) = 4<br />
<strong>Oracle, sans aucune option payante, est donc naturellement 4 fois plus cher que SQL Server </strong></p>
<p>Avec notre machine exemple (quadriprocesseur ayant des CPU comportant 12 coeurs) et toutes les options, nous arrivons à la différence suivante :<br />
Oracle : 24 x ( 47 500 + 139 500 ) = 4 488 000 $<br />
SQL Server : 12 x 27 496 = 329 952 $<br />
<strong>À ce stade, Oracle est 13,6 fois plus cher&#8230;</strong> </p>
<p>Mais vous pouvez négocier !</p>
<ul>
<li>les remises maximales chez Oracle vont jusqu&rsquo;à 70%, vous passez donc à : 1 346 400 $</li>
<li>les remises maximales chez Microsoft vont jusqu&rsquo;à 40%, vous passez donc à : 197 971 $</li>
</ul>
<p>De plus si vous avez misé sur des serveur dotés de processeurs OPTERON d&rsquo;AMD, alors Microsoft accorde un facteur de réfaction supplémentaire de 25%. La note passe donc à 148 478 $<br />
<strong>Après négociation et utilisation de processeurs Opteron d&rsquo;AMD, au final, Oracle s&rsquo;avère 9 fois plus cher&#8230;</strong></p>
<p><strong>En conclusion</strong></p>
<p>Comme je le mentionnait dans un article précédent &laquo;&nbsp;<a href="http://blog.developpez.com/sqlpro/p12653/bases-de-donnees/le-declin-oracle" target="_blank">le déclin d&rsquo;Oracle</a>&nbsp;&raquo; la firme de Redwood Shores est en sérieuse perte de vitesse. Elle n&rsquo;est même plus le champion de l&rsquo;avancée technologique. Par exemple elle s&rsquo;est faite grillée sur le &laquo;&nbsp;In Memory&nbsp;&raquo; par SAP avec HanaDB, puis par SQL Server&#8230;<br />
Sur les performances la plupart des benchmarks effectués par les utilisateurs montre quelle est plus gourmande à performances équivalente que la plupart de ses challengers ou si l&rsquo;on prend l&rsquo;autre bout de la lorgnette, qu&rsquo;elle est moins performantes sur une même machine. Mais Oracle interdisant de publier le moindre benchmark concernant le produit, vous ne trouverez pas d&rsquo;étude sérieuses sur le sujet. Reste les benchmarks officiels du TPC, mais là c&rsquo;est une autre histoire&#8230; Oracle ne publie que les résultats du <a href="http://www.tpc.org/tpcc/results/tpcc_perf_results.asp" title="Résultat TCP-C" target="_blank">TCP-C</a> datant de 1992 donc sur une base de données datée de 23 ans comportant en tout et pour tout <a href="http://www.tpc.org/tpc_documents_current_versions/pdf/tpc-c_v5.11.0.pdf" title="TPC-C documentation" target="_blank">8 tables et des jointures limitées à 2 tables sans aucune sous requête</a> ! Et même dans ce cas, SQL AnyWhere de SAP (anciennement Syabse) la bât sur le coût&#8230;<br />
En revanche SQL Server se sert du <a href="http://www.tpc.org/tpce/results/tpce_perf_results.asp" title="TPC-E Résultats" target="_blank">TPC-E</a> plus récent (2007) et plus réaliste, comportant 33 tables des jointures avec 7 tables et de multiples sous requêtes. Et là curieusement, Oracle n&rsquo;y a jamais présenté un seul résultat de benchmark !<br />
Et ce déclin est bien constaté par d&rsquo;inexorables chiffres. Par exemple celui comparant, pour un organisme de formation bien connu pour son indépendance, le nombre de stagiaires formés sur chacune des deux plateformes&#8230;<br />
<div id="attachment_666" style="width: 610px" class="wp-caption alignnone"><a href="http://blog.developpez.com/sqlpro/files/2016/02/Formation-professionnelle-évotion-2005-2015-Oracle-vs-SQL-Server.jpg"><img src="http://blog.developpez.com/sqlpro/files/2016/02/Formation-professionnelle-évotion-2005-2015-Oracle-vs-SQL-Server.jpg" alt="Formation professionnelle - évolution 2005-2015 Oracle vs SQL Server" width="1147" height="618" class="size-full wp-image-666" /></a><p class="wp-caption-text">Formation professionnelle &#8211; évolution 2005-2015 Oracle vs SQL Server</p></div></p>
<p><em>Pas la peine de vous faire un dessin !</em></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Un point sur les collations&#8230;</title>
		<link>https://blog.developpez.com/sqlpro/p12825/langage-sql-norme/un-point-sur-les-collations</link>
		<comments>https://blog.developpez.com/sqlpro/p12825/langage-sql-norme/un-point-sur-les-collations#comments</comments>
		<pubDate>Mon, 19 Jan 2015 10:13:20 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[bases de données]]></category>
		<category><![CDATA[Langage SQL (norme)]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=553</guid>
		<description><![CDATA[Voici une réponse de forum dans laquelle je précise comment sont gérées les collations dans les SGBDR. http://www.developpez.net/forums/d1397211/bases-donnees/langage-sql/utilisation-d-between-chaine-caracteres/#post7632749 À noter : Oracle ne dispose pas de collation mais de l&#8217;imbitable NLS qui ne permet pas entre autre : &#8211; de gérer différentes collations au sein d&#8217;une même requête (par exemple faire une recherche de login [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Voici une réponse de forum dans laquelle je précise comment sont gérées les collations dans les SGBDR.<span id="more-553"></span></p>
<p><a href="http://www.developpez.net/forums/d1397211/bases-donnees/langage-sql/utilisation-d-between-chaine-caracteres/#post7632749">http://www.developpez.net/forums/d1397211/bases-donnees/langage-sql/utilisation-d-between-chaine-caracteres/#post7632749</a></p>
<p>À noter : Oracle ne dispose pas de collation mais de l&rsquo;imbitable NLS qui ne permet pas entre autre :<br />
&#8211; de gérer différentes collations au sein d&rsquo;une même requête (par exemple faire une recherche de login en ne tenant pas compte de la casse et du mot de passe associé en tenant compte de la casse et des diacritiques.<br />
&#8211; de faire des recherches sans tenir compte de la casse, mais en tenant compte des accents, pas exemple pour différencier &laquo;&nbsp;maïs&nbsp;&raquo; de &laquo;&nbsp;mais&nbsp;&raquo; lorsque l&rsquo;on travaille chez un semencier !</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>
<p>L&rsquo;entreprise <a href="http://www.sqlspot.com">SQL Spot</a><br />
<strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a></p>
<p><img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL
Server" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Données géographiques gratuites pour la France</title>
		<link>https://blog.developpez.com/sqlpro/p12749/bases-de-donnees/donnees-geographiques-gratuites-pour-la-france</link>
		<comments>https://blog.developpez.com/sqlpro/p12749/bases-de-donnees/donnees-geographiques-gratuites-pour-la-france#comments</comments>
		<pubDate>Tue, 23 Sep 2014 11:50:40 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[bases de données]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=499</guid>
		<description><![CDATA[Voici un ensemble d&#8217;URL pour télécharger des données cartographiques et géographiques françaises&#8230; Collectivités locales &#8211; voies et lieux-dits en France : http://www.collectivites-locales.gouv.fr/mise-a-disposition-fichier-fantoir-des-voies-et-lieux-dits INSEE &#8211; découpages géographiques nationaux officiels (COG) : &#8211; communes &#8211; cantons &#8211; arrondissements &#8211; départements &#8211; régions Documentation : http://www.insee.fr/fr/methodes/nomenclatures/cog/documentation.asp Téléchargement : http://www.insee.fr/fr/methodes/nomenclatures/cog/telechargement.asp IGN &#8211; Bases géomatiques diverses : http://professionnels.ign.fr/gratuit]]></description>
				<content:encoded><![CDATA[<p>Voici un ensemble d&rsquo;URL pour télécharger des données cartographiques et géographiques françaises&#8230;<br />
<span id="more-499"></span></p>
<p><strong>Collectivités locales &#8211; voies et lieux-dits en France </strong> :</p>
<p><a href="http://www.collectivites-locales.gouv.fr/mise-a-disposition-fichier-fantoir-des-voies-et-lieux-dits">http://www.collectivites-locales.gouv.fr/mise-a-disposition-fichier-fantoir-des-voies-et-lieux-dits</a></p>
<p><strong>INSEE &#8211; découpages géographiques nationaux officiels</strong> (COG) :<br />
&#8211; communes<br />
&#8211; cantons<br />
&#8211; arrondissements<br />
&#8211; départements<br />
&#8211; régions</p>
<p>Documentation : <a href="http://www.insee.fr/fr/methodes/nomenclatures/cog/documentation.asp">http://www.insee.fr/fr/methodes/nomenclatures/cog/documentation.asp</a><br />
Téléchargement : <a href="http://www.insee.fr/fr/methodes/nomenclatures/cog/telechargement.asp">http://www.insee.fr/fr/methodes/nomenclatures/cog/telechargement.asp</a></p>
<p><strong>IGN &#8211; Bases géomatiques diverses</strong> :</p>
<p><a href="http://professionnels.ign.fr/gratuit">http://professionnels.ign.fr/gratuit</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Le déclin d&#8217;Oracle ?</title>
		<link>https://blog.developpez.com/sqlpro/p12653/bases-de-donnees/le-declin-oracle</link>
		<comments>https://blog.developpez.com/sqlpro/p12653/bases-de-donnees/le-declin-oracle#comments</comments>
		<pubDate>Tue, 24 Jun 2014 10:20:14 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[bases de données]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=472</guid>
		<description><![CDATA[De récentes études montre l&#8217;inexorable déclin d&#8217;Oracle&#8230; Dans une étude récente* sur l&#8217;utilisation des bases de données SQL et NoSQL, menée par l&#8217;entreprise Tesora, on note, sur la question de quels SGBDR sont actuellement utilisés en entreprise, les chiffres suivants : &#8211; Microsoft SQL Server : 57 % &#8211; MySQL : 40 % &#8211; Oracle [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>De récentes études montre l&rsquo;inexorable déclin d&rsquo;Oracle&#8230;<br />
<span id="more-472"></span><br />
Dans une étude récente* sur l&rsquo;utilisation des bases de données SQL et NoSQL, menée par l&rsquo;entreprise Tesora, on note, sur la question de quels SGBDR sont actuellement utilisés en entreprise, les chiffres suivants :<br />
&#8211; Microsoft SQL Server : 57 %<br />
&#8211; MySQL : 40 %<br />
&#8211; Oracle : 38 %<br />
&#8211; IBM DB2 : 14 %<br />
&#8211; PostgreSQL : 13 %<br />
<strong>NOTA</strong> : le total est supérieur à 100%, les entreprises ayant souvent plusieurs SGBDR.</p>
<p>Une autre étude*** datant de mars 2014, menée par Information Week, intitulée &laquo;&nbsp;2014 State of<br />
Database Technology&nbsp;&raquo;, montre les métriques suivantes :<br />
Bases de données utilisées pour les missions les plus critiques (voir figure ci après) &#8211; 3 réponses possibles :<br />
&#8211; Microsoft SQL Server : 57 %<br />
&#8211; Oracle : 38 %<br />
&#8211; MySQL : 13 %<br />
&#8211; IBM DB2 : 11 %<br />
&#8211; Microsoft Access : 11 %<br />
&#8211; PostgreSQL : 3 %<br />
&#8230;<br />
<div id="attachment_490" style="width: 398px" class="wp-caption alignnone"><a href="http://blog.developpez.com/sqlpro/files/2014/06/Oracle_le_declin.jpg"><img src="http://blog.developpez.com/sqlpro/files/2014/06/Oracle_le_declin.jpg" alt="Oracle surpassé par SQL Server dans les fonctions d&#039;entreprise les plus critiques" width="388" height="496" class="size-full wp-image-490" /></a><p class="wp-caption-text">Oracle surpassé par SQL Server dans les fonctions d&rsquo;entreprise les plus critiques</p></div></p>
<p>Bases de données en usage dans l’entreprise :<br />
&#8211; Microsoft SQL Server : 75 %<br />
&#8211; Microsoft Access : 48 %<br />
&#8211; Oracle : 47 %<br />
&#8211; MySQL : 37%<br />
&#8211; IBM DB2 : 17 %<br />
&#8211; PostgreSQL : 10 %<br />
&#8230;</p>
<p>Il y a quelques années, Oracle était en tête dans des études similaires. Aujourd&rsquo;hui Oracle est passé derrière SQL Server depuis quelques années, et même derrière MySQL détenu aussi par Oracle et parfois même derrière Microsoft Access !</p>
<p>Un déclin confirmé en France d&rsquo;une part, par le nombre important de consultants ayants des difficultés à trouver des contrats, et d&rsquo;autre part, par des tarifs journaliers en baisse.<br />
Ainsi, au début des années 2000, un spécialiste Oracle décrochait facilement des journées de prestation pour des missions courtes avec un tarif généralement très supérieur au millier d&rsquo;euros.<br />
Aujourd&rsquo;hui le prix de journée a été presque divisé par deux tant l&rsquo;offre est importante et la demande est faible&#8230;</p>
<p>Autre élément contribuant au déclin d&rsquo;Oracle : un prix de licence élevé, une forte complexité d&rsquo;administration et une sécurité très en dessous de celle de SQL Server.<br />
On constate dans les faits de nombreuses migrations de bases Oracle vers PostGreSQL, MySQL ou SQL Server. Plusieurs outils d&rsquo;aide à la migration (assistants) ont vu le jour récemment.</p>
<p><em>* : étude Tesora &laquo;&nbsp;Database Usage in the Public and Private Cloud: Choices and Preferences,&nbsp;&raquo; menée auprès de 500 &laquo;&nbsp;répondants&nbsp;&raquo; du &laquo;&nbsp;North American developer communities&nbsp;&raquo; dans des entreprise qui se définissent elles-même comme adepte, dès les premiers temps, des nouvelles technologies et ayant adopté l&rsquo;open source.<br />
** : étude Information Week, intitulée &laquo;&nbsp;2014 State of Database Technology&nbsp;&raquo; de mars 2014, auprès de 956 répondants destinée à déterminer le rôle des technologies de bases de données dans l&rsquo;entreprise.</em></p>
<p><strong>Autres études :</strong></p>
<p><a href="http://sqlmag.com/blog/survey-shows-companies-now-have-more-sql-server-databases-oracle-databases">Embarcadero Technologies’ Database Survey Report (décembre 2010)</a></p>
<p><a href="http://itic-corp.com/blog/2010/09/sql-server-most-secure-database-oracle-least-secure-database-since-2002/">SQL Server Most Secure Database &#8211; Oracle Least Secure Database Since 2002 (septembre 2010)</a></p>
<p><a href="http://www.informationweek.com/software/information-management/microsoft-sql-server-2012-vs-oracle-customers-voting/d/d-id/1103771?">Microsoft SQL Server 2012 Vs. Oracle: Customers Voting (septembre 2012)</a></p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>
<p>L&rsquo;entreprise <a href="http://www.sqlspot.com">SQL Spot</a><br />
<strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a></p>
<p><img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL Server" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Hachage n&#8217;est pas cryptage ! De la sécurité des données chiffrées dans les SGBDR</title>
		<link>https://blog.developpez.com/sqlpro/p12496/langage-sql-norme/hachage-nest-pas-cryptage-de-la-securite-des-donnees-chiffrees-dans-les-sgbdr</link>
		<comments>https://blog.developpez.com/sqlpro/p12496/langage-sql-norme/hachage-nest-pas-cryptage-de-la-securite-des-donnees-chiffrees-dans-les-sgbdr#comments</comments>
		<pubDate>Wed, 19 Feb 2014 10:24:54 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[bases de données]]></category>
		<category><![CDATA[Langage SQL (norme)]]></category>
		<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[PostGreSQL]]></category>
		<category><![CDATA[SQL Server 2005]]></category>
		<category><![CDATA[SQL Server 2008]]></category>
		<category><![CDATA[SQL Server 2012]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=403</guid>
		<description><![CDATA[De plus en plus de jeunes développeurs confondent la technique du hachage et le chiffrement des données. Voici un point sur le sujet&#8230; Qu&#8217;est-ce que le hachage ? Le hachage consiste à calculer une donnée de petite dimension à partir d&#8217;une donnée de grande dimension afin de s&#8217;en servir comme repère dans différents processus algorithmique. [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>De plus en plus de jeunes développeurs confondent la technique du hachage et le chiffrement des données. Voici un point sur le sujet&#8230;<br />
<span id="more-403"></span><br />
<strong>Qu&rsquo;est-ce que le hachage ?</strong></p>
<p>Le hachage consiste à calculer une donnée de petite dimension à partir d&rsquo;une donnée de grande dimension afin de s&rsquo;en servir comme repère dans différents processus algorithmique. La valeur obtenu par hachage est un nombre ou une chaine binaire et dans ce dernier cas généralement représentée en  hexadécimal.<br />
Les algorithmes de hachage les plus connus sont : MD2, MD4, MD5 (16 octets / 128 bits en sortie), SHA (ou SHA-0), SHA-1 (20 octets / 160 bits en sortie), SHA-2 (224 à 512 bits), Whirlpoll (64 octets / 512 bits).<br />
On trouvera la description des algorithmes de calcul de ces fonctions de hachage aux URL suivantes :</p>
<li>MD2 : <a href="http://tools.ietf.org/html/rfc1319">http://tools.ietf.org/html/rfc1319</a></li>
<li>MD4 : <a href="http://tools.ietf.org/search/rfc1320">http://tools.ietf.org/search/rfc1320</a></li>
<li>MD5 : <a href="http://fr.wikipedia.org/wiki/MD5">http://fr.wikipedia.org/wiki/MD5</a></li>
<li>SHA : <a href="http://fr.wikipedia.org/wiki/SHA-0">http://fr.wikipedia.org/wiki/SHA-0</a></li>
<li>SHA1 : <a href="http://fr.wikipedia.org/wiki/SHA-1">http://fr.wikipedia.org/wiki/SHA-1</a></li>
<li>SHA2 : <a href="http://fr.wikipedia.org/wiki/SHA-2">http://fr.wikipedia.org/wiki/SHA-2</a></li>
<li>Whirlpool : <a href="http://www.seas.gwu.edu/~poorvi/Classes/CS381_2007/Whirlpool.pdf">http://www.seas.gwu.edu/~poorvi/Classes/CS381_2007/Whirlpool.pdf</a></li>
<p>La valeur en sortie est de taille fixe quel que soit la longueur de l&rsquo;information d&rsquo;entrée. Du point de vue des mathématiques il ne peut s&rsquo;agir d&rsquo;un processus de cryptage puisque le cryptage produit des données dont le volume est au moins aussi important que le volume des données en entrée, voir beaucoup plus lorsque les données d&rsquo;entrée sont de petits volumes.<br />
Certains logiciels utilisent leurs propres algorithmes pour générer des valeurs de hachage. Par exemple SQL Server implémente les fonctions CHECKSUM, BINARY_CHECKSUM et CHECKSUM_AGG pour calculer un entier 32 bits à partir d&rsquo;une valeur, d&rsquo;une expression ou d&rsquo;une liste d&rsquo;expression ou de valeurs combinées, soit pour une ligne, soit pour une colonne.<br />
On trouvera un exemple de l&rsquo;algorithme utilisé à l&rsquo;URL suivante : <a href="http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=70832">http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=70832</a></p>
<p>Le hachage entraîne fatalement des <strong>collisions</strong>, c&rsquo;est à dire que différentes informations peuvent produire une même valeur de hachage. </p>
<p>Voici un exemple de collision de hachage avec la fonction MD5&#8230;<br />
Pour PostGreSQL :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> md5<span style="color: #66cc66;">&#40;</span>E<span style="color: #ff0000;">'<span style="color: #000099; font-weight: bold;">\\</span>xd131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f8955ad340609f4b30283e488832571415a085125e8f7cdc99fd91dbdf280373c5bd8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70'</span>::bytea<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">UNION</span> <span style="color: #993333; font-weight: bold;">ALL</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> md5<span style="color: #66cc66;">&#40;</span>E<span style="color: #ff0000;">'<span style="color: #000099; font-weight: bold;">\\</span>xd131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f8955ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5bd8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70'</span>::bytea<span style="color: #66cc66;">&#41;</span></div></div>
<p>Pour MS SQL Server :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> HASHBYTES<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'md5'</span><span style="color: #66cc66;">,</span> 0xd131dd02c5e6eec4693d9a0698aff95c2fcab58712467eab4004583eb8fb7f8955ad340609f4b30283e488832571415a085125e8f7cdc99fd91dbdf280373c5bd8823e3156348f5bae6dacd436c919c6dd53e2b487da03fd02396306d248cda0e99f33420f577ee8ce54b67080a80d1ec69821bcb6a8839396f9652b6ff72a70<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">UNION</span> <span style="color: #993333; font-weight: bold;">ALL</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> HASHBYTES<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'md5'</span><span style="color: #66cc66;">,</span> 0xd131dd02c5e6eec4693d9a0698aff95c2fcab50712467eab4004583eb8fb7f8955ad340609f4b30283e4888325f1415a085125e8f7cdc99fd91dbd7280373c5bd8823e3156348f5bae6dacd436c919c6dd53e23487da03fd02396306d248cda0e99f33420f577ee8ce54b67080280d1ec69821bcb6a8839396f965ab6ff72a70<span style="color: #66cc66;">&#41;</span></div></div>
<p>le 20e octet est différent dans les deux chaines hexadécimales passées en argument. </p>
<p><strong>Le hachage n&rsquo;est pas non plus réversible</strong>. Il n&rsquo;existe pas de fonction permettant à coup sûr de retrouver l&rsquo;information initiale partant de la valeur hachée. La possibilité de collisions s&rsquo;oppose à la bijection impérativement nécessaire à déterminer une fonction réciproque.</p>
<p><em><strong>Le but du hachage n&rsquo;est donc pas de crypter des données mais de donner une &laquo;&nbsp;empreinte&nbsp;&raquo; à une donnée.</strong></em></p>
<p><strong>Qu&rsquo;est-ce que le cryptage ?</strong></p>
<p>Le cryptage est l&rsquo;ensemble des processus permettant à une donnée d&rsquo;être transformée en une autre incompréhensible pour qui ne connais pas la donnée originale, puis, partant de la transformation, d&rsquo;être retransformée en donnée d&rsquo;origine.<br />
Le cryptage nécessite donc l&rsquo;existence de deux traitements conjoints et bijectifs : l&rsquo;un de cryptage, l&rsquo;autre de décryptage. On parle alors de correspondance univoque entre l&rsquo;ensemble des données en clair et l&rsquo;ensemble des données cryptées.<br />
Le chiffrement est un sous ensemble du cryptage qui consiste à utiliser des fonctions mathématiques afin de crypter et de décrypter. Néanmoins il en existe d&rsquo;autres comme par exemple la stéganographie&#8230;</p>
<p>Les techniques modernes de cryptage en matière informatique sont basées sur le chiffrement à l&rsquo;aide d&rsquo;algorithmes à clefs :
<li>la même clef servant à crypter et décrypter, on parle alors de chiffrement symétrique (il faut garder sa clef secrète)</li>
<li>une clef sert à chiffrer une autre à déchiffrer, on parle alors de chiffrement asymétrique (on peut rendre publique l&rsquo;une des deux clefs)</li>
<p>L&rsquo;algorithme est connu et la clef de décryptage est confidentielle. La sécurité est basée sur la complexité d&rsquo;un possible déchiffrement par une attaque de type &laquo;&nbsp;force brute&nbsp;&raquo; (essais de décryptage par toutes une série de clef probables).<br />
La complexité du chiffrement est liée à l&rsquo;algorithme et à la longueur de la clef. Les algorithmes à clef asymétriques étant plus fiables car plus complexes, mais aussi plus couteux en temps de traitement.</p>
<p>Principaux algorithmes (et longueur de clef) :
<li>symétrique : DES (56 bits), TRIPLE_DES (128 ou 192 bits), RC2, RC4, RC4_128 (128 bits), AES (128 à 256 bits)</li>
<li>asymétrique : RSA_512 (512 bits), RSA_1024 (1024 bits), RSA_2048 (2048 bits)</li>
<p><strong>NOTA : </strong>les algorithmes de type RC sont aujourd&rsquo;hui considérés comme peu fiables et ne doivent plus être utilisés en production, car ils sont faciles à casser. RC2 fût longtemps utilisé par Lotus Notes. RC4 est encore utilisé pour protéger les informations d&rsquo;un réseau wifi avec clef WEP ou WPA.</p>
<p><strong>Emploi du hachage</strong></p>
<p>Les tous premiers emplois du hachage ont été une pseudo cryptographie à sens unique destinée à vérifier la justesse d&rsquo;une information connue. Le principe est assez simple : on calcule une valeur de hachage sur des informations confidentielle et on stocke cette valeur plutôt que les informations.<br />
Si quelqu&rsquo;un vient avec les données originales que l&rsquo;on hache avec le même algorithme, alors les deux valeurs (le hachage calculé et le hachage stocké) sont identiques; On suppose alors que les données sont les mêmes, ce qui, du fait des collisions potentielles est paradoxalement faux.<br />
Mais avant l&rsquo;an 2000, exploiter un véritable mécanisme de cryptage était considéré comme un crime et passible d&rsquo;une peine de prison. C&rsquo;est pourquoi le hachage prit de l&rsquo;ampleur avant que deux choses ne se produisent :</p>
<li>la découverte de techniques d&rsquo;attaques permettant de &laquo;&nbsp;casser&nbsp;&raquo; ou de semer le trouble concernant le hachage (par exemple la génération de collisions)</li>
<li>la liberté légale de crypter des données, introduite en droit français peu après la directive européenne 2000/31/CE du 8 juin 2000 sur le commerce électronique, suite à l&rsquo;affaire Zimmermann et son outil PGP.</li>
<p>Dès lors les algorithmes de cryptage ont remplacé la plupart des processus de hachage sauf dans les systèmes encore en vigueur dont ils constituent une part essentiel du fonctionnement.</p>
<p>Néanmoins le hachage peut rendre d&rsquo;inestimables services. Il est notablement utilisé dans les systèmes informatiques distribués ou dans la gestion du parallélisme d&rsquo;accès à des ressources d&rsquo;un système, notamment pour situer une information.<br />
Ainsi dans un système de bases de données distribuées on calculera une clef de hachage sur les éléments d&rsquo;authentification de l&rsquo;utilisateur et sur cette clef on calculera un modulo en fonction du nombre de nœuds dans le maillage du système distribué.<br />
Par exemple pour un site web comme fnac.com il existe de nombreux serveurs de bases de données, chacun ayant en table tous les produits à vendre, mais un client n&rsquo;existant que sur un seul des serveurs.<br />
Tant que l&rsquo;utilisateur navigue anonymement on route ses requêtes sur le serveur le moins chargé à l&rsquo;instant t;<br />
Dès qu&rsquo;il est authentifié ou calcule une clef de hachage sur son mail + mot de passe, puis on calcule un modulo en fonction du nombre de serveurs et on route dorénavant toutes ses requêtes sur le serveur dont l&rsquo;indice correspond au modulo, puisque c&rsquo;est seulement sur ce serveur que le client est connu.</p>
<p>Le même algorithme est appliqué dans certains moteurs de bases de données relationnelles pour gérer des traitements en parallèle ou diminuer le temps de traitement. Par exemple pour résoudre une jointure (hash join) ou un groupage (hash group)</p>
<p><strong>Emploi de la cryptographie</strong></p>
<p>La cryptographie sert à rendre confidentielles certaines informations qui ne pourrons être décryptées que par ceux qui connaisse la façon de crypter et donc de décrypter.<br />
Elle permet aussi l&rsquo;authentification, par le biais de certificat qui sont des documents liant une identité à une clef par le biais d&rsquo;une signature (tiers de confiance) et permettent d&rsquo;avoir la certitude sur l&rsquo;origine d&rsquo;une entité.</p>
<p><strong>Signature de documents et authentification</strong></p>
<p>La signature numérique (ou signature électronique) permet de garantir l&rsquo;intégrité d&rsquo;un document électronique et par là même d&rsquo;en authentifier l&rsquo;auteur.<br />
Elle fonctionne à l&rsquo;aide d&rsquo;une clef asymétrique ou d&rsquo;un certificat, et une fonction de hachage :</p>
<li>l&rsquo;auteur calcule une valeurs de hachage par le biais de la fonction de hachage considérée puis crypte cette information de hachage qui constitue la signature du document électronique. Cette signature est incorporée au document.</li>
<li>lors de la réception le destinataire calcule une valeur de hachage sur le document sans tenir compte de la signature, puis décrypte la signature à l&rsquo;aide de la clef publique. Si les deux valeurs (la signature incorporée et la signature nouvellement calculées) sont identiques, alors le document à toutes les chances d&rsquo;être authentique.</li>
<p>Il est par exemple possible de &laquo;&nbsp;signer&nbsp;&raquo; un programme informatique (exécutable ou DLL).</p>
<p><strong>Chiffrement de données</strong></p>
<p>Un exemple typique de chiffrement est la communication d&rsquo;information confidentielle par email. En effet, les données d&rsquo;un email peuvent être interceptées sur le réseau Internet, ce à quoi s&rsquo;emploient certaines organisations telles que la NSA.</p>
<p>La confidentialité des données stockées notamment dans les bases de données nécessite parfois du chiffrement. C&rsquo;est le cas des données des cartes bancaires ou des données personnelles notamment dans certains domaines sensibles comme la politique, le syndicalisme, la religion ou la santé.<br />
Dans ce dernier secteur, la Loi française impose des standards de chiffrement très élevées lorsque ces données sont accessibles sur Internet (<a href="http://www.legifrance.gouv.fr/affichCode.do;jsessionid=7A144763E4004F90B4EA25BB405A5652.tpdjo16v_3?idSectionTA=LEGISCTA000006196138&amp;cidTexte=LEGITEXT000006072665&amp;dateTexte=20101105">Décret n° 2006-6 relatif à l’hébergement de données de santé à caractère personnel</a>).</p>
<p>Certains SGBDR incorporent des services de génération et de gestion de clefs, de cryptage/décryptage et d&rsquo;authentification par certificat. C&rsquo;est par exemple le cas d&rsquo;Oracle ou de MS SQL Server qui sont leurs propres autorités de certifications et stockent les clefs dans les bases.<br />
D&rsquo;autres SGBDR propose des fonctions de cryptage/décryptage sans la gestion des clefs, ce qui pose le problème de la conservation des clefs&#8230; C&rsquo;est le cas de MySQL et de PostGreSQL qui nécessite un tiers externe de certification et obligent à véhiculer les clefs d&rsquo;une manière ou d&rsquo;une autre, souvent par le biais de fichiers sur le serveur&#8230;<br />
Le chiffrement des données dans les bases de données posent d&rsquo;ailleurs d&rsquo;autres problèmes :</p>
<li>le cassage aisé du code, si les données ne sont pas &laquo;&nbsp;salées&nbsp;&raquo;</li>
<li>la rapidité d&rsquo;accès à l&rsquo;information</li>
<li>la volumétrie de stockage des données cryptées</li>
<li>la difficulté de recherches performantes</li>
<p><strong>Le salage</strong> est abordé au paragraphe suivant et constitue une faille de sécurité importante en son absence.</p>
<p><strong>La rapidité d&rsquo;accès à l&rsquo;information</strong> est notablement diminuée par le fait de crypter et décrypter en permanence</p>
<p><strong>La volumétrie des données cryptées</strong> est plus importante en général que lorsque les données ne sont pas cryptées</p>
<p>Enfin, il est très <strong>difficile de rendre les recherches performantes</strong> dès lors que les données sont cryptées et salées par le simple fait qu&rsquo;il est impossible d&rsquo;utiliser un index et que par conséquent, il faut lire séquentiellement toutes les données et les décrypter avant d&rsquo;effectuer la comparaison.</p>
<p>Il faut aussi faire très attention dans les bases de données au <strong>recoupement des données qui permettrait</strong>, même avec un chiffrage, <strong>de trouver certaines données</strong>. En effet, toutes les informations ne sont pas chiffrées et heureusement sinon les performances seraient catastrophiques et la base inexploitable&#8230; Mais imaginons une base de données dans laquelle nous savons qu&rsquo;un des patients est un général argentin&#8230; Si ces informations figurent en clair et que, comme il est probable, il y a peu d&rsquo;argentins et peu de généraux dans les données, alors il est facile de trouver ou figure cet individu dans la base et par là même de retrouver de fil en aiguille certaines informations comme son prochain rendez-vous de chimio !</p>
<p>Pour pallier à ce dernier inconvénient, une autre solution de chiffrement dans les bases données est basée sur le cryptage du stockage et non plus des données (<a href="http://en.wikipedia.org/wiki/Transparent_Data_Encryption">TDE ou Transparent Data Encryption</a> que l&rsquo;on trouve notamment chez Oracle et MS SQL Server). Les données sont alors manipulées en clair en mémoire et de façon optimisé (utilisation des index) alors qu&rsquo;elles figurent de manière chiffrées dans les fichiers (données des tables en index et journal de transactions), le cryptage/décryptage étant assurée à la volée lors des entrées / sorties au niveau du disque.</p>
<p>Enfin, certains SGBDR (Oracle, MS SQL Server) permmettent d&rsquo;utiliser des boitiers externes de chiffrement inviolables (<a href="http://en.wikipedia.org/wiki/Hardware_Security_Module">HSM ou Hardware Security Module</a>) que l&rsquo;on place sur le réseau et qui sont utilisés par le serveur SQL. En cas de tentative d&rsquo;accès au boitier, les clefs sont automatiquement détruites.<br />
Un exemple d&rsquo;utilisation d&rsquo;un HMS en pratique est celui qui protège les données personnelles confidentielles de santé des agents territoriaux de France (environ 2 millions d&rsquo;individus) par le biais d&rsquo;un HSM et d&rsquo;un serveur de bases de données Microsoft SQL Server, </p>
<p><strong>Salage</strong></p>
<p>Le salage, est une méthode permettant de renforcer la sécurité des informations cryptées en y ajoutant une donnée supplémentaire afin d&rsquo;empêcher que deux informations identiques conduisent aux mêmes données chiffrées. Le but du salage est de lutter contre une attaque par analyse fréquentielle.<br />
Le cas est classique dans les bases de données. En effet, lorsque le système concentre beaucoup de données, il est fréquent de trouver des informations identiques (redondances) comme c&rsquo;est par exemple le cas des noms de famille (<a href="http://www.genealogie.com/nom-de-famille-1/">MARTIN, DURAND, LEFEBVRE&#8230;</a>)<br />
Dès lors une analyse basées sur la fréquence d&rsquo;apparition des redondances permettrait assez rapidement de casser le code.<br />
Pour pallier à cet inconvénient, certains SGBDR comme Oracle ou SQL Server intègrent automatiquement un salage pour que deux données identiques donnent deux codes chiffrés différents. </p>
<p><strong>NOTA :</strong> les serveurs de bases de données comme MySQL ou PostGreSQL ne permettent pas d&rsquo;utiliser un salage automatique des données lors de l&rsquo;utilisation des fonctions de cryptage. </p>
<p><strong>Bases de données et chiffrement</strong></p>
<p>À la lecture des paragraphes précédent, il apparait clair que les solutions de chiffrement actuelles dans les bases de données &laquo;&nbsp;libres&nbsp;&raquo; comme PostGreSQL ou MySQL sont incapable de procurer une sécurité suffisante :</p>
<li>les clefs sont généralement stockées en fichiers sur le serveur et non dans la base et sont par conséquent lisible par tout utilisateur ayant accès au serveur;</li>
<li>le chiffrement n&rsquo;est pas &laquo;&nbsp;salé&nbsp;&raquo; et par conséquent une attaque du code par analyse fréquentielle est possible;</li>
<li>ces serveurs ne permettent pas d&rsquo;utiliser des boitiers de type HSM, qui s&rsquo;avèrent particulièrement intéressant pour les données bancaires (code des cartes de paiement) ou de santé (données personnelles);</li>
<li>un service de chiffrement du stockage de type TDE n&rsquo;est pas intégré dans de tels serveur ce qui fait par exemple qu&rsquo;un fichier de données ou une sauvegarde volée donne tout le temps au voleur de déchiffrer par recoupement.</li>
<li>comme la clef ne figure pas dans la base, elle doit être transmise en clair dans les requêtes. Elle figure donc dans les routines (fonctions PG/PLSQL de PostGreSQL par exemple) comme dans les requêtes des appliciations clientes.</li>
<li>le code généré est généralement assez court et permet plus aisément une attaque</li>
<p><strong>Exemple de chiffrement de données dans les bases de données</strong> </p>
<p>Avec PostGreSQL, extension pgcrypto avec algorithme AES :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">CREATE</span> EXTENSION pgcrypto;<br />
<br />
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> T_NOM<br />
<span style="color: #66cc66;">&#40;</span>NOM &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">32</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp;NOM_CRYPTE &nbsp;bytea<span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_NOM <span style="color: #66cc66;">&#40;</span>NOM<span style="color: #66cc66;">&#41;</span> <br />
<span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'MARTIN'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'DUPONT'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'MARTIN'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'DURAND'</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<p>Cryptage :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">UPDATE</span> T_NOM<br />
<span style="color: #993333; font-weight: bold;">SET</span> &nbsp; &nbsp;NOM_CRYPTE <span style="color: #66cc66;">=</span> encrypt<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span>NOM <span style="color: #993333; font-weight: bold;">AS</span> bytea<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Le petit chat est mort.'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'aes'</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> T_NOM;<br />
<br />
NOM &nbsp; &nbsp; &nbsp; &nbsp;NOM_CRYPTE<br />
<span style="color: #808080; font-style: italic;">---------- ---------------------------------------------------------------</span><br />
MARTIN &nbsp; &nbsp; \<span style="color: #cc66cc;">212</span>\<span style="color: #cc66cc;">306</span>\<span style="color: #cc66cc;">335</span>\<span style="color: #cc66cc;">270</span>\<span style="color: #cc66cc;">27615</span>\<span style="color: #cc66cc;">334</span>\33021o\<span style="color: #cc66cc;">212</span>\<span style="color: #cc66cc;">271</span>\252a\<span style="color: #cc66cc;">277</span>\<span style="color: #cc66cc;">302</span><br />
DUPONT &nbsp; &nbsp; \<span style="color: #cc66cc;">343</span>\<span style="color: #cc66cc;">331</span>\<span style="color: #cc66cc;">307</span><span style="color: #66cc66;">-</span>\<span style="color: #cc66cc;">202</span>\<span style="color: #cc66cc;">203</span>\<span style="color: #cc66cc;">301</span><span style="color: #66cc66;">|</span><span style="color: #66cc66;">&#40;</span>\247M32<span style="color: #66cc66;">+</span>\<span style="color: #cc66cc;">177</span>\<span style="color: #cc66cc;">301</span>\<span style="color: #cc66cc;">265</span><br />
MARTIN &nbsp; &nbsp; \<span style="color: #cc66cc;">212</span>\<span style="color: #cc66cc;">306</span>\<span style="color: #cc66cc;">335</span>\<span style="color: #cc66cc;">270</span>\<span style="color: #cc66cc;">27615</span>\<span style="color: #cc66cc;">334</span>\33021o\<span style="color: #cc66cc;">212</span>\<span style="color: #cc66cc;">271</span>\252a\<span style="color: #cc66cc;">277</span>\<span style="color: #cc66cc;">302</span><br />
DURAND &nbsp; &nbsp; <span style="color: #cc66cc;">3513</span>\<span style="color: #cc66cc;">252</span>\<span style="color: #cc66cc;">23627</span>^M21<span style="color: #66cc66;">,</span><span style="color: #cc66cc;">3002</span><span style="color: #66cc66;">&#93;</span>w\<span style="color: #cc66cc;">326</span>\<span style="color: #cc66cc;">227</span></div></div>
<p>Décryptage :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> NOM<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span>decrypt<span style="color: #66cc66;">&#40;</span>NOM_CRYPTE<span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'Le petit chat est mort.'</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'aes'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">32</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> NOM_CLAIR<br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_NOM;<br />
<br />
NOM &nbsp; &nbsp; &nbsp; &nbsp;NOM_CLAIR<br />
<span style="color: #808080; font-style: italic;">---------- ---------------------------------------------------------------</span><br />
MARTIN &nbsp; &nbsp; MARTIN<br />
DUPONT &nbsp; &nbsp; DUPONT<br />
MARTIN &nbsp; &nbsp; MARTIN<br />
DURAND &nbsp; &nbsp; DURAND</div></div>
<p>Comme on le voit, le mot de passe de la clef de cryptage est passée en clair lors de l&rsquo;utilisation des fonctions de cryptage et décryptage.<br />
Le chiffrement de MARTIN a donné deux fois le même code, la longueur du code est d&rsquo;une quinzaine d&rsquo;octets&#8230;</p>
<p>Avec SQL Server (chiffrement intégré dans toutes les versions) algorithme AES :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- création d'une clef de cryptage de niveau base de données </span><br />
<span style="color: #808080; font-style: italic;">-- permettant la génération de clefs de cryptage interne</span><br />
<span style="color: #993333; font-weight: bold;">CREATE</span> MASTER <span style="color: #993333; font-weight: bold;">KEY</span> ENCRYPTION <span style="color: #993333; font-weight: bold;">BY</span> PASSWORD <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Le petit chat est mort.'</span>;<br />
<span style="color: #993333; font-weight: bold;">GO</span><br />
<br />
<span style="color: #808080; font-style: italic;">-- création d'une clef de cryptage avec algorithme ASE clef à 256 bits</span><br />
<span style="color: #993333; font-weight: bold;">CREATE</span> SYMMETRIC <span style="color: #993333; font-weight: bold;">KEY</span> MA_CLEF<br />
<span style="color: #993333; font-weight: bold;">WITH</span> ALGORITHM <span style="color: #66cc66;">=</span> AES_256 <br />
&nbsp; &nbsp; ENCRYPTION <span style="color: #993333; font-weight: bold;">BY</span> PASSWORD <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'P@ssw0rd !'</span>;<br />
<span style="color: #993333; font-weight: bold;">GO</span> &nbsp; &nbsp;<br />
<br />
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> T_NOM<br />
<span style="color: #66cc66;">&#40;</span>NOM &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">32</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp;NOM_CRYPTE &nbsp;VARBINARY<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">256</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_NOM <span style="color: #66cc66;">&#40;</span>NOM<span style="color: #66cc66;">&#41;</span> <br />
<span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'MARTIN'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'DUPONT'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'MARTIN'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'DURAND'</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<p>Cryptage :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- ouverture de la clef pour la session</span><br />
<span style="color: #808080; font-style: italic;">-- peut être fait côté serveur dans un déclencheur FOR LOGON et dans ce cas</span><br />
<span style="color: #808080; font-style: italic;">-- le mot de passe ne sera pas codé dans les applis ni transmis dans le réseau</span><br />
<span style="color: #993333; font-weight: bold;">OPEN</span> SYMMETRIC <span style="color: #993333; font-weight: bold;">KEY</span> MA_CLEF<br />
DECRYPTION <span style="color: #993333; font-weight: bold;">BY</span> PASSWORD <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'P@ssw0rd !'</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp;<br />
<span style="color: #808080; font-style: italic;">-- la fonction KEY_GUID permet de retrouver la clef primaire informatique </span><br />
<span style="color: #808080; font-style: italic;">-- (de type GUID) de la clef de cryptage pour pouvoir l'utiliser</span><br />
<span style="color: #993333; font-weight: bold;">UPDATE</span> T_NOM<br />
<span style="color: #993333; font-weight: bold;">SET</span> &nbsp; &nbsp;NOM_CRYPTE <span style="color: #66cc66;">=</span> ENCRYPTBYKEY<span style="color: #66cc66;">&#40;</span>KEY_GUID<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'MA_CLEF'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> NOM<span style="color: #66cc66;">&#41;</span>;</div></div>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> T_NOM;<br />
<br />
NOM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NOM_CRYPTE<br />
<span style="color: #808080; font-style: italic;">------------ ------------------------------------------------------------------------------------------------------------</span><br />
MARTIN &nbsp; &nbsp; &nbsp; 0x00AC31E101131E408D190F626A5F757801000000519DC1A3C61A63A66EA857F7E9BBE649E09989B0E718CDFE861BE27CFAEA68B8<br />
DUPONT &nbsp; &nbsp; &nbsp; 0x00AC31E101131E408D190F626A5F7578010000000BECCA5469AFF7771675C1D9FB7103A1807FE2430FBF1922C56A990CBC3BA6FF<br />
MARTIN &nbsp; &nbsp; &nbsp; 0x00AC31E101131E408D190F626A5F757801000000B496C2D5DC5D92D4303B05B86457042767CC4382F852B29BFA1B0A66BB566388<br />
DURAND &nbsp; &nbsp; &nbsp; 0x00AC31E101131E408D190F626A5F757801000000121A2325A435CD72E830B255089C25CA24CF0A7FD2C693F66819FE5493FDD0F0</div></div>
<p>Décryptage :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- la clef étant ouverte, on a pas besoin du mot de passe pour décryptage</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> NOM<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">CAST</span><span style="color: #66cc66;">&#40;</span>DECRYPTBYKEY<span style="color: #66cc66;">&#40;</span>NOM_CRYPTE<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">32</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> NOM_CLAIR<br />
<span style="color: #993333; font-weight: bold;">FROM</span> T_NOM;<br />
<br />
NOM &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;NOM_CLAIR<br />
<span style="color: #808080; font-style: italic;">------------ --------------</span><br />
MARTIN &nbsp; &nbsp; &nbsp; MARTIN<br />
DUPONT &nbsp; &nbsp; &nbsp; DUPONT<br />
MARTIN &nbsp; &nbsp; &nbsp; MARTIN<br />
DURAND &nbsp; &nbsp; &nbsp; DURAND &nbsp; &nbsp;<br />
<br />
CLOSE SYMMETRIC <span style="color: #993333; font-weight: bold;">KEY</span> MA_CLEF;</div></div>
<p>Le mot de passe de la clef n&rsquo;est pas passé pour crypter et décrypter. L&rsquo;ouverture de la clef peut être automatisée côté serveur par un déclencheur FOR LOGON.<br />
Le chiffrement de MARTIN a donné deux codes différents et la longueur du code est de 52 octets&#8230;<br />
On peut aussi utiliser un certificat à la place du mot de passe.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>
<p>L&rsquo;entreprise <a href="http://www.sqlspot.com">SQL Spot</a><br />
<strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a></p>
<p><img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL Server" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Calculs SQL avec des dates : age exact révolu et anniversaires&#8230;</title>
		<link>https://blog.developpez.com/sqlpro/p12468/langage-sql-norme/calculs-sql-avec-des-dates-age-exact-revolu-et-anniversaires</link>
		<comments>https://blog.developpez.com/sqlpro/p12468/langage-sql-norme/calculs-sql-avec-des-dates-age-exact-revolu-et-anniversaires#comments</comments>
		<pubDate>Wed, 05 Feb 2014 23:27:07 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[bases de données]]></category>
		<category><![CDATA[Langage SQL (norme)]]></category>
		<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[PostGreSQL]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=392</guid>
		<description><![CDATA[Parmi les requêtes les plus difficile à établir en SQL se trouve généralement les calculs temporels. Voici deux problématiques résolues, celle du calcul de l&#8217;âge révolu et celle de la recherche de personnes sont l&#8217;anniversaire est à souhaiter&#8230; pas si simple ! Tout d&#8217;abord, voici les données de nos exemples&#8230; D&#8217;abord la table : CREATE [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Parmi les requêtes les plus difficile à établir en SQL se trouve généralement les calculs temporels. Voici deux problématiques résolues, celle du calcul de l&rsquo;âge révolu et celle de la recherche de personnes sont l&rsquo;anniversaire est à souhaiter&#8230; pas si simple !<br />
<span id="more-392"></span></p>
<p><strong>Tout d&rsquo;abord, voici les données de nos exemples&#8230; </strong></p>
<p>D&rsquo;abord la table :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> T_PERSONNE_PRS<br />
<span style="color: #66cc66;">&#40;</span>PRS_ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">INT</span> <span style="color: #993333; font-weight: bold;">IDENTITY</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">,</span><br />
&nbsp;PRS_DATE_NAISSANCE &nbsp;<span style="color: #993333; font-weight: bold;">DATE</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">GO</span></div></div>
<p>Ensuite son alimentation, d&rsquo;abord avec plus de 40 000 lignes de personnes ayant des dates de naissances continues du 1/1/1900 à nos jours&#8230;</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">DECLARE</span> @D <span style="color: #993333; font-weight: bold;">DATE</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'1900-01-01'</span>;<br />
WHILE @D <span style="color: #66cc66;">&lt;=</span> <span style="color: #993333; font-weight: bold;">CURRENT_TIMESTAMP</span><br />
<span style="color: #993333; font-weight: bold;">BEGIN</span><br />
&nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_PERSONNE_PRS <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span>@D<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">SET</span> @D <span style="color: #66cc66;">=</span> DATEADD<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> @D<span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #993333; font-weight: bold;">END</span>;</div></div>
<p>Enfin, on y ajoutant des doublons pour la charge afin d&#039;effectuer des tests de performances :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">WITH</span> TN <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">AS</span> N<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">UNION</span> <span style="color: #993333; font-weight: bold;">ALL</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">SELECT</span> N <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; TN<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;N <span style="color: #66cc66;">&lt;</span> <span style="color: #cc66cc;">24</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> T_PERSONNE_PRS<br />
<span style="color: #993333; font-weight: bold;">SELECT</span> PRS_DATE_NAISSANCE<br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; TN<br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">CROSS</span> <span style="color: #993333; font-weight: bold;">JOIN</span> T_PERSONNE_PRS <span style="color: #993333; font-weight: bold;">AS</span> TP;</div></div>
<p>Ce qui remplit notre table avec plus d&#039;un million de lignes.</p>
<p><strong>Le calcul de l&rsquo;âge révolu</strong></p>
<p>Il fut calculer l&rsquo;âge en tenant compte du jour près par rapport à la date courante.<br />
Voici quelques approches malheureuses (fonctions SQL Server) :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- ceci est inexact... car imprécis jusqu'à 11 mois et 30 jours près !</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*,</span> DATEDIFF<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">YEAR</span><span style="color: #66cc66;">,</span> PRS_DATE_NAISSANCE<span style="color: #66cc66;">,</span> GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> AGE<br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS;<br />
<br />
<span style="color: #808080; font-style: italic;">-- ceci est inexact... car imprécis jusqu'à 30 jours près ! </span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*,</span> DATEDIFF<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">,</span> PRS_DATE_NAISSANCE<span style="color: #66cc66;">,</span> GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">/</span> <span style="color: #cc66cc;">12</span> <span style="color: #993333; font-weight: bold;">AS</span> AGE<br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS;<br />
<br />
<span style="color: #808080; font-style: italic;">-- ceci est inexact... car imprécis à 1 jours près ! </span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*,</span> <span style="color: #993333; font-weight: bold;">FLOOR</span><span style="color: #66cc66;">&#40;</span>DATEDIFF<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">,</span> PRS_DATE_NAISSANCE<span style="color: #66cc66;">,</span> GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">/</span> <span style="color: #cc66cc;">365.25</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> AGE<br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS;</div></div>
<p>Voici maintenant une formulation qui donne les réponses exactes :</p>
<p><em>Requête 1 :</em></p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span><span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span> % <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2013-11-20'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2013-11-20'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp; % <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2013-12-10'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">-</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2013-12-10'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">371</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; % <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<p>Les métriques de performances relevées (4 UC), sont les suivantes :<br />
&#8212; 1) Temps UC = 748 ms, temps écoulé = 8031 ms.<br />
&#8212; 2) Temps UC = 515 ms, temps écoulé = 7994 ms.<br />
&#8212; 3) Temps UC = 717 ms, temps écoulé = 7948 ms.<br />
&#8212; 4) Temps UC = 624 ms, temps écoulé = 7932 ms.</p>
<p><strong>La recherche des anniversaires</strong></p>
<p>Voici tout d&rsquo;abord quelques requêtes simples pour des cas triviaux :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- les personnes qui ont leur date d'anniversaire aujourd'hui</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> &nbsp;<span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; <br />
<span style="color: #808080; font-style: italic;">-- les personnes qui ont leur date de naissance dans 15 jours</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>DATEADD<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">15</span><span style="color: #66cc66;">,</span> GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; <span style="color: #993333; font-weight: bold;">AND</span> &nbsp;<span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>DATEADD<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">15</span><span style="color: #66cc66;">,</span> GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>; &nbsp;<br />
&nbsp; <br />
<span style="color: #808080; font-style: italic;">-- les personnes qui ont leur date d'anniversaire dans le mois courant</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #808080; font-style: italic;">-- les personnes qui ont leur date d'anniversaire dans le mois suivant le mois courant</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> % <span style="color: #cc66cc;">13</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">/</span> <span style="color: #cc66cc;">12</span>;<br />
<span style="color: #808080; font-style: italic;">-- notez le + 1 pour rechercher le mois suivant</span><br />
<br />
<span style="color: #808080; font-style: italic;">-- les personnes qui ont leur date d'anniversaire dans le 6e mois suivant le mois courant</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">6</span><span style="color: #66cc66;">&#41;</span> % <span style="color: #cc66cc;">13</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>GETDATE<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">/</span> <span style="color: #cc66cc;">12</span>;<br />
<span style="color: #808080; font-style: italic;">-- notez le + 6...</span></div></div>
<p>Nous allons maintenant rechercher les personnes qui ont leur date d&rsquo;anniversaire entre deux dates&#8230; </p>
<p>Voici tout d&rsquo;abord quelques cas triviaux :</p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- exemple 1 : 20 février / 10 mars</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&gt;=</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-02-20'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-02-20'</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&lt;=</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-03-10'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-03-10'</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- exemple 2 : 20 décembre / 10 janvier (an + 1)</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&gt;=</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-12-20'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-12-20'</span><span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">OR</span> &nbsp;<span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&lt;=</span> <span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2015-01-10'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2015-01-10'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #808080; font-style: italic;">-- notez la présence du OR à la place du AND, car nous avons changé d'année (l'intervalle s'est &quot;retourné&quot;) !</span></div></div>
<p>Et maintenant la solution générique :</p>
<p><em>Requête 2</em></p>
<div class="codecolorer-container sql default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">-- avec dates du 20 décembre au 10 janvier (an + 1)</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span> % <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-12-20'</span><span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-12-20'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp;% <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2015-01-10'</span><span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2015-01-10'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">372</span><span style="color: #66cc66;">&#41;</span> &nbsp;% <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #808080; font-style: italic;">-- &nbsp;avec dates du 20 février au 10 mars</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span><br />
<span style="color: #993333; font-weight: bold;">FROM</span> &nbsp; T_PERSONNE_PRS <br />
<span style="color: #993333; font-weight: bold;">WHERE</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span>PRS_DATE_NAISSANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#41;</span> % <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">BETWEEN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-02-20'</span><span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-02-20'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp;% <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">MONTH</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-03-10'</span><span style="color: #66cc66;">&#41;</span> &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">+</span> <span style="color: #993333; font-weight: bold;">DAY</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'2014-03-10'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">372</span><span style="color: #66cc66;">&#41;</span> &nbsp;% <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">31</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span>;</div></div>
<p>Les métriques de performances relevées (4 UC), sont les suivantes :<br />
&#8211;&gt; 1) Temps UC = 951 ms, temps écoulé = 677 ms.<br />
&#8211;&gt; 2) Temps UC = 967 ms, temps écoulé = 641 ms.<br />
&#8211;&gt; 3) Temps UC = 890 ms, temps écoulé = 638 ms.<br />
&#8211;&gt; 4) Temps UC = 905 ms, temps écoulé = 663 ms.</p>
<p>La question est maintenant&#8230; Y a t-il des formulations plus performantes ?</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>
<p>L&rsquo;entreprise <a href="http://www.sqlspot.com">SQL Spot</a><br />
<strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a></p>
<p><img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL Server" /></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Tri combiné dans un arbre intervallaire</title>
		<link>https://blog.developpez.com/sqlpro/p11925/langage-sql-norme/tri-combine-dans-un-arbre-intervallaire</link>
		<comments>https://blog.developpez.com/sqlpro/p11925/langage-sql-norme/tri-combine-dans-un-arbre-intervallaire#comments</comments>
		<pubDate>Thu, 18 Apr 2013 07:42:23 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[bases de données]]></category>
		<category><![CDATA[Langage SQL (norme)]]></category>
		<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[PostGreSQL]]></category>
		<category><![CDATA[arborescence]]></category>
		<category><![CDATA[chemin]]></category>
		<category><![CDATA[fratrie]]></category>
		<category><![CDATA[intervale]]></category>
		<category><![CDATA[intervallaire]]></category>
		<category><![CDATA[path]]></category>
		<category><![CDATA[sibling]]></category>
		<category><![CDATA[tri]]></category>
		<category><![CDATA[tri mixte]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=286</guid>
		<description><![CDATA[Trier des données dans le sens de l&#8217;arborescence et quand elle sont aux même niveau (frères) par ordre alphabétique (tri mixte arbre et alfa) est difficile à réaliser dans un arbre modélisé par intervalle. Mais le principe est assez simple. Il suffit de composer une nouvelle colonne constitué d&#8217;une alternance de nœud et d&#8217;ordre alphabétique [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Trier des données dans le sens de l&rsquo;arborescence et quand elle sont aux même niveau (frères) par ordre alphabétique (tri mixte arbre et alfa) est difficile à réaliser dans un arbre modélisé par intervalle. Mais le principe est assez simple. Il suffit de composer une nouvelle colonne constitué d&rsquo;une alternance de nœud et d&rsquo;ordre alphabétique relatif dans la fratrie, et de trier dessus. Voici comment faire. Cette technique s’appelle en anglais &laquo;&nbsp;sibling ordering&nbsp;&raquo;.<br />
<span id="more-286"></span> </p>
<p><strong>1 &#8211;  LE PROBLÈME</strong></p>
<p><strong>Voici notre jeu de test :</strong></p>
<p>Tout d&rsquo;abord la table</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">CREATE TABLE T_VEHICULE_VHC<br />
(VHC_ID &nbsp; &nbsp; &nbsp; &nbsp; INTEGER NOT NULL PRIMARY KEY,<br />
&nbsp;VHC_BG &nbsp; &nbsp; &nbsp; &nbsp; INTEGER,<br />
&nbsp;VHC_BD &nbsp; &nbsp; &nbsp; &nbsp; INTEGER,<br />
&nbsp;VHC_NIVEAU &nbsp; &nbsp; SMALLINT,<br />
&nbsp;VHC_NOM &nbsp; &nbsp; &nbsp; &nbsp;VARCHAR(16));</div></div>
<p>Et ses données :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">INSERT INTO T_VEHICULE_VHC VALUES ( 1, &nbsp;1, 26, 0, 'ALL');<br />
INSERT INTO T_VEHICULE_VHC VALUES ( 2, &nbsp;2, &nbsp;7, 1, 'SEA');<br />
INSERT INTO T_VEHICULE_VHC VALUES ( 3, &nbsp;8, 19, 1, 'EARTH');<br />
INSERT INTO T_VEHICULE_VHC VALUES ( 4, 20, 25, 1, 'AIR');<br />
INSERT INTO T_VEHICULE_VHC VALUES ( 5, &nbsp;3, &nbsp;4, 2, 'SUBMARINE');<br />
INSERT INTO T_VEHICULE_VHC VALUES ( 6, &nbsp;5, &nbsp;6, 2, 'BOAT');<br />
INSERT INTO T_VEHICULE_VHC VALUES ( 7, &nbsp;9, 10, 2, 'CAR');<br />
INSERT INTO T_VEHICULE_VHC VALUES ( 8, 11, 16, 2, 'TWO WHEELS');<br />
INSERT INTO T_VEHICULE_VHC VALUES ( 9, 17, 18, 2, 'TRUCK');<br />
INSERT INTO T_VEHICULE_VHC VALUES (10, 21, 22, 2, 'ROCKET');<br />
INSERT INTO T_VEHICULE_VHC VALUES (11, 23, 24, 2, 'PLANE');<br />
INSERT INTO T_VEHICULE_VHC VALUES (12, 12, 13, 3, 'MOTORCYCLE');<br />
INSERT INTO T_VEHICULE_VHC VALUES (13, 14, 15, 3, 'BICYCLE');</div></div>
<p><strong>Premier essai :</strong></p>
<p>Une simple requête telle que celle-ci :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT CAST(SPACE(VHC_NIVEAU) + VHC_NOM AS VARCHAR(32)) AS NOM_IDENTE, <br />
&nbsp; &nbsp; &nbsp; &nbsp;VHC_ID, VHC_BG, VHC_BD, VHC_NIVEAU<br />
FROM &nbsp; T_VEHICULE_VHC &nbsp;<br />
ORDER &nbsp;BY VHC_BG;</div></div>
<p>Donne un résultat insatisfaisant :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">NOM_IDENTE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; VHC_ID &nbsp; &nbsp; &nbsp;VHC_BG &nbsp; &nbsp; &nbsp;VHC_BD &nbsp; &nbsp; &nbsp;VHC_NIVEAU<br />
-------------------------------- ----------- ----------- ----------- ----------<br />
ALL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 26 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0<br />
&nbsp;SEA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; SUBMARINE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2<br />
&nbsp; BOAT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2<br />
&nbsp;EARTH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 19 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1<br />
&nbsp; CAR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 10 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br />
&nbsp; TWO WHEELS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 11 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;16 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br />
&nbsp; &nbsp;MOTORCYCLE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;12 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;12 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;13 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3<br />
&nbsp; &nbsp;BICYCLE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 13 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;14 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;15 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3<br />
&nbsp; TRUCK &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 17 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;18 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br />
&nbsp;AIR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 20 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;25 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1<br />
&nbsp; ROCKET &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 10 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;21 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;22 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br />
&nbsp; PLANE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;11 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;23 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;24 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2</div></div>
<p>Au niveau 1, &laquo;&nbsp;SEA&nbsp;&raquo; est avant &laquo;&nbsp;EARTH&nbsp;&raquo; qui lui même est avant &laquo;&nbsp;AIR&nbsp;&raquo;. Dans les deux roues (&laquo;&nbsp;TWO WHEELS&nbsp;&raquo;), &laquo;&nbsp;MOTORCYCLE&nbsp;&raquo; précède &laquo;&nbsp;BICYCLE&nbsp;&raquo;. Enfin, &laquo;&nbsp;CAR&nbsp;&raquo;, &laquo;&nbsp;TWO WHEELS&nbsp;&raquo; et &laquo;&nbsp;TRUCK&nbsp;&raquo; sont mélangés.<br />
Il n&rsquo;est pas possible d&rsquo;obtenir un meilleur ordonnancement directement basé sur les valeurs des colonnes actuelles de la table.</p>
<p>Mais la technique de l&rsquo;arbre intervallaire permet d&rsquo;ordonner les frères entre eux. Il suffit donc de bouger les bornes droites et gauches pour que cela corresponde à l&rsquo;ordre demandé. </p>
<p><strong>2 &#8211; PREMIÈRE SOLUTION</strong></p>
<p>Elle consiste donc à réordonner les bornes gauche et droite.</p>
<p>La nouvelle table pour ce faire :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">CREATE TABLE T_VEHICULE2_VHC<br />
(VHC_ID &nbsp; &nbsp; &nbsp; &nbsp; INTEGER NOT NULL PRIMARY KEY,<br />
&nbsp;VHC_BG &nbsp; &nbsp; &nbsp; &nbsp; INTEGER,<br />
&nbsp;VHC_BD &nbsp; &nbsp; &nbsp; &nbsp; INTEGER,<br />
&nbsp;VHC_NIVEAU &nbsp; &nbsp; SMALLINT,<br />
&nbsp;VHC_NOM &nbsp; &nbsp; &nbsp; &nbsp;VARCHAR(16));</div></div>
<p>Les données réarrangées :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">INSERT INTO T_VEHICULE2_VHC VALUES ( 1, &nbsp;1, 26, 0, 'ALL');<br />
INSERT INTO T_VEHICULE2_VHC VALUES ( 2, 20, 25, 1, 'SEA');<br />
INSERT INTO T_VEHICULE2_VHC VALUES ( 3, &nbsp;8, 19, 1, 'EARTH');<br />
INSERT INTO T_VEHICULE2_VHC VALUES ( 4, &nbsp;2, &nbsp;7, 1, 'AIR');<br />
INSERT INTO T_VEHICULE2_VHC VALUES ( 5, 23, 24, 2, 'SUBMARINE');<br />
INSERT INTO T_VEHICULE2_VHC VALUES ( 6, 21, 22, 2, 'BOAT');<br />
INSERT INTO T_VEHICULE2_VHC VALUES ( 7, &nbsp;9, 10, 2, 'CAR');<br />
INSERT INTO T_VEHICULE2_VHC VALUES ( 8, 13, 18, 2, 'TWO WHEELS');<br />
INSERT INTO T_VEHICULE2_VHC VALUES ( 9, 11, 12, 2, 'TRUCK');<br />
INSERT INTO T_VEHICULE2_VHC VALUES (10, &nbsp;5, &nbsp;6, 2, 'ROCKET');<br />
INSERT INTO T_VEHICULE2_VHC VALUES (11, &nbsp;3, &nbsp;4, 2, 'PLANE');<br />
INSERT INTO T_VEHICULE2_VHC VALUES (12, 16, 17, 3, 'MOTORCYCLE');<br />
INSERT INTO T_VEHICULE2_VHC VALUES (13, 14, 15, 3, 'BICYCLE');</div></div>
<p>La requête :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">SELECT CAST(SPACE(VHC_NIVEAU) + VHC_NOM AS VARCHAR(32)) AS NOM_IDENTE, <br />
&nbsp; &nbsp; &nbsp; &nbsp;VHC_ID, VHC_BG, VHC_BD, VHC_NIVEAU<br />
FROM &nbsp; T_VEHICULE2_VHC &nbsp;<br />
ORDER &nbsp;BY VHC_BG;</div></div>
<p>Le résultat :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">NOM_IDENTE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; VHC_ID &nbsp; &nbsp; &nbsp;VHC_BG &nbsp; &nbsp; &nbsp;VHC_BD &nbsp; &nbsp; &nbsp;VHC_NIVEAU<br />
-------------------------------- ----------- ----------- ----------- ----------<br />
ALL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 26 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0<br />
&nbsp;AIR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1<br />
&nbsp; PLANE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;11 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2<br />
&nbsp; ROCKET &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 10 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2<br />
&nbsp;EARTH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 19 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1<br />
&nbsp; CAR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 10 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br />
&nbsp; TRUCK &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 11 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;12 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br />
&nbsp; TWO WHEELS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 13 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;18 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br />
&nbsp; &nbsp;BICYCLE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 13 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;14 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;15 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3<br />
&nbsp; &nbsp;MOTORCYCLE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;12 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;16 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;17 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3<br />
&nbsp;SEA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 20 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;25 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1<br />
&nbsp; BOAT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 21 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;22 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2<br />
&nbsp; SUBMARINE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 23 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;24 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2</div></div>
<p><strong>Critique de la première solution</strong></p>
<p>La requête finale est simple. En revanche le coût est reporté lors des mises à jours (généralement peu nombreuses dans les arborescences) mais cela oblige souvent à réordonner tout l&rsquo;arbre (ce qui peut se minimiser en modélisant l&rsquo;arbre intervallaire à côté de la table contenant les données).<br />
De plus, elle n&rsquo;est pas satisfaisante si d&rsquo;autres colonnes complique la structure de la table et qu&rsquo;il faut en tenir compte dans la solution (par exemple de multiples arborescences).</p>
<p><strong>3 &#8211; UNE SOLUTION GÉNÉRIQUE</strong></p>
<p>Il existe une façon de faire globale, mais elle nécessite hélas une requête récursive en sus d&rsquo;être gourmande en données. Cette solution consiste à rajouter un &laquo;&nbsp;chemin&nbsp;&raquo; composé d&rsquo;une mixité de données comprenant les ancêtres alternés avec la position ordinale des frères entre eux. Pour la faire fonctionner correctement il est nécessaire d&rsquo;utiliser une fonction de remplissage que j&rsquo;ai intitulé PADMASK :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">--===========================================================================--<br />
-- Masque de caractères avec fusion alignée<br />
--===========================================================================--<br />
CREATE FUNCTION &nbsp;[F_PADMASK](@DATA NVARCHAR(1024), <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;@MASK NVARCHAR(1024),<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;@ALIGN CHAR(6))<br />
RETURNS NVARCHAR(1024)<br />
AS<br />
/****************************************************************************** <br />
* Fonction de masque pour une donées polymorphe retournée en chaine de car. &nbsp; *<br />
******************************************************************************* <br />
* Fred. Brouard - http://sqlpro.developpez.com - www.sqlspot.com - 2012-07-12 * <br />
*******************************************************************************<br />
* Fusionne une donnée chaine avec un masque aligné à droite ou à gauche &nbsp; &nbsp; &nbsp; * <br />
* Exemples : &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;*<br />
* SELECT dbo.F_PADMASK('ABC', '*****', 'LEFT' ) &nbsp; --&amp;gt; 'ABC**' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *<br />
* SELECT dbo.F_PADMASK(123, '00000', 'RIGHT') &nbsp; &nbsp; --&amp;gt; '00123' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *<br />
* SELECT dbo.F_PADMASK('ABCDEFG', '***', 'LEFT') &nbsp;--&amp;gt; 'EFG' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *<br />
* SELECT dbo.F_PADMASK('ABCDEFG', '***', 'RIGHT') --&amp;gt; 'ABC' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; *<br />
******************************************************************************/ <br />
BEGIN<br />
&nbsp; &nbsp;IF @MASK IS NULL RETURN '';<br />
&nbsp; &nbsp;IF @DATA IS NULL RETURN @MASK;<br />
&nbsp; &nbsp;IF UPPER(@ALIGN) IN ('RIGHT', 'DROIT', 'DROITE')<br />
&nbsp; &nbsp; &nbsp; SET @ALIGN = 'RIGHT'<br />
&nbsp; &nbsp;ELSE<br />
&nbsp; &nbsp; &nbsp; SET @ALIGN = 'LEFT'; &nbsp; &nbsp;<br />
-- masque avec alignement à gauche (alpha) &nbsp; <br />
&nbsp; &nbsp;IF @ALIGN = 'LEFT'<br />
&nbsp; &nbsp;BEGIN<br />
&nbsp; &nbsp; &nbsp; IF LEN(@MASK) &amp;gt; LEN(@DATA)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SET @DATA = @DATA + SUBSTRING(@MASK, LEN(@DATA) + 1, LEN(@MASK) - LEN(@DATA));<br />
&nbsp; &nbsp; &nbsp; IF LEN(@MASK) &nbsp;LEN(@DATA)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SET @DATA = SUBSTRING(@MASK, 1, LEN(@MASK) - LEN(@DATA)) + @DATA;<br />
&nbsp; &nbsp; &nbsp; IF LEN(@MASK) &amp;lt; LEN(@DATA)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SET @DATA = SUBSTRING(@DATA, LEN(@DATA) - LEN(@MASK) + 1, LEN(@MASK));<br />
&nbsp; &nbsp;END;<br />
&nbsp; &nbsp;RETURN @DATA; &nbsp; <br />
END<br />
GO</div></div>
<p><strong>NOTA</strong> : la fonction F_PADMASK a été écrite pour MS SQL Server, et peut aisément être traduite en PGPL/SQL pour PostGreSQL.</p>
<p>Voici maintenant la requête :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">WITH <br />
TA AS -- crée un indice numérique global d'ordonnancement alphabétique des libellés et le transforme en chaine complété avec des zéros<br />
(SELECT VHC_ID, VHC_BG, VHC_BD, VHC_NIVEAU, VHC_NOM, <br />
&nbsp; &nbsp; &nbsp; &nbsp; dbo.F_PADMASK(CAST(ROW_NUMBER() OVER(ORDER BY VHC_NOM) AS VARCHAR(10)), '00000000000', 'RIGHT') &nbsp;AS ORDRE<br />
&nbsp;FROM &nbsp; T_VEHICULE_VHC),<br />
T0 AS -- concatène un mixte de chemin et d'indice alphabétique dans une colonne intitulée PATH_MIXTE<br />
(SELECT VHC_ID, VHC_BG, VHC_BD, VHC_NIVEAU, VHC_NOM, ORDRE, <br />
&nbsp; &nbsp; &nbsp; &nbsp; CAST(dbo.F_PADMASK(VHC_NOM, '****************', 'LEFT') + ORDRE AS NVARCHAR(max)) AS PATH_MIXTE<br />
&nbsp;FROM &nbsp; TA<br />
&nbsp;WHERE &nbsp;VHC_NIVEAU = 0<br />
&nbsp;UNION ALL<br />
&nbsp;SELECT T1.VHC_ID, T1.VHC_BG, T1.VHC_BD, T1.VHC_NIVEAU, T1.VHC_NOM, T1.ORDRE, <br />
&nbsp; &nbsp; &nbsp; &nbsp; T0.PATH_MIXTE + dbo.F_PADMASK(T1.VHC_NOM, '****************', 'LEFT') + T1.ORDRE<br />
&nbsp;FROM &nbsp; TA AS T1<br />
&nbsp; &nbsp; &nbsp; &nbsp; INNER JOIN T0 <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ON T1.VHC_NIVEAU = T0.VHC_NIVEAU + 1<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AND T1.VHC_BG &amp;gt; T0.VHC_BG<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AND T1.VHC_BD &amp;lt; T0.VHC_BD)<br />
SELECT CAST(SPACE(VHC_NIVEAU) + VHC_NOM AS VARCHAR(32)) AS NOM_IDENTE, <br />
&nbsp; &nbsp; &nbsp; &nbsp;VHC_ID, VHC_BG, VHC_BD, VHC_NIVEAU, PATH_MIXTE<br />
FROM &nbsp; T0 &nbsp;<br />
ORDER &nbsp;BY PATH_MIXTE;</div></div>
<p>Comme indiqué, la colonne surnuméraire de tri, PATH_MIXTE, va contenir le chemin jusqu&rsquo;au nœud en cours avec entre chaque nom d&rsquo;élément sa position relative dans la fratrie. Le nécessité d&rsquo;utiliser la fonction de remplissage est lié au fait que notre colonne de tri contient une alternance de données numérique et alphabétique qu&rsquo;il faut ordonner ensemble. or les nombres sont alignés à droite et les mots à gauche. la fonction F_PADMASK permet de coordonner ces alignements. On comprend mieux la chose en voyant ce quelle contient :</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">NOM_IDENTE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;VHC_ID &nbsp; &nbsp; &nbsp;VHC_BG &nbsp; &nbsp; &nbsp;VHC_BD &nbsp; &nbsp; &nbsp;VHC_NIVEAU PATH_MIXTE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
------------------- ----------- ----------- ----------- ---------- ------------------------------------------------------------------------------------------------------------<br />
ALL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 26 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002<br />
&nbsp;AIR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 20 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;25 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002AIR*************00000000001<br />
&nbsp; PLANE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 11 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;23 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;24 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002AIR*************00000000001PLANE***********00000000008<br />
&nbsp; ROCKET &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;10 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;21 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;22 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002AIR*************00000000001ROCKET**********00000000009<br />
&nbsp;EARTH &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 19 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002EARTH***********00000000006<br />
&nbsp; CAR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 10 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002EARTH***********00000000006CAR*************00000000005<br />
&nbsp; TRUCK &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 9 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 17 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;18 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002EARTH***********00000000006TRUCK***********00000000012<br />
&nbsp; TWO WHEELS &nbsp; &nbsp; &nbsp; &nbsp;8 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 11 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;16 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002EARTH***********00000000006TWO WHEELS******00000000013<br />
&nbsp; &nbsp;BICYCLE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;13 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;14 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;15 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002EARTH***********00000000006TWO WHEELS******00000000013BICYCLE*********00000000003<br />
&nbsp; &nbsp;MOTORCYCLE &nbsp; &nbsp; &nbsp; 12 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;12 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;13 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002EARTH***********00000000006TWO WHEELS******00000000013MOTORCYCLE******00000000007<br />
&nbsp;SEA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002SEA*************00000000010<br />
&nbsp; BOAT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 6 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002SEA*************00000000010BOAT************00000000004<br />
&nbsp; SUBMARINE &nbsp; &nbsp; &nbsp; &nbsp; 5 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ALL*************00000000002SEA*************00000000010SUBMARINE*******00000000011</div></div>
<p><strong>NOTA</strong> : le nombre de caractères de remplissage pour la partie alphabétique (ici colonne VHC_NOM) dépend de la longueur de la colonne (ici 16) définit à la construction de la table.</p>
<p><strong>ATTENTION</strong> : Certaines formulations, comme celle données ici sur Internet &laquo;&nbsp;<a href="http://stackoverflow.com/questions/2834156/ordering-recursive-result-set-in-sql-server" title="Ordering recursive result set in SQL Server">Ordering recursive result set in SQL Server</a>&nbsp;&raquo; sont fausses. Je vous laisse deviner pourquoi !</p>
<p><strong>Le site web sur le </strong><a href="http://sqlpro.developpez.com/">SQL et les SGBDR</a><br />
<img src="http://blog.developpez.com/media/Microsoft_MVP_logo_vertical Brouard 400.jpg" width="400" height="135" alt="MVP Microsoft SQL Server" /></p>
<pre>

<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES<br />
Expert &nbsp;S.G.B.D &nbsp;relationnelles &nbsp; et &nbsp; langage &nbsp;S.Q.L<br />
Moste &nbsp;Valuable &nbsp;Professionnal &nbsp;Microsoft &nbsp;SQL Server<br />
Société SQLspot &nbsp;: &nbsp;modélisation, conseil, formation,<br />
optimisation, &nbsp;audit, &nbsp;tuning, &nbsp;administration &nbsp;SGBDR<br />
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.</div></div>

</pre>
<p>L&rsquo;ntreprise <a href="http://www.sqlspot.com">SQL Spot</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
