<?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>TecnoRetales &#187; Bases de datos</title>
	<atom:link href="http://www.tecnoretales.com/categoria/bases-de-datos/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.tecnoretales.com</link>
	<description>La experiencia no se olvida</description>
	<lastBuildDate>Wed, 07 Jul 2010 21:23:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<!-- google ad injected by adsense-optimizer http://www.adsenseoptimizer.de -->
			<div  style="padding:7px; float: right; padding-right: 0; margin: 3px;"><!-- Ad number: 1 --><script type="text/javascript"><!--
    	 
    	google_ad_client = "pub-7180773421652966"; google_alternate_color = "FFFFFF";
		google_ad_width = 468; google_ad_height = 60;
		google_ad_format = "468x60_as"; google_ad_type = "text";
		google_ad_channel =""; google_color_border = "FE8B00";
		google_color_link = "FE8B00"; google_color_bg = "FFFFFF";
		google_color_text = "000000"; google_color_url = "D9D9D9";
		google_ui_features = "rc:6"; //--></script>
		<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script></div>	<item>
		<title>Consideraciones de velocidad con LIMIT</title>
		<link>http://www.tecnoretales.com/bases-de-datos/consideraciones-de-velocidad-con-limit/</link>
		<comments>http://www.tecnoretales.com/bases-de-datos/consideraciones-de-velocidad-con-limit/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 06:11:36 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=631</guid>
		<description><![CDATA[Un compañero de trabajo que es un crack en temas de optimización de bases de datos me ha pasado la siguiente información. Cuando hacemos una consulta con un LIMIT x, y sobre una tabla con millones de registros, a medida que x aumenta, la consulta se va haciendo cada vez más lenta. Veamos un ejemplo:
SELECT [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Un compañero de trabajo que es un crack en temas de optimización de bases de datos me ha pasado la siguiente información. Cuando hacemos una consulta con un <em>LIMIT x, y</em> sobre una tabla con millones de registros, a medida que <em>x</em> aumenta, la consulta se va haciendo cada vez más lenta. Veamos un ejemplo:</p>
<p>SELECT version FROM car LIMIT 300,100; (100 results, <strong>0.01 sec</strong>)</p>
<p>SELECT version FROM car LIMIT 3000000,100; (100 results, <strong>2.5 sec</strong>)</p>
<p>Si además agregamos un par de JOINS a esta consulta, la complicamos un poco y le añadimos un ORDER BY, los problemas de rendimiento pueden llegar a causar un colapso en la base de datos.<span id="more-631"></span></p>
<p><strong>¿Por qué pasa esto?</strong></p>
<p>Para determinar el primer valor que tiene que seleccionar, MySQL debe recorrer desde el primer registro e ir contando hasta llegar al 300, a partir de ahí, cogerá 100. Obviamente, a medida que el valor de X va aumentando, la búsqueda del primer elemento es más lenta y como podemos ver en el ejemplo de arriba, llega a tardar 2,5 segundos en recorrer 3.000.000 de registros.</p>
<p><strong>¿Cómo lo podemos solucionar?</strong></p>
<p>Mi compañero propone hacer la búsqueda acotando a partir de primary key de la tabla, de este modo, al ser un campo indexado la búsqueda es realmente eficiente y nos evitamos cargar la máquina:</p>
<p><span style="font-family: Arial; font-size: x-small;"><span style="font-size: 10pt; font-family: Arial;" lang="EN-GB">SELECT version FROM car WHERE id_car BETWEEN 3000000 AND 3000100; (~100 results, <strong>0.01 sec</strong>)</span></span></p>
<p><span style="font-family: Arial; font-size: x-small;"><span style="font-size: 10pt; font-family: Arial;" lang="EN-GB">Esta solución no nos sería válida a la hora de construir un paginador, porque en el caso de tener vehículos desactivados u eliminados, unas páginas contendrían 100 vehículos, otras quizá 74&#8230; sin embargo, si por ejemplo construimos un script que se recorra toda la tabla <em>car</em> esta es una buena manera de realizar la búsqueda.</span></span></p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/bases-de-datos/consideraciones-de-velocidad-con-limit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Configurar Doctrine en Symfony</title>
		<link>http://www.tecnoretales.com/bases-de-datos/configurar-doctrine-en-symfony/</link>
		<comments>http://www.tecnoretales.com/bases-de-datos/configurar-doctrine-en-symfony/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 14:23:27 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=496</guid>
		<description><![CDATA[ Symfony integra Propel ORM por defecto, sin embargo, Doctrine está ganando puntos sobre su rival.
La principal ventaja de cada uno de ellos es:
Propel: Está completamente integrado con Symfony y decenas de plugins sólo funcionan para Propel.
Doctrine: Tiene muy buen rendimiento en ejecución y una forma muy concisa al escribir consultas complejas.
Si te has decidido [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><img class="alignleft size-full wp-image-497" src="http://www.tecnoretales.com/wp-content/uploads/2009/07/doctrine.gif" alt="Doctrine Logo" width="191" height="53" /> Symfony integra Propel ORM por defecto, sin embargo, Doctrine está ganando puntos sobre su rival.</p>
<p>La principal ventaja de cada uno de ellos es:</p>
<p><strong>Propel:</strong> Está completamente integrado con Symfony y decenas de plugins sólo funcionan para Propel.</p>
<p><strong>Doctrine:</strong> Tiene muy buen rendimiento en ejecución y una forma muy concisa al escribir consultas complejas.</p>
<p>Si te has decidido a utilizar Doctrine en lugar de Propel y no sabes como integrarlo con Symfony, aquí te dejo los pasos para activarlo.<span id="more-496"></span></p>
<ol>
<li>Lo primero que deberemos hacer es habilitar <em>sfDoctrinePlugin</em> y deshabilitar <em>sfPropelPlugin</em>, esto lo haremos editando el archivo <em>config/ProjectConfiguration.class.php </em>:
<pre class="brush: php;">
public function setup()
{
  $this-&gt;enablePlugins(array('sfDoctrinePlugin'));
  $this-&gt;disablePlugins(array('sfPropelPlugin'));
}
</pre>
<p>o si lo prefieres, puedes habilitar todos los plugins por defecto excepto los que no te interesen:</p>
<pre class="brush: php;">
public function setup()
{
  $this-&gt;enableAllPluginsExcept(array('sfPropelPlugin'));
}
</pre>
</li>
<li>Activado Doctrine, borraremos la caché para asegurarnos que se cargan nuestros cambios:<br />
<code>symfony cc</code></li>
<li>Crearemos una carpeta <em>doctrine</em> dentro de <em>config</em> que contendrá nuestro archivo <em>schema.yml</em> y listo, ya tenemos a Symfony funcionando con Doctrine</li>
<li>Ahora sólo queda abrir el archivo <em>config/databases.yml</em> y cambiar &#8220;<em>propel</em>&#8221; por &#8220;<em>doctrine</em>&#8221; (respetando mayúsculas y minúsculas) y eliminar la linea &#8220;<em>classname:  PropelPDO</em>&#8220;.</li>
</ol>
<p>Recordemos que a partir de ahora, deberemos utilizar la sintaxis Doctrine, tanto en nuestra definición del schema como en el modelo de nuestra aplicación. Si son tus primeros pasos con Doctrine, puedes ver su documentación original <a title="Doctrine Tutorial" href="http://www.doctrine-project.org/documentation/manual/1_1/en/introduction" target="_blank">aquí</a>.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/bases-de-datos/configurar-doctrine-en-symfony/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Qué es Doctrine ORM?</title>
		<link>http://www.tecnoretales.com/programacion/que-es-doctrine-orm/</link>
		<comments>http://www.tecnoretales.com/programacion/que-es-doctrine-orm/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 09:48:54 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[ORM]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=487</guid>
		<description><![CDATA[Qué es un ORM?
Un ORM o (Object Relation Mapper) es una técnica de programación que nos permite convertir datos entre el sistema de tipos utilizado en un lenguaje de programación orientado a objetos y el utilizado en una base de datos relacional, es decir, las tablas de nuestra base de datos pasan a ser clases [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><strong>Qué es un ORM?</strong></p>
<p>Un ORM o (Object Relation Mapper) es una técnica de programación que nos permite convertir datos entre el sistema de tipos utilizado en un lenguaje de programación orientado a objetos y el utilizado en una base de datos relacional, es decir, las tablas de nuestra base de datos pasan a ser clases y los registros objetos que podemos manejar con facilidad.</p>
<p><img class="aligncenter size-full wp-image-489" title="fig02" src="http://www.tecnoretales.com/wp-content/uploads/2009/07/fig02.jpg" alt="fig02" width="362" height="438" /></p>
<p><span id="more-487"></span>Utilizar un ORM tiene una serie de ventajas que nos facilitan enormemente tareas comúnes y de mantenimiento:</p>
<ol>
<li><strong>Reutilización:</strong> La principal ventaja que aporta un ORM es la reutilización permitiendo llamar a los métodos de un objeto de datos desde distintas partes de la aplicación e incluso desde diferentes aplicaciones.</li>
<li><strong>Encapsulación:</strong> La capa ORM encapsula la lógica de los datos pudiendo hacer cambios que afectan a toda la aplicación únicamente modificando una función.</li>
<li><strong>Portabilidad:</strong> Utilizar una capa de abstracción nos permite cambiar en mitad de un proyecto de una base de datos MySQL a una Oracle sin ningún tipo de complicación. Esto es debido a que no utilizamos una sintaxis MySQL, Oracle o SQLite para acceder a nuestro modelo, sino una sintaxis propia del ORM utilizado que es capaz de traducir a diferentes tipos de bases de datos.</li>
<li><strong>Seguridad:</strong> Los ORM suelen implementar mecanísmos de seguridad que protegen nuestra aplicación de los ataques más comúnes como SQL Injections.</li>
<li><strong>Mantenimiento del código:</strong> Gracias a la correcta ordenación de la capa de datos, modificar y mantener nuestro código es una tarea sencilla.</li>
</ol>
<p><strong>Qué es Doctrine?</strong></p>
<p><img class="alignleft size-full wp-image-488" title="doctrine-logo" src="http://www.tecnoretales.com/wp-content/uploads/2009/07/doctrine-logo.png" alt="doctrine-logo" width="119" height="96" />Según la <a title="Doctrine ORM" href="http://www.doctrine-project.org/" target="_blank">documentación oficial</a>, Doctrine es un <strong>ORM para PHP</strong> 5.2.3 y posterior. Además de todas las ventajas que conlleva un ORM, uno de sus puntos fuertes es su lenguaje <strong>DQL</strong> (Doctrine Query Language) <strong>inspirado en el HQL de Hibernate</strong>.</p>
<p>Cuando trabajamos con Doctrine, necesitamos informar a su motor interno de cual es el modelo de nuestra aplicación, para ello podemos hacer <strong>ingeniería inversa</strong> de nuestra base de datos existente, o si empezamos la aplicación desde 0, crear el modelo en la sintaxis específica que nos propone Doctrine y luego generar toda la base de datos.</p>
<p>Para crear el modelo, doctrine nos da dos alternativas, hacer una clase por tabla e indicarle mediante PHP el tipo de datos que almacenaremos en él, un ejemplo:</p>
<pre class="brush: php;">// models/generated/BaseUser.php

class User extends BaseUser
{
    public function setTableDefinition()
    {
        $this-&gt;hasColumn('username', 'string', 255, array('default' =&gt; 'default username'));
        $this-&gt;hasColumn('name', 'string', 255, array('default' =&gt; 'default name'));
        $this-&gt;hasColumn('age', 'integer', 4, array('unsigned' =&gt; true));
        // ...
    }

    // ...
}</pre>
<p>O crear un esquema en <a title="Yaml" href="http://es.wikipedia.org/wiki/YAML" target="_blank">formato YAML</a> (<em>schema.yml</em>) similar a XML, pero bastante más legible. El equivalente al ejemplo anterior en YAML sería:</p>
<pre class="brush: plain;"># schema.yml

# ...
User:
# ...
  columns:
    username:
      type: string(255)
      default: default username
    name:
      type: string(255)
      default: default name
    age:
      type: integer(4)
      unsigned: true
    # ...</pre>
<p>Además de definir los campos de cada tabla, también le indicamos las relaciones que tienen con las otras tablas y su tipo (many-to-many, one-to-many, one-to-one&#8230;), lo que deja perfectamente estructurada nuestro modelo de datos y su manera de acceder a los valores.</p>
<p>Más adelante seguiré escribiendo sobre las ventajas de Doctrine y añadiendo ejemplos que considere interesantes y/o útiles.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/programacion/que-es-doctrine-orm/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	<!-- google ad injected by adsense-optimizer http://www.adsenseoptimizer.de -->
			<div  style="padding:7px; float: left; padding-left: 0px; margin: 3px;"><!-- Ad number: 2 --><script type="text/javascript"><!--
    	 
    	google_ad_client = "pub-7180773421652966"; google_alternate_color = "FFFFFF";
		google_ad_width = 468; google_ad_height = 60;
		google_ad_format = "468x60_as"; google_ad_type = "text";
		google_ad_channel =""; google_color_border = "FE8B00";
		google_color_link = "FE8B00"; google_color_bg = "FFFFFF";
		google_color_text = "000000"; google_color_url = "D9D9D9";
		google_ui_features = "rc:6"; //--></script>
		<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script></div>	<item>
		<title>Instalar DBDesigner4 en Ubuntu</title>
		<link>http://www.tecnoretales.com/linux/instalar-dbdesigner4-en-ubuntu/</link>
		<comments>http://www.tecnoretales.com/linux/instalar-dbdesigner4-en-ubuntu/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 06:05:36 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[DBDesigner4]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=451</guid>
		<description><![CDATA[DBDesigner4 es una aplicación gratuita que integra diseño de bases de datos, modelado, creación y mantenimiento en un entorno único.
Instalar DBDesigner4 en Ubuntu y hacer que funcione es relativamente fácil, el problema viene cuando quieres hacer conexiones con la base de datos para hacer, por ejemplo, ingeniería inversa y obtener el modelo gráfico de las [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><img class="alignleft size-full wp-image-452" title="DBDesigner4 logo" src="http://www.tecnoretales.com/wp-content/uploads/2009/06/dbdesigner.jpg" alt="DBDesigner4 logo" width="150" height="134" /><strong>DBDesigner4 </strong>es una aplicación gratuita que integra diseño de bases de datos, modelado, creación y mantenimiento en un entorno único.</p>
<p><strong>Instalar DBDesigner4 en Ubuntu</strong> y hacer que funcione es relativamente fácil, el problema viene cuando quieres hacer conexiones con la base de datos para hacer, por ejemplo, ingeniería inversa y obtener el modelo gráfico de las tablas.</p>
<p>Para que esto no nos suceda, aquí os dejo los pasos a seguir para que os funcione en vuestra Ubuntu a la primera.<span id="more-451"></span></p>
<ol>
<li>Descargarnos las librerias que vamos a necesitar y el programa:
<pre>cd /opt</pre>
<pre>wget http://www.silcom.com.pe/soft/xlibs_6.8.2-77_all.deb</pre>
<pre>wget http://www.silcom.com.pe/soft/kylixlibs3-borqt_3.0-1_i386.deb</pre>
<pre>wget http://downloads.mysql.com/DBDesigner4/DBDesigner4.0.5.4.tar.gz</pre>
<pre>wget http://crlab.com/dbx/dbxmda.tar.gz</pre>
</li>
<li>
<pre>Instalamos...</pre>
<pre>sudo apt-get install xkeyboard-config</pre>
<pre>sudo dpkg -i xlibs_6.8.2-77_all.deb</pre>
<pre>sudo dpkg -i kylixlibs3-borqt_3.0-1_i386.deb</pre>
<pre>sudo tar xvfz DBDesigner4.0.5.4.tar.gz</pre>
<pre>sudo tar xvfz dbxmda.tar.gz</pre>
<pre>sudo mv DbxMda/libsqlmda.so.3.20 /usr/lib/</pre>
<pre>sudo ldconfig</pre>
</li>
<li>
<pre>Hacemos unos cuantos enlaces simbólicos:</pre>
<pre>sudo ln -s /usr/lib/kylix3/libborqt-6.9-qt2.3.so /usr/lib/libborqt-6.9-qt2.3.so</pre>
<pre>sudo ldconfig</pre>
<pre>sudo ln -s /usr/lib/kylix3/libborqt-6.9.0-qt2.3.so /lib/libborqt-6.9-qt2.3.so</pre>
</li>
<li>Por último, sólo nos queda iniciar el programa
<pre>/opt/DBDesigner4/DBDesigner4 &amp;</pre>
</li>
</ol>
<p>Si todo ha ido bien, el programa iniciará normalmente mostrándonos el entorno de modelado de base de datos. El siguiente paso será <strong>configurar la conexión a base de datos</strong>:</p>
<ol>
<li>Click en el menú superior en &#8220;D<span style="text-decoration: underline;">a</span>tabase &gt; <span style="text-decoration: underline;">C</span>onnect to Database&#8221; y nos aparecerá una ventana como la que siguie:<img class="aligncenter size-full wp-image-453" title="DBDesigner4 - New Database" src="http://www.tecnoretales.com/wp-content/uploads/2009/06/pantallazo-select-database-connection.png" alt="DBDesigner4 - New Database" width="500" height="201" /></li>
<li>Click en el botón &#8220;New Database Connect&#8221; y rellenamos la información:
<ul>
<li><span style="text-decoration: underline;">Connection Name</span>: Nombre para la conexión</li>
<li><span style="text-decoration: underline;">Driver</span>: En nuestro caso, será MySQL pero se pueden elegir varios (Oracle, SQLLite&#8230;)</li>
<li><span style="text-decoration: underline;">Hostname</span>: Donde está localizada la base de datos (generalmente localhost)</li>
<li><span style="text-decoration: underline;">Database Name</span>: Nombre de la base de datos a la que queremos conectar</li>
<li><span style="text-decoration: underline;">Username</span>: Nombre de usuario para conectar a dicha base de datos</li>
<li><span style="text-decoration: underline;">Password</span>: Password de acceso</li>
</ul>
</li>
<li>Click en la pestaña &#8220;Advanced&#8221; y rellenamos los valores como muestra la imágen excepto los campos User Name y Database que deberán contener los de tu conexión:<img class="aligncenter size-full wp-image-454" title="DBDesigner4 Database Connection Editor" src="http://www.tecnoretales.com/wp-content/uploads/2009/06/pantallazo-database-connection-editor-2.png" alt="DBDesigner4 Database Connection Editor" width="300" height="279" /></li>
</ol>
<p>Ahora ya estás en disposición de conectar el programa con tu base de datos y hacer ingeniería inversa de tus tablas existentes.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/linux/instalar-dbdesigner4-en-ubuntu/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Explain MySQL para optimizar tus consultas</title>
		<link>http://www.tecnoretales.com/bases-de-datos/explain-mysql-para-optimizar-tus-consultas/</link>
		<comments>http://www.tecnoretales.com/bases-de-datos/explain-mysql-para-optimizar-tus-consultas/#comments</comments>
		<pubDate>Wed, 17 Jun 2009 17:25:01 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=563</guid>
		<description><![CDATA[Explain es una potente herramienta que MySQL pone a nuestra disposición para orientarnos sobre como está ejecutando una consulta el motor de la base de datos.
Esto nos es de mucha utilidad cuando creamos una consulta nueva, pues nos indica que índices va a utilizar, de que tipo son, como de efectiva será la respuesta al [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><strong><img class="alignleft size-full wp-image-565" src="http://www.tecnoretales.com/wp-content/uploads/2009/07/mysql_5_4_300x290.png" alt="MySQL Dolphin" width="150" height="145" />Explain</strong> es una potente herramienta que MySQL pone a nuestra disposición para orientarnos sobre como está ejecutando una consulta el motor de la base de datos.</p>
<p>Esto nos es de mucha utilidad cuando creamos una consulta nueva, pues nos indica que índices va a utilizar, de que tipo son, como de efectiva será la respuesta al usar esos índices&#8230; por lo tanto, podemos detectar rápidamente, por ejemplo, de que nuestra consulta no está bien formada o que nos falta un índice en algún campo concreto.</p>
<p>Si ejecutamos la siguiente consulta:</p>
<p><code>EXPLAIN SELECT *<br />
FROM user u<br />
INNER JOIN user_profile up ON u.id = up.user_id</code></p>
<p>Obtendremos una respuesta como esta:</p>
<table id="table_results" border="1">
<thead>
<tr>
<th>id</th>
<th>select_type</th>
<th>table</th>
<th>type</th>
<th>possible_keys</th>
<th>key</th>
<th>key_len</th>
<th>ref</th>
<th>rows</th>
<th>Extra</th>
</tr>
</thead>
<tbody>
<tr>
<td align="right">1</td>
<td>SIMPLE</td>
<td>up</td>
<td>ALL</td>
<td>user_id_idx</td>
<td><em>NULL</em></td>
<td><em>NULL</em></td>
<td><em>NULL</em></td>
<td align="right">13</td>
<td></td>
</tr>
<tr>
<td align="right">1</td>
<td>SIMPLE</td>
<td>u</td>
<td>eq_ref</td>
<td>PRIMARY</td>
<td>PRIMARY</td>
<td>4</td>
<td>futbol.up.user_id</td>
<td align="right">1</td>
<td></td>
</tr>
</tbody>
</table>
<p>Pero, ¿qué quieren decir estas columnas? ¿qué información nos dan?<span id="more-563"></span></p>
<ol>
<li><strong>Table: </strong>Nos informa de la tabla a la que nos estamos refiriendo.</li>
<li><strong>Type:</strong> El tipo de unión que se está usando. Desde la mejor hasta la peor, los tipos de uniones son system, const, eq_ref, ref, range, index, y ALL.
<ul>
<li><strong>System:</strong> Tabla con una única fila, por tanto, la respuesta es inmediata.</li>
<li><strong>Const:</strong> En la tabla coincide una única fila con los criterios indicados. Al sólo haber una fila, el optimizador toma este valor como constante, por este motivo este tipo de tablas son muy rápidas.</li>
<li><strong>Eq_ref:</strong> Una fila de la tabla 1 será leída por cada combinación de filas de la tabla 2. Este tipo es usado cuando todas las partes de un índice se usan en la consulta y el índice es UNIQUE o PRIMARY KEY.</li>
<li><strong>Ref:</strong> Todas las filas con valores en el índice que coincidan serán leídos desde esta tabla por cada combinación de filas de las tablas previas. Similar a <strong>eq_ref</strong>, pero usado cuando usa sólo un prefijo más a la izquierda de la clave o si la clave no es UNIQUE o PRIMARY KEY. Si la clave que es usada coincide sólo con pocas filas, esta union es buena.</li>
<li><strong>Range:</strong> Sólo serán recuperadas las filas que estén en un rango dado, usando un índice para seleccionar las filas. La columna <strong>key</strong> indica cual índice es usado, y el valor <strong>key_len</strong> contiene la parte más grande de la clave que fue usada. La columna ref será NULL para este tipo.</li>
<li><strong>Index:</strong> Escaneo completo de la tabla para cada combinación de filas de las tablas previas, revisando únicamente el índice.</li>
<li><strong>ALL:</strong> Escaneo completo de la tabla para cada combinación de filas. Es el peor caso ya que revisará todas las filas para cada combinación.</li>
</ul>
</li>
<li><strong>Possible_keys:</strong> Posibles indices que utilizará la consulta.</li>
<li><strong>Key:</strong> Índice utilizado para ejecutar la consulta. Si indica el valor NULL, no se ha escogido ningún índice.</li>
<li><strong>Key_len: </strong>Cuanto más pequeño sea este valor, más rápida será la consulta, pues nos indica la longitud del índice usado.</li>
<li><strong>Ref: </strong>Las columnas del índice que se está usando, o una constante si esta es posible.</li>
<li><strong>Rows: </strong>Número de filas que MySQL debe analizar para devolver los datos solicitados.</li>
<li><strong>Extra: </strong>Información complementaria sobre como MySQL ejecutará la consulta. Los posibles valores en este campo pueden ser:
<ul>
<li> <strong>Distinct</strong>: MySQL ha encontrado una fila coincidente con los filtros indicados y no necesita seguir analizando.</li>
<li><strong>Not exists:</strong> MySQL fue capaz de hacer una optimización LEFT JOIN sobre la consulta y no examinará más filas en la tabla para la combinación de filas previa después de que encuentre una fila que coincida con el criterio LEFT JOIN.</li>
<li><strong>Range checked for each record:</strong> No se encontró un índice válido. Para cada combinación de filas se hará un chequeo para determinar que indice utilizar y en caso de encontrar alguno válido, lo utilizará.</li>
<li><strong>Using filesort:</strong> Este valor indica que MySQL necesita hacer un paso extra para encontrar la forma de ordenar las filas. Este tipo de consultas <strong>debe ser optimizada</strong>.</li>
<li><strong>Using index:</strong> Recupera la información solicitada utilizando únicamente la información del índice. Esto sucede cuando todas las columnas requeridas forman parte del índice.</li>
<li><strong>Using temporary:</strong> Para resolver esta consulta, MySQL creará una tabla temporal. Uno de los casos típicos en los que devuelve este valor es cuando usamos un ORDER BY sobre un conjunto de columnas diferentes a las indicadas en la clausula GROUP BY. Este tipo de consultas <strong>debe ser optimizada</strong>.</li>
<li><strong>Where used:</strong> Se usará una clausula WHERE para determinar que filas serán comparadas con otra tabla. Si no deseamos regresar todas las filas desde la tabla, y el join es del tipo ALL o index, es muy probable que hayamos escrito algo mal en la consulta.</li>
</ul>
<p>Una respuesta en este campo del tipo &#8220;Using filesort&#8221; o &#8220;Using temporary&#8221; es susceptible de ser una consulta a optimizar.</li>
</ol>
<p>Si analizamos la consulta ejecutada anteriormente,vemos que para la tabla con alias &#8216;up&#8217; está utilizando el tipo de unión `ALL` debido a que no existe ningun filtro en la clausula WHERE (en este caso, es normal ya que queremos devolver todos los valores). Se podría utilizar el índice existente `user_id_idx` pero al no haber ningún filtro, no es necesario usarlo. Para devolver esta consulta MySQL analizará 13 filas.</p>
<p>La segunda fila hace referencia a la tabla con alias &#8216;u&#8217;. Utiliza un tipo de unión `eq_ref` ya que devolverá una fila para cada fila de la tabla `up` pudiendo usar y usando el índice primario de la tabla que tiene una longitud de 4 (muy pequeño). Se está utilizando la columna `user_id` del índice de la tabla `up` y de la base de datos `futbol` analizando una única fila para cada fila de la tabla contigua.</p>
<p>Todos los valores son correctos y podemos asegurar que esta consulta está optimizada!!</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/bases-de-datos/explain-mysql-para-optimizar-tus-consultas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Replicación asíncrona unidireccional Maestro &#8211; Esclavo en MySQL 5.0</title>
		<link>http://www.tecnoretales.com/bases-de-datos/replicacion-asincrona-unidireccional-maestro-esclavo-en-mysql-50/</link>
		<comments>http://www.tecnoretales.com/bases-de-datos/replicacion-asincrona-unidireccional-maestro-esclavo-en-mysql-50/#comments</comments>
		<pubDate>Tue, 26 May 2009 18:26:05 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=94</guid>
		<description><![CDATA[Supongamos un escenario real de producción en el que tenemos dos servidores. Una de las máquinas contiene un servidor http y una base de datos MySQL que usamos para abserver el tráfico web; la otra la utilizamos para otras tareas necesarias. Sería magnífico poder utilizar la segunda máquina como backup de nuestro MySQL por si [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><img class="alignright size-full wp-image-373" title="mysql logo" src="http://www.tecnoretales.com/wp-content/uploads/2009/05/mysql.jpg" alt="mysql logo" width="150" height="110" />Supongamos un escenario real de producción en el que tenemos dos servidores. Una de las máquinas contiene un servidor http y una base de datos MySQL que usamos para abserver el tráfico web; la otra la utilizamos para otras tareas necesarias. Sería magnífico poder utilizar la <strong>segunda máquina como backup de nuestro MySQL</strong> por si hay algún problema grave en la primera ¿no? En este artículo os explico como hacerlo.</p>
<p>La replicación en MySQL funciona de la siguiente manera, el servidor maestro escribe todas las actualizaciones en un fichero de log binario, y mantiene un índice de los ficheros para rastrear las rotaciones de logs. A su vez, el servidor esclavo, que mantiene una conexión abierta contínua con el  maestro, es informado cuando sucede algún cambio en el log binario del maestro, y ejecutan estos cambios en sus tablas.<span id="more-94"></span></p>
<p><strong>Configuración de la replica asíncrona unidireccional</strong></p>
<p>1) Localizaremos el fichero de configuración de MySQL de la máquina que hará de maestro. Generalmente lo podemos encontrar en la ruta <em>/etc/mysql/my.cnf</em> y descomentamos las líneas:</p>
<p><code>log_bin=/var/log/mysql/mysql-bin.log<br />
server-id = 1</code></p>
<p>Buscamos la misma línea en el servidor que hará las veces de esclavo y descomentamos la línea log_bin y server-id modificando el valor a uno diferente del de master:</p>
<p><code> log_bin=/var/log/mysql/mysql-bin.log<br />
server-id = 2</code></p>
<p>Ahora podemos arrancar los dos servidores MySQL para empezar a enseñarles a replicar.</p>
<p>2) Una vez arrancados ambos servidores, nos ponemos en el que hará de master y creamos la base de datos y el volcado de los datos en las tablas. En mi caso haré una importación de un fichero sql:</p>
<p><code>mysql -u [DBUSER-MASTER] -p -e "CREATE DATABASE `myBaseDeDatos`"<br />
mysql -u [DBUSER-MASTER] -p myBaseDeDatos &lt; myBaseDeDatos.sql</code></p>
<p>3) Ahora crearemos una cuenta de usuario con permisos de replicación, para autorizar, en el servidor maestro, al nuevo usuario a realizar replicas:</p>
<p><code> mysql&gt; GRANT REPLICATION SLAVE ON *.* TO '[DBUSER-REPLICATOR]'@'[IP-SERVER-SLAVE]' IDENTIFIED BY '[DBPASS-REPLICATOR]';<br />
mysql&gt; flush privileges;<br />
mysql&gt; exit<br />
</code></p>
<p>4) Finalmente, consultamos el nombre del archivo de log binario y la posición de compensación, datos necesarios para configurar el esclavo:</p>
<p><code>mysql&gt; SHOW MASTER STATUS;<br />
+------------------+----------+--------------+------------------+<br />
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |<br />
+------------------+----------+--------------+------------------+<br />
| mysql-bin.000    | 103      |              |                  |<br />
+------------------+----------+--------------+------------------+<br />
1 row in set (0.00 sec)</code></p>
<p>5) Una vez hecho esto, volcaremos la base de datos en el servidor esclavo tal y como hicimos con el maestro. Ejecutaré el mismo archivo sql:</p>
<p><code>mysql -u [DBUSER-SLAVE] -p -e "CREATE DATABASE `myBaseDeDatos`"<br />
mysql -u [DBUSER-SLAVE] -p myBaseDeDatos &lt; myBaseDeDatos.sql</code></p>
<p>6) Y una vez que el esclavo tenga generada la base de datos, lo configuramos para que esté posicionado con respecto al maestro:</p>
<p><code>mysql&gt; CHANGE MASTER TO MASTER_HOST = '[IP-SERVER-MASTER]';<br />
mysql&gt; CHANGE MASTER TO MASTER_USER = '[DBUSER-REPLICATOR]';<br />
mysql&gt; CHANGE MASTER TO MASTER_PASSWORD = '[DBPASS-REPLICATOR]';<br />
mysql&gt; CHANGE MASTER TO MASTER_LOG_FILE = 'mysql-bin.0001';<br />
mysql&gt; CHANGE MASTER TO MASTER_LOG_POS = 103;<br />
mysql&gt; start slave;</code></p>
<p>Y con esto ya queda configurado el servidor esclavo y alineado con el master. Desde este momento comenzará la replicación con el maestro.</p>
<p>Para comprobar que realmente está replicando, podemos ejecutar el siguiente comando en el servidor esclavo:</p>
<p><code>mysql&gt; show slave status</code></p>
<p>Eso muestra:</p>
<p><code>*************************** 1. row ***************************<br />
Slave_IO_State: Waiting for master to send event<br />
Master_Host: [IP-SERVER-MASTER]<br />
Master_User: [DBUSER-REPLICATOR]<br />
Master_Port: 3306<br />
Connect_Retry: 60<br />
Master_Log_File: mysql-bin.0001<br />
Read_Master_Log_Pos: 103<br />
Relay_Log_File: esclavo-relay-bin.000001<br />
Relay_Log_Pos: 103<br />
Relay_Master_Log_File: mysql-bin.0001<br />
Slave_IO_Running: Yes<br />
Slave_SQL_Running: Yes<br />
Replicate_Do_DB: myBaseDeDatos<br />
Replicate_Ignore_DB:<br />
Replicate_Do_Table:<br />
Replicate_Ignore_Table:<br />
Replicate_Wild_Do_Table:<br />
Replicate_Wild_Ignore_Table:<br />
Last_Errno: 0<br />
Last_Error:<br />
Skip_Counter: 0<br />
Exec_Master_Log_Pos: 103<br />
Relay_Log_Space: 103<br />
Until_Condition: None<br />
Until_Log_File:<br />
Until_Log_Pos: 0<br />
Master_SSL_Allowed: No<br />
Master_SSL_CA_File:<br />
Master_SSL_CA_Path:<br />
Master_SSL_Cert:<br />
Master_SSL_Cipher:<br />
Master_SSL_Key:<br />
Seconds_Behind_Master: 0<br />
1 row in set (0.00 sec)</code></p>
<p>En <strong>Read_Master_Log_Pos</strong> y <strong>Relay_Log_Pos</strong> podemos ver que ambos valores están correctamente alineados. La variable <strong>Seconds_Behind_Master</strong> nos indica el desfase de actualización entre maestro y esclavo, si todo está bien, mostrará un valor 0.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/bases-de-datos/replicacion-asincrona-unidireccional-maestro-esclavo-en-mysql-50/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Como crear y modificar un campo autoincremental en Oracle</title>
		<link>http://www.tecnoretales.com/programacion/como-crear-y-modificar-un-campo-autoincremental-en-oracle/</link>
		<comments>http://www.tecnoretales.com/programacion/como-crear-y-modificar-un-campo-autoincremental-en-oracle/#comments</comments>
		<pubDate>Fri, 22 May 2009 22:30:19 +0000</pubDate>
		<dc:creator>Jordi Anta Ugarte</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=349</guid>
		<description><![CDATA[Muchas veces nos encontramos con la necesidad de crear un campo autoincremental en una tabla de nuestra base de datos. Típicamente suele usarse para generar una clave primaria para dicha tabla. Pues bien, la primera vez que nos enfrentamos con esta situación trabajando con Oracle, nos encontraremos con un grave problema que nos puede hacer [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Muchas veces nos encontramos con la necesidad de crear un campo autoincremental en una tabla de nuestra base de datos. Típicamente suele usarse para generar una clave primaria para dicha tabla. Pues bien, la primera vez que nos enfrentamos con esta situación trabajando con Oracle, nos encontraremos con un grave problema que nos puede hacer perder mucho tiempo, puesto que, aunque parezca mentira, no existe ningún tipo de campo autoincremental en Oracle.</p>
<p>La solución es bastante sencilla (aunque no por ello deja de ser incómodo no disponer de un campo de este tipo directamente). Oracle dispone de un tipo de objeto denominado secuencia (SEQUENCE). Una secuencia tiene un valor inicial, un valor máximo y un valor de secuencia que incrementará cada vez que hagamos una llamada a la secuencia.<span id="more-349"></span></p>
<p>La estructura para crear una secuencia es la siguiente:</p>
<blockquote><p><strong>CREATE SEQUENCE sequence_name<br />
MINVALUE value<br />
MAXVALUE value<br />
START WITH value<br />
INCREMENT BY value<br />
CACHE value / NOCACHE;</strong></p></blockquote>
<p>Donde:</p>
<ul>
<li> MINVALUE es el valor mínimo que tendrá la secuencia (usualmente 0 o 1)</li>
<li>MAXVALUE es el valor máximo que tendrá la secuencia (se puede obviar y por defecto se le asignará 999999999999999999999999999)</li>
<li>START WITH es el valor con el que empezará la secuencia</li>
<li>INCREMENT BY es el valor con el que se incrementará la secuencia (usualmente 1, pero podríamos usar 2 para generar solo valores pares por ejemplo [siempre y cuando hubiesemos puesto el campo anterior a 0 o 2 <img src='http://www.tecnoretales.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  ] )</li>
<li>CACHE / NOCACHE el uso de CACHE permite indicar cuantos valores queremos que sean guardados en memoria para una acceso más rápido. El inconveniente que tiene es que en caso de una caida del sistema, los valores generados por la secuencia se pierden y quedarian &#8220;huecos&#8221;.</li>
</ul>
<p>Una vez creada la secuencia la usaremos llamando a <strong>sequence_name.nextval</strong>. Por ejemplo:</p>
<blockquote><p><strong>I</strong><strong>NSERT INTO mi_tabla (tabla_id, tabla_campo1) VALUES (mi_secuencia.nextval, &#8216;valor1&#8242;);</strong></p></blockquote>
<p>También podremos acceder al valor de la secuencia en una consulta haciendo la siguiente llamada (hay que tener en cuenta que esta llamada también nos incrementará el contador de la secuencia):</p>
<blockquote><p><strong>SELECT sequence_name.nextval FROM dual;</strong><strong><br />
</strong></p></blockquote>
<p>Por último veremos como podemos modificar el valor de la secuencia para asignarle uno arbitráriamente. Primero modificaremos la secuencia indicándole que a partir de este momento cada vez que sea llamada incremente su contador en tantas posiciones como la diferencia entre el valor que queremos asignarle (p.ej. si nuestra secuencia tiene valor 327 y queremos asignarle el 450, deberemos incrementar en 123).</p>
<blockquote class="sql_command"><p><strong>ALTER SEQUENCE seq_name INCREMENT BY 123;</strong></p></blockquote>
<p>Luego haremos una llamada a la secuencia para que se incremente con el nuevo valor:</p>
<blockquote class="sql_command"><p><strong>SELECT seq_name.nextval FROM dual;</strong></p></blockquote>
<p>Y por último volveremos a alterar la secuencia para que vuelva a incrementar igual que antes (en nuestro ejemplo de uno en uno)</p>
<blockquote class="sql_command"><p><strong>ALTER SEQUENCE seq_name INCREMENT BY 1;</strong></p></blockquote>
<p>También existe la posibilidad de generar campos autoincrementales creando un trigger que sea llamado antes de la inserción y se encargue de calcular el siguiente valor libre. O haciendo una consulta previa del primer valor libre del campo. Pero son técnicas más engorrosas y que pueden dar lugar a errores y problemas con más facilidad de la expuesta aquí.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/programacion/como-crear-y-modificar-un-campo-autoincremental-en-oracle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	<!-- google ad injected by adsense-optimizer http://www.adsenseoptimizer.de -->
			<div  style="padding:7px; display: block; margin-left: auto; margin-right: auto; text-align: center;"><!-- Ad number: 3 --><script type="text/javascript"><!--
    	 
    	google_ad_client = "pub-7180773421652966"; google_alternate_color = "FFFFFF";
		google_ad_width = 468; google_ad_height = 60;
		google_ad_format = "468x60_as"; google_ad_type = "text";
		google_ad_channel =""; google_color_border = "FE8B00";
		google_color_link = "FE8B00"; google_color_bg = "FFFFFF";
		google_color_text = "000000"; google_color_url = "D9D9D9";
		google_ui_features = "rc:6"; //--></script>
		<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script></div>	<item>
		<title>Importar archivos DBF a MySQL</title>
		<link>http://www.tecnoretales.com/linux/importar-archivos-dbf-a-mysql/</link>
		<comments>http://www.tecnoretales.com/linux/importar-archivos-dbf-a-mysql/#comments</comments>
		<pubDate>Wed, 06 May 2009 20:54:39 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=56</guid>
		<description><![CDATA[Pues bien, otro post provocado por una necesidad del curro&#8230; esa necesidad me ha obligado a googlear un ratito y por último, he aquí el resultado.
La cosa está en que me han pasado unos archivos en formato dbf y para poder hacer el tratamiento necesario necesitaba poderlos importar a MySQL. La solucion está en dbf2mysql, [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Pues bien, otro post provocado por una necesidad del curro&#8230; esa necesidad me ha obligado a googlear un ratito y por último, he aquí el resultado.</p>
<p>La cosa está en que me han pasado unos archivos en <strong>formato dbf</strong> y para poder hacer el tratamiento necesario necesitaba poderlos <strong>importar a MySQL</strong>. La solucion está en <em>dbf2mysql</em>, programa que de una manera bastante sencilla se encarga de hacer la importación a la base de datos MySQL.<span id="more-56"></span></p>
<p>Los flags más importantes que nos ofrece dbf2mysql són los siguientes:</p>
<ul>
<li>-h indica server donde conectarse</li>
<li>-U usuario MySql</li>
<li>-P password MySql</li>
<li>-d base de datos donde se insertaran los datos</li>
<li>-t tabla donde se insertarán los datos</li>
<li>-c crea la tabla si no existe</li>
<li>-cc crea la tabla, pero no inserta registros</li>
<li>-f traduce los nombres de campo a minúsculas</li>
<li>-n no se agrega &#8216;NOT NULL&#8217; en las sentencias de creación de tabla</li>
<li>-o exporta solo los campos listados (Ej. -o field1,field2&#8230;)</li>
<li>-s substituye permite cambiar nombres de campos (Ej. -s oldName1=newName1,oldName1=newName1)</li>
<li>-i lista de campos a indexar. Genera UN indice por campo (Ej. -i field1,field2&#8230;)</li>
<li>-r quita espacios antes y después de datos alfanuméricos</li>
<li>-v muestra detalles de la conversión</li>
<li>-vv muestra más detalles</li>
<li>-vvv incluye informe de progreso</li>
</ul>
<p>Los pasos que he siguido para hacer la importacion són:</p>
<p>1) Instalo dbf2mysql, en mi caso desde <a title="Ubuntu" href="http://www.tecnoretales.com/tag/ubuntu/">Ubuntu</a>:</p>
<pre>sudo apt-get install dbf2mysql</pre>
<p>En cualquier caso, nos podemos bajar el programa para sistemas Unix de <a href="http://sourceforge.net/projects/dbf2mysql/" target="blank">Source Forge</a></p>
<p>2) Creo una base de datos MySQL vacia:</p>
<pre>mysql -u [DBUSER] -p -e "CREATE DATABASE `[DBNAME]`"</pre>
<p>3) Por último lanzamos el siguiente comando para indicarle que importe el archivo dbf a la base de datos local, en la tabla [DBTABLE] de la base de datos [DBNAME], entrando con el usuario [DBUSER] y el password [DBPASS]. Mediante el flag -c forzamos a que cree la tabla si no existe y con -f le indicamos que traduzca los nombres de los campos a minusculas:</p>
<pre>dbf2mysql -h localhost -U [DBUSER] -P [DBPASS] -d [DBNAME] -t [DBTABLE] -c -f /path/to/file/miTabla.dbf</pre>
<p>Es importante tener en cuenta que <strong>esta importación no tendra en cuenta algunos atributos importantes</strong> de la tabla como, por ejemplo, los campos autoincrementales. Si tenemos algun problema de este estilo, es recomendable crear la estructura de la tabla antes de realizar la importación.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/linux/importar-archivos-dbf-a-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Convertir base de datos a UTF8</title>
		<link>http://www.tecnoretales.com/bases-de-datos/convertir-base-de-datos-a-utf8/</link>
		<comments>http://www.tecnoretales.com/bases-de-datos/convertir-base-de-datos-a-utf8/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 08:10:55 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Bases de datos]]></category>
		<category><![CDATA[Encoding]]></category>
		<category><![CDATA[ISO-8859-15]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[UTF8]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=3</guid>
		<description><![CDATA[Hace algún tiempo que tenía ganas de migrar una base de datos de ISO-8859-1 a UTF-8, pero cuando tienes un proyecto funcionando, hacer un cambio de este estilo es algo delicado y por lo tanto, uno intenta postergarlo. En cualquier caso, finalmente decidí liarme la manta a la cabeza y tirarlo adelante.
Por desgracia, no existe [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Hace algún tiempo que tenía ganas de <strong>migrar una base de datos de ISO-8859-1 a UTF-8</strong>, pero cuando tienes un proyecto funcionando, hacer un cambio de este estilo es algo delicado y por lo tanto, uno intenta postergarlo. En cualquier caso, finalmente decidí liarme la manta a la cabeza y tirarlo adelante.</p>
<p>Por desgracia, no existe una sentencia SQL que haga algo similar de manera sencilla, sin embargo, podemos conseguirlo utilizando el comando de Linux recode (evolución bastante más inteligente del antiguo iconv), os dejo detallados los pasos que seguí para hacer el cambio:<span id="more-3"></span></p>
<p>1) <strong>Exportamos</strong> la base de datos mediante el comando mysqldump:</p>
<pre>mysqldump -u  -p -f --single-transaction --opt -hlocalhost --all-databases | gzip -9 -c &gt; [FICHERO_EXPORTACION_BD]</pre>
<p>2) <strong>Recodificamos</strong> el archivo dump mediante el comando recode:</p>
<pre>recode iso-8859-15..utf8 &lt; [FICHERO_EXPORTACION_BD] &gt; [FICHERO_EXPORTACION_BD].utf8</pre>
<p>3) <strong>Editamos</strong> el archivo y reemplazamos &#8220;latin1&#8243; por &#8220;utf8&#8243;</p>
<p>4) <strong>Creamos la nueva base de datos con el encoding utf8</strong>:</p>
<pre>mysql -u [USER] -p [DBNAME] -e "CREATE DATABASE `[DBNAME]` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin;"</pre>
<p>5) Por último, <strong>importamos</strong> la base de datos de la siguiente manera:</p>
<pre>mysql -u [USER] -p [DBNAME] &lt; [FICHERO_EXPORTACION_BD].utf8</pre>
<p><strong>NOTA!!</strong> En mi caso concreto, la aplicación PHP seguía mostrando errores al visualizar la información que provenía de base de datos a pesar de haber cambiado convenientemente los metas del html resultante. En mi caso era debido a que la conexión a la base de datos estaba forzada a leer en ISO. Esto lo solventé añadiendo justo después de la conexión:</p>
<pre>@mysql_query("SET character_set_results='utf8'");</pre>
<p>o si nuestra version de PHP es superior o igual a la 5.2.3, tambien podemos hacer:</p>
<pre>@mysql_set_charset("utf8", $link_identifier);</pre>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/bases-de-datos/convertir-base-de-datos-a-utf8/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
