<?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; modélisation</title>
	<atom:link href="https://blog.developpez.com/sqlpro/ptag/modelisation/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>20 requêtes pour auditer la qualité de la structure de votre base de données</title>
		<link>https://blog.developpez.com/sqlpro/p12963/ms-sql-server/20-requetes-pour-auditer-la-qualite-de-la-structure-de-votre-base-de-donnees</link>
		<comments>https://blog.developpez.com/sqlpro/p12963/ms-sql-server/20-requetes-pour-auditer-la-qualite-de-la-structure-de-votre-base-de-donnees#comments</comments>
		<pubDate>Mon, 07 Dec 2015 00:19:12 +0000</pubDate>
		<dc:creator><![CDATA[SQLpro]]></dc:creator>
				<category><![CDATA[MS SQL Server]]></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[audit]]></category>
		<category><![CDATA[modele de données]]></category>
		<category><![CDATA[modélisation]]></category>
		<category><![CDATA[qualité]]></category>
		<category><![CDATA[SQL server]]></category>
		<category><![CDATA[structure]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/sqlpro/?p=637</guid>
		<description><![CDATA[Voici 20 requêtes permettant d&#8217;auditer la qualité de la structure de votre base de données, autrement dit son modèle. Ces 20 requêtes sont le fruit de mon expérience à faire des audits de bases de données et de serveurs SQL depuis maintenant plus de quinze ans. La présentation a eu lieu aux journées SQL Server [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Voici 20 requêtes permettant d&rsquo;auditer la qualité de la structure de votre base de données, autrement dit son modèle.<br />
Ces 20 requêtes sont le fruit de mon expérience à faire des audits de bases de données et de serveurs SQL depuis maintenant plus de quinze ans.</p>
<p><span id="more-637"></span></p>
<p>La présentation a eu lieu aux journées SQL Server qui ont eu lieu les lundi 30 novembre et mardi 1er décembre 2015 chez Microsoft France à Issy les Moulineaux.<br />
Les journées SQL Server sont organisées par le GUSS (Groupe des Utilisateurs de SQL Server) une association française.</p>
<p>Vous trouverez la présentation <a href="http://blog.developpez.com/sqlpro/files/2015/12/20-requetes-pour-auditer-la-structure-de-votre-base-de-donnees-PPT.pdf">ICI sous forme de Power Point &laquo;&nbsp;pdfisée&nbsp;&raquo;.</a><br />
Vous trouverez les 20 requêtes <a href="http://blog.developpez.com/sqlpro/files/2015/12/20-requetes-pour-auditer-la-structure-de-votre-base-de-donnees-SQL.pdf">ICI sous forme de fichier texte/sql aussi &laquo;&nbsp;pdfisé&nbsp;&raquo;</a></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>2</slash:comments>
		</item>
	</channel>
</rss>
