<?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>davideferrero.com &#187; DB</title>
	<atom:link href="http://blog.davideferrero.com/tag/db/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.davideferrero.com</link>
	<description>&#62; Web developer for passion</description>
	<lastBuildDate>Sun, 13 Nov 2011 15:55:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Differenze tra il tipo char e il varchar in MySQL</title>
		<link>http://blog.davideferrero.com/2010/05/differenze-char-varchar-mysql/</link>
		<comments>http://blog.davideferrero.com/2010/05/differenze-char-varchar-mysql/#comments</comments>
		<pubDate>Sun, 30 May 2010 17:28:34 +0000</pubDate>
		<dc:creator>davide</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Char]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Varchar]]></category>

		<guid isPermaLink="false">http://blog.davideferrero.com/?p=451</guid>
		<description><![CDATA[Prosegue il mio lavoro insieme a MySQL, ormai lo sto usando intensamente in molti programmi non solo in php, ma anche nella programmazione in java. Usandolo così massicciamente sto continuando a scoprire cose interessanti. Probabilmente quella di cui vi parlo oggi, non è una novità per qualcuno, ma credo sia bene chiarirla per chi non [...]]]></description>
			<content:encoded><![CDATA[<p>Prosegue il mio lavoro insieme a MySQL, ormai lo sto usando intensamente in molti programmi non solo in php, ma anche nella programmazione in java.</p>
<p>Usandolo così massicciamente sto continuando a scoprire cose interessanti. Probabilmente quella di cui vi parlo oggi, non è una novità per qualcuno, ma credo sia bene chiarirla per chi non lo sapesse.</p>
<p>Qualche giorno fa stavo lavorando su un database che non ho creato io e mi sono imbattuto in un campo <strong>CHAR</strong>. Subito non ci ho fatto caso, ma poi mi è venuto in mente che di solito quando devo dichiarare un campo stringa, uso il tipo <strong>VARCHAR</strong>. Mi sono così documentato un po&#8217;, cercando su google ho trovato diverse spiegazioni su forum, ma come sapete di quello che viene detto sui forum è sempre meglio non fidarsi troppo. Ho fatto quindi direttamente riferimento alla <a title="MySQL reference manual" href="http://dev.mysql.com/doc/refman/5.1/en/" target="_blank">guida ufficiale MySQL (in inglese)</a> e ho scoperto quello che mi interessava.</p>
<p>Innanzitutto prima di MySQL 5.0.3 sia il tipo <strong>char</strong> sia il <strong>varchar</strong> potevano essere dimensionati da 0 a 255 caratteri. Da MySQL 5.0.3 in poi il tipo <strong>varchar</strong> supporta lunghezza da 0 a 65535 caratteri. Oltre a questa differenza di dimensionamento c&#8217;è un&#8217;altra sostanziale differenza: quando dimensionate un campo con il tipo <strong>char</strong>, ad esempio char(4) verrà effettivamente occupato spazio per 4 caratteri, anche se il valore che inserirete nel campo sarà di un solo carattere. Lo spazio rimanente verrà riempito con degli spazi. A differenza del <strong>char</strong>, il <strong>varchar</strong> invece utilizza solamente lo spazio necessario, richiesto dal valore inserito nel campo più un byte (non sono riuscito a trovare il motivo, ma credo sia il famoso &#8220;tappo&#8221; in stile C).</p>
<p>Riepilogando quindi:</p>
<table border="1">
<tbody>
<tr>
<td><strong>Valore</strong></td>
<td><code>CHAR(4)</code></td>
<td><strong>Spazio richiesto<br />
</strong></td>
<td><code>VARCHAR(4)</code></td>
<td><strong>Spazio richiesto<br />
</strong></td>
</tr>
<tr>
<td><code>''</code></td>
<td><code>'    '</code></td>
<td>4 bytes</td>
<td><code>''</code></td>
<td>1 byte</td>
</tr>
<tr>
<td><code>'ab'</code></td>
<td><code>'ab  '</code></td>
<td>4 bytes</td>
<td><code>'ab'</code></td>
<td>3 bytes</td>
</tr>
<tr>
<td><code>'abcd'</code></td>
<td><code>'abcd'</code></td>
<td>4 bytes</td>
<td><code>'abcd'</code></td>
<td>5 bytes</td>
</tr>
<tr>
<td><code>'abcdefgh'</code></td>
<td><code>'abcd'</code></td>
<td>4 bytes</td>
<td><code>'abcd'</code></td>
<td>5 bytes</td>
</tr>
</tbody>
</table>
<p>Per finire, come si può vedere nell&#8217;ultima riga dell&#8217;esempio, per tutti e due i tipi, se il valore supera la lunghezza effettiva dichiarata, esso verrà troncato.</p>
<p>In sostanza se sapete che nel campo che state dichiarando dovrete inserire valori sempre della stessa lunghezza, senza eccezioni, potrebbe essere intelligente dichiararlo <strong>char</strong> mentre invece se, come succede nella stragrande maggioranza dei casi, il campo che state dichiarando conterrà stringhe generiche, allora vi converrà utilizzare il tipo <strong>varchar</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.davideferrero.com/2010/05/differenze-char-varchar-mysql/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Un tool open source per la progettazione dei database</title>
		<link>http://blog.davideferrero.com/2009/12/un-tool-open-source-per-la-progettazione-dei-database/</link>
		<comments>http://blog.davideferrero.com/2009/12/un-tool-open-source-per-la-progettazione-dei-database/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 15:15:05 +0000</pubDate>
		<dc:creator>davide</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Utility]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[ER]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[SQL Progettazione]]></category>

		<guid isPermaLink="false">http://blog.davideferrero.com/?p=311</guid>
		<description><![CDATA[Ogni buon programmatore che si rispetti sa che non si può creare un database dal nulla. Proprio i database sono alla base di qualsiasi software degno di nota, e sono indispensabili per la realizzazione di un sito web. Da buon fanatico di progetti open source, ma soprattutto dell&#8217;ambiente php-mysql per la creazione di web application [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="aligncenter" title="MySQL Workbench" src="http://lh4.ggpht.com/__IYVAt3JPe8/SyUR8pcbT6I/AAAAAAAAB6I/7ONtTszU-x4/s400/workbench.png" alt="" width="400" height="209" /></p>
<p>Ogni buon programmatore che si rispetti sa che non si può creare un database dal nulla. Proprio i database sono alla base di qualsiasi software degno di nota, e sono indispensabili per la realizzazione di un sito web.</p>
<p>Da buon fanatico di progetti open source, ma soprattutto dell&#8217;ambiente php-mysql per la creazione di web application mi sono dato da fare nel <a href="http://en.wikipedia.org/wiki/Google_%28verb%29" target="_blank">mio sport preferito</a> e ho trovato un tool davvero interessante.</p>
<p>Si chiama <a href="http://wb.mysql.com/" target="_blank">MySQL workbench</a> e proviene dagli stessi laboratori dai quali ci viene fornito uno dei DBMS open source più conosciuti al mondo. E&#8217; da qualche mese che lo uso ogni volta in cui ho bisogno di realizzare un db, a lavoro o a casa e lo trovo davvero utile e funzionale. Che cos&#8217;è workbench? Semplice! Un sw che consente di progettare un database, partendo dalla realizzazione dello schema E-R e risparmiando molto lavoro a noi poveri programmatori.</p>
<p style="text-align: center;"><img class="aligncenter" title="ER Schema" src="http://lh4.ggpht.com/__IYVAt3JPe8/SzOEiLMikpI/AAAAAAAAB7Q/AuFJmsTAgrU/s400/workbench_visual_design_linux.png" alt="" width="400" height="296" /></p>
<p>In sostanza basta disegnare lo schema del database inserendo tabelle, chiavi primarie, chiavi esterne, indici, trigger, viste e chi più ne ha più ne metta, e workbench farà per noi tutto il resto. Una volta disegnato lo schema infatti, sarà possibile esportare la struttura del db creato e reimportarla nel nostro DBMS. Io uso abitualmente MySQL e workbench mi permette di esportare in un file .sql le query di creazione della mia base dati, pienamente compatibili con questo DBMS, e di creare con una <em>import</em> il database vero e proprio.</p>
<p>Esiste in due versioni, la community e la standard, la prima rilasciata gratuitamente sotto licenza GPL mentre la seconda a pagamento (e con alcune funzionalità in più) al costo di 79$ per svillupatore per anno. Ovviamente non mi sono potuto permettere di acquistare la versione standard, ma la community svolge il suo egregio lavoro in maniera impeccabile.</p>
<p>Dimenticavo, workbench è multipiattaforma ossia esiste nella versione per Linux (comodo pacchetto debian autoinstallante, o rpm), nella versione per Mac OS X e nella versione per Windows in modo che nessuno possa lamentarsi e tutti possano progettare in tutta serenità i propri database sul proprio sistema preferito.</p>
<p>Direi che non vi resta che <a href="http://dev.mysql.com/downloads/workbench/5.0.html" target="_blank">provarlo</a>!<br />
[ad]</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.davideferrero.com/2009/12/un-tool-open-source-per-la-progettazione-dei-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Indici Full Text in MySQL</title>
		<link>http://blog.davideferrero.com/2009/10/indici-full-text-in-mysql/</link>
		<comments>http://blog.davideferrero.com/2009/10/indici-full-text-in-mysql/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 21:33:58 +0000</pubDate>
		<dc:creator>davide</dc:creator>
				<category><![CDATA[Informatica]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Algoritmi]]></category>
		<category><![CDATA[DB]]></category>
		<category><![CDATA[Full Text]]></category>
		<category><![CDATA[Indici]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programmazione]]></category>

		<guid isPermaLink="false">http://blog.davideferrero.com/?p=217</guid>
		<description><![CDATA[Post da nerd, astenersi perditempo&#8230; :-P [NERD MODE ON] Alcuni giorni fa sul lavoro mi sono cimentato in un nuovo esperimento. Tutto è partito dal problema di dover indicizzare dei contenuti, sui quali poi eseguira una ricerca &#8220;generica&#8221; in stile google (ovvero un unico campo che riceve un insieme di parole, che possono corrispondere a [...]]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter" title="Php MySQL" src="http://lh5.ggpht.com/__IYVAt3JPe8/SuIPro8wh8I/AAAAAAAABys/XcqeHmFBZmY/s800/hosting-php-mysql.jpg" alt="" width="333" height="225" /></p>
<p>Post da <em>nerd</em>, astenersi perditempo&#8230; :-P</p>
<p><strong>[NERD MODE ON]</strong></p>
<p>Alcuni giorni fa sul lavoro mi sono cimentato in un nuovo esperimento.</p>
<p>Tutto è partito dal problema di dover indicizzare dei contenuti, sui quali poi eseguira una ricerca &#8220;generica&#8221; in stile google (ovvero un unico campo che riceve un insieme di parole, che possono corrispondere a diversi campi del db).</p>
<p>Bene non voglio stare qui a spiegare nei dettagli la soluzione che abbiamo deciso di adottare, ma in sostanza mi sono ritrovato con un campo testuale con dentro tutte le parole che corrispondono ad una chiave.</p>
<p>Ok, e ora? L&#8217;idea iniziale è stata quella di eseguire una query con &#8221; <em>LIKE &#8216;%parola%&#8217; </em>&#8221; in <em>OR</em> con altre <em>LIKE</em> simili, per ogni parola inserita dall&#8217;utente. Una volta implementata, tutto funzionava (avevo 3 record in quella tabella). Siccome per scrupolo avevo anche implementato un timer che misurasse il tempo di esecuzione, ho provato a fare un test <strong>pesante</strong>&#8230; Con python mi sono creato un programma per scrivere su file qualche centinaia di query di inserimento su quella tabella, lo eseguo e popolo il db. Ora ci sono 1000 record (non sono ancora abbastanza ma rende già l&#8217;idea), rilancio la ricerca e il timer segna 0,3 secondi. Buono no? sì ma sono 1000 record, se mai i record dovessero essere 100K o ancora di più? Mmm non mi soddisfa questa cosa. *Googleing*&#8230;.*Googleing*&#8230;.*Googleing* <strong>FULL TEXT INDEX</strong></p>
<p>Cos&#8217;è? In <a href="http://www.mysql.it" target="_blank">MySQL</a> è possibile definire su un campo di una tabella, un indice FULL TEXT, ovvero una struttura che indicizza in maniera ottimale tutte le parole presenti in uno o più campi. Ci sono <em>alcune restrizioni</em> però. Quella più importante è che la tabella non può essere creata con il motore InnoDB (il più comune perchè supporta query multiple in una singola transazione). Inoltre le stringhe da cercare con le query dovranno avere più di 3 caratteri (altrimenti bisogna andare a modificare le impostazioni di MySQL, cosa impossibile se non si ha accesso al server, e comunque relativamente complicata da fare).</p>
<p>Detto ciò i passi da fare sono i seguenti:<br />
<em> Definiamo la tabella e l&#8217;indice:</em></p>
<pre class="brush: sql; title: ;">CREATE TABLE test (
id INT UNSIGNED   AUTO_INCREMENT NOT NULL PRIMARY KEY,
keywords TEXT,
[keywords2] VARCHAR(255),
FULLTEXT (keywords[,keywords2])
);</pre>
<p>[Tra le parentesi quadre ho messo il secondo campo, spero si capisca che è opzionale...]</p>
<p>Fatto questo e dopo aver popolato la tabella, possiamo provare la nostra ricerca con la seguente query:</p>
<pre class="brush: sql; title: ;">SELECT * FROM test WHERE MATCH(keywords) AGAINST('pippo')</pre>
<p>In questo modo andremo a dire a MySQL di cercarci l&#8217;esatta parola &#8216;pippo&#8217; all&#8217;interno del campo keywords.</p>
<p>Una cosa che non si trova facilmente nelle guide che ho seguito (ho fatto perciò riferimento alla documentazione ufficiale di MySQL) è che così facendo si effettua una ricerca in <em>linguaggio naturale</em>, che è ottimale per indicizzare frasi di senso (più o meno) compiuto. Il &#8220;difetto&#8221; se può definirsi così, è che con questo tipo di ricerca alcune parole non verranno trovate, infatti MySQL utilizza un array di <em>stopwords</em> che verranno saltate a piè pari dalla ricerca. Per effettuare una ricerca su tutte le parole e utilizzando operatori logici (ad esempio &#8220;+&#8221; significa OR mentre &#8220;-&#8221; esclude la parole che segue questo simbolo) bisogna effettuare una ricerca IN BOOLEAN MODE, più lenta, ma più efficace. La nostra query dovrà quindi essere modificata in:</p>
<pre class="brush: sql; title: ;">SELECT * FROM test WHERE MATCH(keywords) AGAINST('*pippo*,*pluto*' IN BOOLEAN MODE)</pre>
<p>In questo modo si effettua una ricerca all&#8217;interno del campo keywords, delle parole che contengono al loro interno &#8220;pippo&#8221; o &#8220;pluto&#8221;. Il carattere &#8220;*&#8221; funziona un po&#8217; come il &#8220;%&#8221; nelle <em>LIKE</em>.</p>
<p>A questo punto manca un ultima chicca. La funzione MATCH (..) AGAINST(..) ritorna un valore che rappresenta la pertinenza delle parole cercate nel campo. Nel BOOLEAN MODE sarà il numero di parole trovate nel campo, mentre con la ricerca in linguaggio naturale ci sarà un algoritmo che calcola la pertinenza con delle regole <em>strane</em> ma che funzionano ;)</p>
<p>Quindi per sfruttare al massimo questo algoritmo bisognerà scrivere la query con:</p>
<pre class="brush: sql; title: ;">SELECT *, MATCH(keywords) AGAINST('*pippo*,*pluto*' IN BOOLEAN MODE) as pertinenza FROM test WHERE MATCH(keywords) AGAINST('*pippo*,*pluto*' IN BOOLEAN MODE) ORDER BY pertinenza DESC</pre>
<p>Così facendo ordiniamo i risultati dal più pertinente, a quello meno.</p>
<p>Risultato? sui miei 1000 records il tempo si è dimezzato, nel caso peggiore&#8230; Risultato accettabile no? :-)</p>
<p>Non vi resta che provare per credere, buon divertimento!</p>
<p><strong>[NERD MODE OFF]</strong><br />
[ad#ad-1]</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.davideferrero.com/2009/10/indici-full-text-in-mysql/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

