<?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>Bicosyes - since evermore... &#187; Bases de Datos</title>
	<atom:link href="http://bicosyes.com/category/desarrollo-de-software/bases-de-datos/feed/" rel="self" type="application/rss+xml" />
	<link>http://bicosyes.com</link>
	<description></description>
	<lastBuildDate>Sat, 06 Mar 2010 20:03:06 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Backup incremental de tu base de datos con Git</title>
		<link>http://bicosyes.com/backup-incremental-de-tu-base-de-datos-con-git/</link>
		<comments>http://bicosyes.com/backup-incremental-de-tu-base-de-datos-con-git/#comments</comments>
		<pubDate>Thu, 09 Jul 2009 19:48:13 +0000</pubDate>
		<dc:creator>blaxter</dc:creator>
				<category><![CDATA[Bases de Datos]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[backups]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://bicosyes.com/?p=858</guid>
		<description><![CDATA[Una forma realmente interesante de realizar backups de tus bases de datos (por ser trivial y muy potente) es usando Git. El proceso es simple y se basa en la realización de los dumps de la base de datos de forma que cada fila de las tablas sea un insert aislado, de esa forma en [...]]]></description>
			<content:encoded><![CDATA[<p>Una forma realmente interesante de realizar backups de tus bases de datos (por ser <strong>trivial</strong> y muy potente) es usando <strong><a href="http://git-scm.com/">Git</a></strong>. El proceso es simple y se basa en la realización de los dumps de la base de datos de forma que cada <strong>fila</strong> de las tablas sea <strong>un</strong> <em>insert</em> aislado, de esa forma en cada commit solo estaremos salvando las diferencias respecto al último estado (tanto <em>deletes</em> como <em>inserts</em>, como <em>updates</em>).</p>
<p>En el caso concreto de <a href="http://www.mysql.com/">MySQL</a> inicialmente haríamos algo como esto:</p>
<pre class="bash">$ <span style="color: #c20cb9; font-weight: bold;">mkdir</span> mydatabase &amp;&amp; <span style="color: #7a0874; font-weight: bold;">cd</span> mydatabase
$ mysqldump --skip-extended-insert &gt; data.sql
$ git init
$ git add data.sql
$ git commit -m <span style="color: #ff0000;">&quot;Initial dump of mydatabase&quot;</span></pre>
<p>A partir de entonces podemos automatizar el proceso con un script tan simple como este:</p>
<pre class="bash">$ <span style="color: #c20cb9; font-weight: bold;">cat</span> /usr/bin/git_backup_database
<span style="color: #808080; font-style: italic;">#!/bin/sh</span>
<span style="color: #007800;">BACKUP_DIRECTORY=</span>$<span style="color: #000000;">1</span>
<span style="color: #007800;">DATABASE=</span>$<span style="color: #000000;">2</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #007800;">$BACKUP_DIRECTORY</span> &amp;&amp; \
mysqldump --skip-extended-insert <span style="color: #007800;">$DATABASE</span> &gt; data.sql &amp;&amp; \
git commit -am <span style="color: #ff0000;">&quot;Updating dump `date +%Y_%m_%d__%H_%M`&quot;</span></pre>
<p>Según el volumen de consultas que tenga tu base de datos, te será interesante ponerlo en <strong>cron</strong> con una frecuencia determina u otra. Adicionalmente sería recomendable ejecutar <em>$ git gc</em> para optimizar el repositorio. Por ejemplo, dos veces al día y una vez a la semana mantenimiento:</p>
<pre class="bash"><span style="color: #000000;">0</span> <span style="color: #000000;">0</span> * * * /usr/bin/git_backup_database /path/to/mydatabase mydatabase
<span style="color: #000000;">0</span> <span style="color: #000000;">12</span> * * * /usr/bin/git_backup_database  /path/to/mydatabase mydatabase
<span style="color: #000000;">0</span> <span style="color: #000000;">1</span> * * <span style="color: #000000;">1</span> <span style="color: #7a0874; font-weight: bold;">cd</span> /path/to/mydatabase &amp;&amp; git <span style="color: #c20cb9; font-weight: bold;">gc</span></pre>
<p>Además desde otro equipo nadie te impide hacer un <em>$ git clone ssh://equipo:path/to/mydatabase</em> y tener todo el historial de la base de datos en un plis (bueno eso es relativo, que ocupará lo suyo...) o incluso programar un <em>$ git pull</em> para tener varios backups en distintas maquinas. En definitiva, se abren un sinfín de opciones <img src='http://bicosyes.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<img src="http://bicosyes.com/?ak_action=api_record_view&id=858&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://bicosyes.com/backup-incremental-de-tu-base-de-datos-con-git/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Benchmark MySQL vs PostgreSQL vs SQLite vs MSAccess (vs ruby)</title>
		<link>http://bicosyes.com/benchmark-mysql-vs-postgresql-vs-ruby/</link>
		<comments>http://bicosyes.com/benchmark-mysql-vs-postgresql-vs-ruby/#comments</comments>
		<pubDate>Fri, 04 Apr 2008 22:19:27 +0000</pubDate>
		<dc:creator>blaxter</dc:creator>
				<category><![CDATA[Bases de Datos]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[postgresql]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://bicosyes.com/benchmark-mysql-vs-postgresql-vs-ruby/</guid>
		<description><![CDATA[Por razones que no vienen al caso, me he encontrado hoy con un increíble WTF? usando MySQL (la lista no es corta, pero este era sorprendente, digno de Access o peor). He decidido hacer una comparativa con uno de sus competidores directos, PostgreSQL. Además probaré a intentar resolver el problema usando código en vez de [...]]]></description>
			<content:encoded><![CDATA[<p>Por razones que no vienen al caso, me he encontrado hoy con un increíble <acronym title="What The fuck? (¿y esto cómo se come?)">WTF?</acronym> usando <strong>MySQL</strong> (la lista no es corta, pero este era sorprendente, digno de Access o peor). He decidido hacer una comparativa con uno de sus competidores directos, <strong>PostgreSQL</strong>. Además probaré a intentar resolver el <em>problema</em> usando código en vez de dejar todo el "trabajo" a la base de datos, en concreto lo haré todo en ruby, no por eficiencia sino por comodidad (que sino me canso). </p>
<p><strong>[Actualización 6 abril 2008 @ 19h]</strong> Ya puestos, he añadido también SQLite y Microsoft Access.</p>
<p>Presentemos el problema, tenemos dos tablas, <strong>A</strong> y <strong>B</strong>, cada una de ellas tiene una clave primaria compuesta por <strong>dos</strong> campos. Queremos averiguar las tuplas de la primera tabla que tienen como valor en uno de sus campos, valores que no se encuentran en ninguna tupla de la segunda tabla. Es decir una resta simplemente. Poniéndolo decentemente sería tal que:</p>
<ul>
<li>Tablas:
<ul>
<li>A(<u>id</u>, <u>otro_id</u>)</li>
<li>B(<u>id</u>, <u>otro_id</u>)</li>
</ul>
</li>
<li>Objetivo: tuplas de A para las cuales no existe ningún elemento en B cuyo valor del campo <em>otro_id</em> sea igual al campo <em>otro_id</em> de A
<ul>
<li>Formalmente: x ɛ A. ∀y ɛ B y.otro_id != x.otro_id</li>
<li>SQL: Lo más intuitivo y simple sería
<pre class="sql"><span style="color: #993333; font-weight: bold;">SELECT</span> * <span style="color: #993333; font-weight: bold;">FROM</span> A <span style="color: #993333; font-weight: bold;">WHERE</span> A.otro_id <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> B.otro_id <span style="color: #993333; font-weight: bold;">FROM</span> B<span style="color: #66cc66;">&#41;</span></pre>
<p>o usando LEFT JOINs también es simple expresarlo
<pre class="sql"><span style="color: #993333; font-weight: bold;">SELECT</span> * <span style="color: #993333; font-weight: bold;">FROM</span> A <span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> B <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #66cc66;">&#40;</span>otro_id<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">WHERE</span> B.otro_id <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NULL</span></pre>
</li>
</ul>
</li>
</ul>
<p>Creo que es algo bastante evidente y simple de entender. Aplicado al MundoReal&reg; puede surgir bastantes veces, no es que estemos antes un tipo de consulta retorcida ni nada por el estilo. Habría que resaltar que estamos usando <strong>parte</strong> de la clave primaria, en ambas tablas involucradas, por lo que en principio la intuición y nuestros conocimientos de bases de datos relaciones nos sugieren que esto va a ir más rápido que el correcaminos. </p>
<p>¿<strong>Cómo</strong> resolverías esta consulta?, No me hagas pensar, veamos <a href="http://www.postgresql.org/docs/8.3/static/sql-explain.html">qué nos dice</a> <em>Postgre</em>:</p>
<pre class="sql">foo=<span style="color: #808080; font-style: italic;"># EXPLAIN SELECT * FROM A WHERE A.otro_id NOT IN (SELECT B.otro_id FROM B);</span>
                          QUERY PLAN
 Seq Scan <span style="color: #993333; font-weight: bold;">ON</span> a  <span style="color: #66cc66;">&#40;</span>cost=<span style="color: #cc66cc;">189.91</span>..<span style="color: #cc66cc;">379.84</span> rows=<span style="color: #cc66cc;">4877</span> width=<span style="color: #cc66cc;">24</span><span style="color: #66cc66;">&#41;</span>
   Filter: <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #66cc66;">&#40;</span>hashed subplan<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
   SubPlan
     -&gt;  Seq Scan <span style="color: #993333; font-weight: bold;">ON</span> b  <span style="color: #66cc66;">&#40;</span>cost=<span style="color: #cc66cc;">0.00</span>..<span style="color: #cc66cc;">165.53</span> rows=<span style="color: #cc66cc;">9753</span> width=<span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span>
&nbsp;</pre>
<p>Parece buen plan, primero hará un hash de los valores que se le indican en <em>B</em>, le da un coste de menos de 2 décimas (son milésimas los valores) y calcula que devolverá 9753 columnas (que son todas las que hay), luego dice que filtrará todos los de A que no se encuentren en ese hash. Es lo que le hemos pedido, correcto. A este segundo paso le da una estimación de menos de 2 décimas también, y cree que saldrán 4877 resutlados (esto son todo estimaciones, postgre ahora mismo no ha ejecutado nada, solo nos cuenta su vida).</p>
<p><em>MySQL</em> es un poco más tímido y <a href="http://dev.mysql.com/doc/refman/5.0/en/using-explain.html">no da tanto detalle</a>, pero también podemos pedir que nos explique qué va a hacer:</p>
<pre class="mysql">mysql&gt; <span style="color: #993333; font-weight: bold;">EXPLAIN</span> <span style="color: #993333; font-weight: bold;">SELECT</span> * <span style="color: #993333; font-weight: bold;">FROM</span> A <span style="color: #993333; font-weight: bold;">WHERE</span> A.otro_id <span style="color: #aa3399; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> B.otro_id <span style="color: #993333; font-weight: bold;">FROM</span> B<span style="color: #66cc66;">&#41;</span> \G
*************************** <span style="color: #cc66cc;">1</span>. row ***************************
           id: <span style="color: #cc66cc;">1</span>
  select_type: PRIMARY
        table: A
         type: index
possible_keys: <span style="color: #aa3399; font-weight: bold;">NULL</span>
          key: PRIMARY
      key_len: <span style="color: #cc66cc;">178</span>
          ref: <span style="color: #aa3399; font-weight: bold;">NULL</span>
         rows: <span style="color: #cc66cc;">9754</span>
        Extra: <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span>; <span style="color: #993333; font-weight: bold;">USING</span> index
*************************** <span style="color: #cc66cc;">2</span>. row ***************************
           id: <span style="color: #cc66cc;">2</span>
  select_type: DEPENDENT SUBQUERY
        table: B
         type: index
possible_keys: <span style="color: #aa3399; font-weight: bold;">NULL</span>
          key: PRIMARY
      key_len: <span style="color: #cc66cc;">178</span>
          ref: <span style="color: #aa3399; font-weight: bold;">NULL</span>
         rows: <span style="color: #cc66cc;">9753</span>
        Extra: <span style="color: #993333; font-weight: bold;">USING</span> <span style="color: #993333; font-weight: bold;">WHERE</span>; <span style="color: #993333; font-weight: bold;">USING</span> index</pre>
<p>Básicamente dice que si, que va a usar clave primaria para ambas partes y punto. ¡Qué sabiduría!.</p>
<p>Ok, pues vamos a comparar. Podía simplemente ejecutar la consulta y santas pascuas, pero como me apetece comparar también cual es el coste a realizar trabajo de la base de datos vía código, he hecho un pequeño script en ruby, usando ActiveRecord para manejar las conexiones a la base de datos de forma simple. El código entero lo pongo targzeado al final, ahora pongo aquí la parte que interesa:</p>
<pre class="ruby"><span style="color:#CC00FF; font-weight:bold;">Benchmark</span>.<span style="color:#9900CC;">bmbm</span><span style="color:#006600; font-weight:bold;">&#123;</span> |b|
   <span style="color:#008000; font-style:italic;"># uno! El brikindans!, digo consulta en MySQL &quot;normal&quot; con el NOT IN</span>
   b.<span style="color:#9900CC;">report</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;(1) Consulta en MySQL&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      execute_with <span style="color:#6666ff; font-weight:bold;">MySQL::A</span>, <span style="color:#ff3333; font-weight:bold;">:normal</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
   <span style="color:#008000; font-style:italic;"># La misma que en (1) pero con PostgreSQL</span>
   b.<span style="color:#9900CC;">report</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;(2) Consulta en PostgreSQL&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      execute_with <span style="color:#6666ff; font-weight:bold;">PostgreSQL::A</span>, <span style="color:#ff3333; font-weight:bold;">:normal</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
   <span style="color:#008000; font-style:italic;"># La misma que en (1) pero con SQLite3</span>
   b.<span style="color:#9900CC;">report</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;(3) Consulta en SQLite3&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      execute_with <span style="color:#6666ff; font-weight:bold;">Sqlite3::A</span>, <span style="color:#ff3333; font-weight:bold;">:normal</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
   <span style="color:#008000; font-style:italic;"># Consulta con MySQL pero esta vez usando LEFT JOIN</span>
   b.<span style="color:#9900CC;">report</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;(4) Consulta en MySQL (LEFT JOIN)&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      execute_with <span style="color:#6666ff; font-weight:bold;">MySQL::A</span>, <span style="color:#ff3333; font-weight:bold;">:left_join</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
   <span style="color:#008000; font-style:italic;"># La misma que en (4) pero con PostgreSQL</span>
   b.<span style="color:#9900CC;">report</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;(5) Consulta en PostgreSQL (LEFT JOIN)&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      execute_with <span style="color:#6666ff; font-weight:bold;">PostgreSQL::A</span>, <span style="color:#ff3333; font-weight:bold;">:left_join</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
   <span style="color:#008000; font-style:italic;"># La misma que en (4) pero con SQLite3</span>
   b.<span style="color:#9900CC;">report</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;(6) Consulta en SQLite3 (LEFT JOIN)&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      execute_with <span style="color:#6666ff; font-weight:bold;">Sqlite3::A</span>, <span style="color:#ff3333; font-weight:bold;">:left_join</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
   <span style="color:#008000; font-style:italic;"># Hacemos el proceso en código de forma penosa, con un coste Ɵ(n^2)</span>
   b.<span style="color:#9900CC;">report</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;(7) Consulta en código (noob mode)&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      as = <span style="color:#6666ff; font-weight:bold;">MySQL::A</span>.<span style="color:#9900CC;">find</span> <span style="color:#ff3333; font-weight:bold;">:all</span>
      bs = <span style="color:#6666ff; font-weight:bold;">MySQL::B</span>.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">map</span><span style="color:#006600; font-weight:bold;">&#123;</span>|i| i.<span style="color:#9900CC;">otro_id</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      as.<span style="color:#CC0066; font-weight:bold;">select</span><span style="color:#006600; font-weight:bold;">&#123;</span>|i| !bs.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>i.<span style="color:#9900CC;">otro_id</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">size</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
   <span style="color:#008000; font-style:italic;"># Hacemos el proceso en código pero de forma decente, restando conjuntos</span>
   b.<span style="color:#9900CC;">report</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;(8) Consulta en código (MySQL)&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#6666ff; font-weight:bold;">MySQL::A</span>.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">map</span><span style="color:#006600; font-weight:bold;">&#123;</span>|i| i.<span style="color:#9900CC;">otro_id</span> <span style="color:#006600; font-weight:bold;">&#125;</span> -
       <span style="color:#6666ff; font-weight:bold;">MySQL::B</span>.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">map</span><span style="color:#006600; font-weight:bold;">&#123;</span>|i| i.<span style="color:#9900CC;">otro_id</span> <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">size</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
   <span style="color:#008000; font-style:italic;"># La misma que en (8) pero con PostgreSQL</span>
   b.<span style="color:#9900CC;">report</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;(9) Consulta en código (PostgreSQL)&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#6666ff; font-weight:bold;">PostgreSQL::A</span>.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">map</span><span style="color:#006600; font-weight:bold;">&#123;</span>|i| i.<span style="color:#9900CC;">otro_id</span> <span style="color:#006600; font-weight:bold;">&#125;</span> -
       <span style="color:#6666ff; font-weight:bold;">PostgreSQL::B</span>.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">map</span><span style="color:#006600; font-weight:bold;">&#123;</span>|i| i.<span style="color:#9900CC;">otro_id</span> <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">size</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
   <span style="color:#008000; font-style:italic;"># La misma que en (8) pero con SQLite3</span>
   b.<span style="color:#9900CC;">report</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;(10) Consulta en código (SQLite3)&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#6666ff; font-weight:bold;">Sqlite3::A</span>.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">map</span><span style="color:#006600; font-weight:bold;">&#123;</span>|i| i.<span style="color:#9900CC;">otro_id</span> <span style="color:#006600; font-weight:bold;">&#125;</span> -
       <span style="color:#6666ff; font-weight:bold;">Sqlite3::B</span>.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">map</span><span style="color:#006600; font-weight:bold;">&#123;</span>|i| i.<span style="color:#9900CC;">otro_id</span> <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">size</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#006600; font-weight:bold;">&#125;</span></pre>
<p>He aquí los resultados en mi pc, con <em>MySQL 5.0.45</em>, <em>PostgreSQL 8.2.7</em> y <em>SQLite 3.4.2</em> (<strong>sin</strong> tunear ninguna, tal y cual vienen en Ubuntu 7.10) y unos 10k registros en cada tabla.</p>
<pre class="bash">$ ./mysqlVsPostgresqlVsSQLite3.rb
Rehearsal --------------------------------------------------------------------------
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en MySQL                    <span style="color: #000000;">0.020000</span>   <span style="color: #000000;">0.000000</span>   <span style="color: #000000;">0.020000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #000000;">54.567416</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en PostgreSQL               <span style="color: #000000;">0.000000</span>   <span style="color: #000000;">0.000000</span>   <span style="color: #000000;">0.000000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">0.100255</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">3</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en SQLite3                  <span style="color: #000000;">0.180000</span>   <span style="color: #000000;">0.030000</span>   <span style="color: #000000;">0.210000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">0.295534</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">4</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en MySQL <span style="color: #7a0874; font-weight: bold;">&#40;</span>LEFT JOIN<span style="color: #7a0874; font-weight: bold;">&#41;</span>        <span style="color: #000000;">0.000000</span>   <span style="color: #000000;">0.000000</span>   <span style="color: #000000;">0.000000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #000000;">54.656340</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">5</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en PostgreSQL <span style="color: #7a0874; font-weight: bold;">&#40;</span>LEFT JOIN<span style="color: #7a0874; font-weight: bold;">&#41;</span>   <span style="color: #000000;">0.000000</span>   <span style="color: #000000;">0.000000</span>   <span style="color: #000000;">0.000000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">0.080631</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">6</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en SQLite3 <span style="color: #7a0874; font-weight: bold;">&#40;</span>LEFT JOIN<span style="color: #7a0874; font-weight: bold;">&#41;</span>     <span style="color: #000000;">47.980000</span>   <span style="color: #000000;">0.360000</span>  <span style="color: #000000;">48.340000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #000000;">54.249483</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">7</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en código <span style="color: #7a0874; font-weight: bold;">&#40;</span>noob mode<span style="color: #7a0874; font-weight: bold;">&#41;</span>      <span style="color: #000000;">21.660000</span>   <span style="color: #000000;">0.200000</span>  <span style="color: #000000;">21.860000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #000000;">30.060858</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">8</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en código <span style="color: #7a0874; font-weight: bold;">&#40;</span>MySQL<span style="color: #7a0874; font-weight: bold;">&#41;</span>           <span style="color: #000000;">0.520000</span>   <span style="color: #000000;">0.040000</span>   <span style="color: #000000;">0.560000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">0.696692</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">9</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en código <span style="color: #7a0874; font-weight: bold;">&#40;</span>PostgreSQL<span style="color: #7a0874; font-weight: bold;">&#41;</span>      <span style="color: #000000;">0.960000</span>   <span style="color: #000000;">0.060000</span>   <span style="color: #000000;">1.020000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">1.203388</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">10</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en código <span style="color: #7a0874; font-weight: bold;">&#40;</span>SQLite3<span style="color: #7a0874; font-weight: bold;">&#41;</span>        <span style="color: #000000;">3.410000</span>   <span style="color: #000000;">0.190000</span>   <span style="color: #000000;">3.600000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">4.141494</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
---------------------------------------------------------------- total: <span style="color: #000000;">75</span>.610000sec
&nbsp;
                                             user     system      total        real
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en MySQL                    <span style="color: #000000;">0.160000</span>   <span style="color: #000000;">0.010000</span>   <span style="color: #000000;">0.170000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">0.200753</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en PostgreSQL               <span style="color: #000000;">0.000000</span>   <span style="color: #000000;">0.000000</span>   <span style="color: #000000;">0.000000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">0.027388</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">3</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en SQLite3                  <span style="color: #000000;">0.140000</span>   <span style="color: #000000;">0.010000</span>   <span style="color: #000000;">0.150000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">0.148729</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">4</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en MySQL <span style="color: #7a0874; font-weight: bold;">&#40;</span>LEFT JOIN<span style="color: #7a0874; font-weight: bold;">&#41;</span>        <span style="color: #000000;">0.010000</span>   <span style="color: #000000;">0.000000</span>   <span style="color: #000000;">0.010000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">0.000826</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">5</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en PostgreSQL <span style="color: #7a0874; font-weight: bold;">&#40;</span>LEFT JOIN<span style="color: #7a0874; font-weight: bold;">&#41;</span>   <span style="color: #000000;">0.000000</span>   <span style="color: #000000;">0.000000</span>   <span style="color: #000000;">0.000000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">0.025892</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">6</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en SQLite3 <span style="color: #7a0874; font-weight: bold;">&#40;</span>LEFT JOIN<span style="color: #7a0874; font-weight: bold;">&#41;</span>     <span style="color: #000000;">51.810000</span>   <span style="color: #000000;">0.370000</span>  <span style="color: #000000;">52.180000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #000000;">69.148641</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">7</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en código <span style="color: #7a0874; font-weight: bold;">&#40;</span>noob mode<span style="color: #7a0874; font-weight: bold;">&#41;</span>      <span style="color: #000000;">21.340000</span>   <span style="color: #000000;">0.200000</span>  <span style="color: #000000;">21.540000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #000000;">24.971090</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">8</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en código <span style="color: #7a0874; font-weight: bold;">&#40;</span>MySQL<span style="color: #7a0874; font-weight: bold;">&#41;</span>           <span style="color: #000000;">0.420000</span>   <span style="color: #000000;">0.010000</span>   <span style="color: #000000;">0.430000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">0.503471</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">9</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en código <span style="color: #7a0874; font-weight: bold;">&#40;</span>PostgreSQL<span style="color: #7a0874; font-weight: bold;">&#41;</span>      <span style="color: #000000;">0.970000</span>   <span style="color: #000000;">0.070000</span>   <span style="color: #000000;">1.040000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">2.188352</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">10</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> Consulta en código <span style="color: #7a0874; font-weight: bold;">&#40;</span>SQLite3<span style="color: #7a0874; font-weight: bold;">&#41;</span>        <span style="color: #000000;">3.170000</span>   <span style="color: #000000;">0.120000</span>   <span style="color: #000000;">3.290000</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>  <span style="color: #000000;">3.581979</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre>
<p>Adicionalmente he hecho también la prueba usando <strong>Microsoft Access 2003</strong>, gracias a <a href="http://blog.behindlogic.com/2007/07/msaccess-for-rails-heres-your-rough.html">este connector</a> (que lo he usado para cargar todos los datos). No lo he incluido en las pruebas porque solo funciona bajo Windows, así que he ejecutado las consulta a mano. La primera de ellas le cuesta unos 200 seg aproximadamente mientras que el left join lo ejecuta casi al instante, no más de <strong>0.25 segundos</strong>.</p>
<p>Mirando entonces todos los resultados, podemos observar como a <em>MySQL</em> le cuesta dos veces más que la ineficiente consulta con código y 700 veces más que a <em>Postgre</em>. Curioso, oye. En la segunda pasada <em>MySQL</em> ha cacheado el resultado (pero si haces otras consultas y volvemos a hacer ésta, tardaría de nuevo su tiempo <em>"normal"</em>) y es bastante más rápido. </p>
<p>En resumen se podría decir que es totalmente <strong>inaceptable</strong> (al menos para esta simple consulta de dos tablas) usar:</p>
<ul>
<li>MySQL (en cualquier caso)</li>
<li>SQLite usando LEFT JOINs (pero funciona perfectamente con subconsulta)</li>
<li>MS Access usando subconsulta (pero funciona perfectamente con LEFT JOINs)</li>
<li>Hacer el trabajo en código de forma estúpida (es lo que tiene)</li>
</ul>
<p>Por lo tanto, según mi propia interpretación, diría que nos quedan solo tres opciones (si consideramos únicamente estas 4 opciones como base de datos a usar) :</p>
<ul>
<li>Usar PostgreSQL</li>
<li>Usar la base de datos <em>'X'</em> para un <em>X</em> <strong>distinto</strong> a <strong>MySQL</strong> y probar nuestras consultas para ver si le gustan o no al <acronym title="sistema gestor de base de datos">SGBD</acronym></li>
<li>Usar la base de datos 'X', para un X cualquiera, emplear consultas triviales y filtrar en código de forma decente. (opción poco viable para entornos reales cuando tengamos millones de registros y no solo 10 mil)</li>
</ul>
<p>Y hasta aquí todo, que cada uno saque sus propias conclusiones. No voy a decir que <em>MySQL</em> es una puta mierda, o que <em>PostgreSQL</em> suele ser más lento que el caballo del malo, a decir verdad lo que si que diré es que los benchmark siempre son muy limitados y comparan cosas en un ámbito restringido y controlado, por lo que no sirven para nada, así que no sé para qué narices he escrito todo esto, a decir verdad no sé ni para que estás leyéndolo, pero allá tú.</p>
<p>El <strong>código</strong>, los <em>dump</em> para postgre y mysql listos para ser cargados en sus respectivas bases de datos, la base de datos en access y la base de datos de sqlite3 los dejó <a href="http://bicosyes.com/code/MySQLvsPostgreSQLvsSQLite3vsMSAccess.tar.gz">en este fichero</a> por si quieres jugar un rato. Se requiere (aparte de las base de datos obviamente) <em>active record</em> y <em>composite primary keys</em> (ambos instalables como gemas, <em>gem install composite_primary_keys</em>, por ejemplo).</p>
<img src="http://bicosyes.com/?ak_action=api_record_view&id=620&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://bicosyes.com/benchmark-mysql-vs-postgresql-vs-ruby/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Bases de Datos Temporales</title>
		<link>http://bicosyes.com/bases-de-datos-temporales/</link>
		<comments>http://bicosyes.com/bases-de-datos-temporales/#comments</comments>
		<pubDate>Wed, 17 Jan 2007 14:22:56 +0000</pubDate>
		<dc:creator>blaxter</dc:creator>
				<category><![CDATA[Bases de Datos]]></category>

		<guid isPermaLink="false">http://bicosyes.com/bases-de-datos-temporales/</guid>
		<description><![CDATA[Cuando empecé a investigar sobre las bases de datos temporales me sorprendí por dos motivos, primero porque al final he tenido que recurrir a libros que me han sido mucho más útiles que todo lo que he podido llegar a encontrar en Internet (donde todos los textos eran muy ligeros o escasos en cuanto a [...]]]></description>
			<content:encoded><![CDATA[<p>Cuando empecé a investigar sobre las bases de datos temporales me sorprendí por dos motivos, primero porque al final he tenido que recurrir a libros que me han sido mucho más útiles que todo lo que he podido llegar a encontrar en Internet (donde todos los textos eran muy ligeros o escasos en cuanto a profundización en la materia), y segundo por la complejidad del tema, puesto que en realidad lo elegí porque parecía simple, error, craso error.<br />&nbsp;<br />Antes he hecho la presentación y, en conclusión, me podría apostar un bote de palomitas a que nadie se ha enterado de lo que en realidad es una base de datos temporal, al menos, no el profesor, pues por las preguntas y afirmaciones que ha hecho al final, eso se podía deducir, y dado que la mitad de la gente se dedicaba a hablar con los demás, o pensar en maneras de hacerme callar lenta y dolorosamente, creo que ganaría ese bote de palomitas <img src='http://bicosyes.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> <br />&nbsp;<br />Como he dicho antes, encontré muy poco material sobre el tema, no hablemos ya en castellano. Así que voy a dejar aquí colgada la presentación, la cual intenté hacerla algo así como unos <i>mini-apuntes</i> que pudiesen tener contenido completo por ellos mismos. Y además un par de pdf's sobre TSQL2, la especificación y un ejemplo práctico.
<ul>
<li><a href="/code/BD_Temporales">BD Temporales</a> (si se te ve muy grande, reduce el tamaño de letra o ponlo a pantalla completa)</li>
<li><a href="/code/BD_Temporales/TSQL2.tar.gz">TSQL2</a></li>
</ul>
<img src="http://bicosyes.com/?ak_action=api_record_view&id=401&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://bicosyes.com/bases-de-datos-temporales/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Bases de datos: paradigmas y tendencias</title>
		<link>http://bicosyes.com/bases-de-datos-paradigmas-y-tendencias/</link>
		<comments>http://bicosyes.com/bases-de-datos-paradigmas-y-tendencias/#comments</comments>
		<pubDate>Tue, 16 Jan 2007 20:16:14 +0000</pubDate>
		<dc:creator>blaxter</dc:creator>
				<category><![CDATA[Bases de Datos]]></category>

		<guid isPermaLink="false">http://bicosyes.com/bases-de-datos-paradigmas-y-tendencias/</guid>
		<description><![CDATA[Debido a una asignatura de la carrera, Bases de datos avanzadas, he tenido que investigar sobre bases de datos temporales. Pero, en verdad, existen muchos tipos de paradigmas y/o tendencias en las BD, muchas de ellas en verdad interrelacionadas entre sí. Voy a intentar hacer un resumen de todas ellas o, al menos, de las [...]]]></description>
			<content:encoded><![CDATA[<p>Debido a una asignatura de la carrera, <em>Bases de datos avanzadas</em>, he tenido que investigar sobre <strong>bases de datos temporales</strong>. Pero, en verdad, existen muchos tipos de <em>paradigmas</em> y/o <em>tendencias</em> en las BD, muchas de ellas en verdad interrelacionadas entre sí. Voy a intentar hacer un resumen de todas ellas o, al menos, de las que considero más relevantes.</p>
<div style="text-align:justify;">
<ul  style="text-align:justify;">
<li  style="text-align:justify;"><strong>Relacionales</strong>, es la base de todo. El modelo más estudiado, comercializado y utilizado. No por ello el mejor, sino que ciertos aspectos (estar en el momento justo, en el lugar indicado) han hecho que así llegue a ser. En definitiva, actualmente hablar de BD es hablar de BD relacionales. Pero todo está cambiando, sino no escribiría este post realmente. Si no sabes qué es el modelo relacional, significa que no sabes que es una BD, por lo que no creo que entiendas el resto de cosas que voy a contar y no se ni para que me lees este tochaco, pero bueno.</li>
<li  style="text-align:justify;"><strong>Orientadas a objeto</strong>, si todas nuestras aplicaciones son con objetos, es tontería querer mantener el modelo relacional por debajo, ¿no?. Existen diferentes ORM que permiten solventar ese inmenso puente entre un modelo de objetos y el modelo relacional, pero si podemos prescindir de él, ¿qué mejor que nuestro SGBD nos entienda directamente y nos guarde objetos directamente?. Hay ciertas cosas bastante llamativas en una BDOO, como que no es necesario tener claves primarias, o las claves ajenas en verdad ahora son referencias. Se podría hablar mucho sobre este tema, pero resumiendo una BDOO son simplemente nuestros objetos hechos persistentes. ¡Capas de persistencia <em>nunca mais</em>! <img src='http://bicosyes.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
</li>
<li  style="text-align:justify;"><strong>Activas</strong>, una SGBD activo es aquel, que bajo ciertas condiciones, y de manera automática ejecuta acciones anteriormente especificadas, todo ello sin intervención del usuario. Es decir una especie de BD + super-triggers (BD relacional con triggers <b>no</b> es una BD activa). Se puede subdividir en dos modelos que lo constituyen:
<ul>
<li>Modelo del conocimiento: especifica las reglas del sistema, en resumen serían tuplas (Evento, Condición, Acción).</li>
<li>Modelo de ejecución: se encarga de realizar un seguimiento de la situación y de gestionar el comportamiento. Vamos, el jefe que dice qué hacer y cómo.</ul>
</li>
<li  style="text-align:justify;"><strong>Deductivas</strong>, un SGBD deductivo es aquel que es capaz, a partir de un conjunto de axiomas deductivos y reglas de inferencias que ya posee, deducir hechos. Una especie de BD + lógica (BD + prolog, imagínate sql + prolog, dios que miedo!). Un esquema global podría ser que recibida una consulta concreta, el SGBD deductivo según unas determinadas reglas de inferencia consulta sus datos para obtener una respuesta. Este modelo está muy ligado a las BD Activas, y tienden a converger. Tanto las BD Activas y como las Deductivas podrían englobarse en el área de <strong>representación del conocimiento</strong>, quizá por ello tiendan a converger.</li>
<li  style="text-align:justify;"><strong>Temporales</strong>, ¡no existen los datos!, adiós datos; bienvenidos los datos temporales (dato + tiempo). Cada dato tendrá información de <b>tiempo válido</b> (cuando ese dato es, o ha sido, válido en el MundoReal) y de <b>tiempo transaccional</b> (cuando ese dato ha estado en la BD). Es decir, ahora no se guarda información, bueno si, pero se guarda junto con su <b>evolución</b> en el tiempo. Todavía es un campo muy ligado a la investigación, a pesar de que son realmente muy interesantes.
</li>
<li  style="text-align:justify;"><strong>Difusas</strong>, <i>casi toda la información que manejamos acerca del MundoReal es incompleta, imprecisa y vaga</i>. Las BD Difusas se basan en la lógica difusa que a su vez se basa en álgebra de conjuntos difusa, que viene a ser mayormente que dado un conjunto de elementos se le da un valor a cada elemento, entre 0 y 1, que indica el grado de pertenencia que tiene dicho elemento en ese conjunto. Este modelo se una ampliación de las BD relaciones, y amplía los operadores del álgebra relacional para poder adaptarlos a los nuevos elementos que se definen. Emocionante.
</li>
<li  style="text-align:justify;"><strong>Multimedia</strong>, actualmente estamos desbordados por audio, video, imagenes, texto, en definitiva documentos multimedia. Éstos por poder se pueden guardar en campos "Blobs" (binary large objets), pero ya que hacemos modelos de BD para todo lo que se nos ocurre, pues que mejor que una BD Multimedia?. El principal inconveniente está en que una BD tradicional carece de una interfaz de usuario para poder tratar con estos datos multimedia, sin mencionar el problema de la inclusión de metadatos (que se podría solventar, si. Pero serían todo soluciones muy "ad-hoc", eso de ingieneril tiene poco). Las BD Multimedia proponen tres niveles: Un nivel monomedia que trataría con un solo tipo de datos (p.ej. audio), un nivel central que hablaría con todos los niveles inferiores y desde el cual se gestionarían las preguntas y se guardarían los metadatos de todos los elementos de la BD; y un último nivel con una interfaz de usuario para poder manejar cada formato multimedia. Todo esto quizá es muy ambicioso, hay BD actualmente usándose como las BD Documentales que serían un subconjunto de las Multimedia. Quizá sea porque, evidentemente, el texto ha sido lo primero que se ha querido salvar en una BD, tiempo al tiempo...
</li>
</ul>
</div>
<p>No son todas las que están, ni están todas las que son. Se podría añadir al conjunto, BD Distribuidas, Federadas, Almacenes de datos (aunque no son BD en el sentido estricto de la palabra), Paralelas, etc... Pero no las considero como un "paradigma" de BD <img src='http://bicosyes.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Por cierto, si has llegado a leer hasta aquí eres <strong>macgyver</strong>!</p>
<img src="http://bicosyes.com/?ak_action=api_record_view&id=396&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://bicosyes.com/bases-de-datos-paradigmas-y-tendencias/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Motores de almacenamiento de MySQL</title>
		<link>http://bicosyes.com/motores-de-almacenamiento-de-mysql/</link>
		<comments>http://bicosyes.com/motores-de-almacenamiento-de-mysql/#comments</comments>
		<pubDate>Sat, 23 Sep 2006 10:24:16 +0000</pubDate>
		<dc:creator>blaxter</dc:creator>
				<category><![CDATA[Bases de Datos]]></category>

		<guid isPermaLink="false">http://bicosyes.com/motores-de-almacenamiento-de-mysql/</guid>
		<description><![CDATA[Como bien sabrás, querido picacódigo, MySQL es una base de datos relacional de licencia GPL, ésto implica que usa tablas para guardar los datos, visto desde su representación lógica (como lo vemos nosotros, los usuarios). Pero, por dentro, usa un motor de almacenamiento (storage engine) que será el encargado de guardar de verdad los datos [...]]]></description>
			<content:encoded><![CDATA[<p><img id="image314" src="http://bicosyes.com/wp-content/mysql_100x52-64.gif" alt="mysql_100x52-64.gif" class="flota"/>Como bien sabrás, querido <em>picacódigo</em>, <strong>MySQL</strong> es una base de datos relacional de licencia GPL, ésto implica que usa tablas para guardar los datos, visto desde su representación lógica (como lo vemos nosotros, los usuarios). Pero, por dentro, usa un motor de almacenamiento (<strong>storage engine</strong>) que será el encargado de guardar de verdad los datos a ficheros, según una determinada estrategia. Este motor es totalmente clave a la hora de evaluar la rápidez y las funcionalidades que puede tener el SGBD. MySQL tiene la opción (para cada tabla que se vaya a crear) de establecer explicitamente qué motor usar.
<ul>
<li><strong>MyISAM</strong>, el motor por defecto, permite lo típico, pero no permite transacciones, toda las consultas se realizan con autocommit. Por lo demás no hay mucho que comentar, como curiosidad decir que los BLOB o TEXT pueden ser indices, e incluso un campo que sea indice puede tomar valor NULL. Usa Arboles B internamete para los indices (<strong>separado</strong> de los datos) y tiene herramientas para chequeo y reparación de tablas.</li>
<li><strong>BLACKHOLE</strong>: si tiene un nivel de inglés tan patetico como el mio (o superior) fijo que descubres que hace este motor (blackhole = agujero negro). Sería el equivalente a /dev/null mayormente. Y dirás, ¿y esto para que cojones lo quiero yo?, pues puede llegar a ser útil, pues cuando realizas una transacción con este motor, auque <strong>no</strong> se guardan los datos, ni te va a devolver nada, <strong>si</strong> que crea LOG de la sentencia SQL que se "ha ejecutado". El caso típico podría ser establecer un servidor esclavo para que de ese modo guardará el log de lo que pasa en el master</li>
<li><strong>CSV</strong>, motor completamente trivial, que guarda cada tabla en un fichero y cada fila de datos es una linea con los datos separados por comas. Queda claro, no?. Para hacer la gracia decir que <strong>no</strong> soporta indices (imagina buscar en ficheros... coste secuencial! <i>O(n)</i> OMFG!). Este formato sería usado mas bien para crear archivos listos para ser importados por otros programas.</li>
<li><strong>ARCHIVE</strong>, el motor almacen almacen, solo soporta INSERT's y SELECT's, es decir un almacen!. Además, siempre que escribes datos se comprimen (con <strong>zlib</strong>), así que es el motor típico para una base de datos histórica o cuando vamos a tener una cantidad realmente enorme de datos (quizás sea la idonea para GIS?, habría que meditarlo...). Decir que si se realizan muchos SELECT a la vez que se realizan INSERT provocaría que el motor se hiciese la picha un lio, ¿por qué? Porque cuando se hace un INSERT los datos van a un buffer (para no tener que recomprimir, con zlib, para cada puta linea que se inserta supongo...) y éstos datos serán flusheados cuando se realice el SELECT, ahora piensa cientos de INSERT y SELECT en paralelo. Da miedo, eh?</li>
<li><strong>EXAMPLE</strong>, este no sirve para nada, jaja. Es solo un ejemplo de motor, para poder mirar su código y crear motores hechos y derechos</li>
<li><strong>FEDERATED</strong>, motor nuevo que se incorporó en la versión 5 de MySQL, para poder crear bases de datos <strong>federadas</strong>, esto significa que estaremos consultando a una bases de datos remota, es decir en nuestro servidor creamos la tabla pero le decimos, <i>oye que esta tabla esta en otro lado, si eso, le preguntas, que fijo que te responde</i>. Este modelo tiene ciertas limitaciones, no permite ALTER's ni transacciones.</li>
<li><strong>MERGE</strong>, este es facil, si tienes dos tablas con motor MyISAM y con la misma estructura, al crear una tabla MERGE, juntarás los datos de ambas tablas. Un caso para el cual puede ser útil este motor, podría ser, por ejemplo, diferentes tablas de log en diferentes servidores y te creas en uno de ellos tablas FEDERATED de esas tablas (que serán MyISAM) y entonces creas una tabla de "log_principal" (usando MERGE) que tendrá el log de todos los servidores. arrr marinero.</li>
<li><strong>MEMORY</strong>, tablas que se guardan en memoria, es decir, cuando reinicies MySQL, adios datos. No le encuentro ninguna utilidad la verdad, si quieres un almacenamiento temporal, que sentido tiene entonces usar un SGBD? Pues ninguno!.</li>
<li><strong><a href="http://www.sleepycat.com/">Berkeley DB</a></strong> (BDB para los friends), una de las bases de datos openSource más famosa y utilizada. El motor es independiente de MySQL, con las ventajas e inconvenientes que esto pueda acarrear. Permite transacciones (COMMIT & ROLLBACK) y solo puede ejecutarse en sistemas operativos soportados (Linux x86 y Windows, si; Mac OS X feo y Linux AMD64/Alpha, no). Como curiosidad decir que su organización de ficheros se basa en solo dos, puesto que utiliza árboles B donde, en cada nodo, están tanto los datos como el índice primario (lo cual implica que será algo más lento a la hora de recorrerlo secuencialmente)</li>
<li><strong>InnoDB</strong>, es el motor más avanzado (junto con BDB) en cuanto a opciones y funcionalidad. Permite transacciones seguras (COMMIT y  tal) y está orientado a manejar grandes cantidad de datos. Realiza el bloqueo usando como granualidad la fila (BDB lo hace a nivel de página, es decir mayor salvo casos raros de filas enormes) e incluso soporta lecturas consistentes tanto bloqueantes como no bloqueantes.</li>
</ul>
<p>Como reflexión final decir que los únicos motores que soportar transacciones seguras son BDB e InnoDB. BDB es externo a MySQL (se usa en muchos otros proyectos, como OpenLDAP por ejemplo...) y fue comprado por ORACLE hace unos meses (febrero)... lo mosqueante es que InnoDB también ha sido comprado por ORACLE (antes de la compra de BDB), por lo que así a lo tonto, ORACLE se ha hecho con el control de los únicos motores de MySQL que soportan transacciones, intrigante... y quizás preocupante... Y con esto y un bizcocho...</p>
<img src="http://bicosyes.com/?ak_action=api_record_view&id=307&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://bicosyes.com/motores-de-almacenamiento-de-mysql/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

