Diferencias entre clave primaria y clave foránea

Vamos con una entrada de SQL básico, uno de los fundamentos del modelo relacional ¿Qué diferencia existe entre una clave primaria y una foránea?

En el diseño de una base de datos relacional la clave primaria es el campo, o conjunto de campos, que nos permite identificar de forma única un registro. Por así decirlo es como el DNI de esa tabla. Se trata de un valor, o grupo de valores, único que nos permitirá diferenciar un registro concreto. Podemos definir la clave primaria en el momento de la creación de la tabla, dentro de la sintaxis del CREATE TABLE, o a posteriori añadiendo la regla en un ALTER TABLE.

Por su parte la clave foránea es un campo, o conjunto de campos, que nos permite relacionar un registro de una tabla con otro, generalmente de una tabla distnta . Como ejemplo piensa en la clásica base de datos de una tienda, en la que tienes una tabla con productos, cada uno de los cuales tiene un código (que será la clave primaria), una descripción y un precio. Por otra parte tienes una tabla en la que registras las ventas, y podrías tener un código para cada una, la fecha, la hora y el producto. Para identificar el producto en esa tabla lo más práctico, para no repetir información, sería utilizar el código de la tabla de productos (la clave primaria de la primera tabla, que en esta se convierte en clave externa).

Una tabla puede tener relaciones con varias a través de distintas claves foráneas, e incluso referenciarse a si misma (clave foránea recursiva). Al igual que con la clave primaria podemos definir las claves foráneas dentro de la sintaxis de creación de la tabla o a posteriori con un ALTER TABLE.

Por tanto la diferencia es sencilla: la clave primaria identifica un registro único de una tabla. La clave foránea relaciona los datos de un registro de una tabla con los de otra, o con un registro distinto de la misma tabla.

Instalar un emulador de Super Nintendo en Linux

¿Echas de menos unas partidillas a Street Fighter, Mario World o Castlevania IV en tu Super NES? Pues tranquilo, como usuario de Linux puedes contar con un emulador, que además para el caso de los usuarios de Ubuntu está disponible en los repositorios oficiales. Para ello basta con instalar desde la consola:

sudo apt-get install zsnes

Super Ghouls and Ghosts

Con esto ya está el emulador listo, pero todavía necesitas los juegos. Los viejos cartuchos eran memorias de sólo lectura, y es posible encontrar diversas webs desde las que descargar ficheros que contienen todos los archivos de estos juegos. Aquí una pequeña lista con algunas de estas webs:

Donkey Kong Country SNES

Una vez descargados los archivos, los copiáis tal cual, comprimidos en .zip (ojito, en FreeRoms bajan en 7z y no me los reconocía, pero basta con descomprimir y volver a comprimir como .zip) en una carpeta. Al ejecutar zsnes en el menú GAME podéis ir a la opción LOAD y desde allí navegáis en el menú DIRECTORY de la derecha hasta la carpeta en la que habéis guardado las ROMs. Seleccionáis el que queráis y a jugar. En ese menú principal podéis guardar y cargar partidas, configurar los controles, etc.

La regla @page y estilos para impresión en CSS

Si bien es cierto que cada día es menos habitual imprimir cosas desde la web muchas veces puede interesarnos tener un formato específico para la impresora que nos permita ocultar menús. A la hora de meter un formato sólo para la impresora procederemos como con cualquier CSS normal, pero añadiendo en la etiqueta media=»print», como en el ejempo:

<!-- Cargando un CSS externo -->
<link href="paraimprimir.css" type="text/css" media="print" />
<!-- Insertando CSS en la cabecera -->
<style type="text/css" media="print">
/*aquí lo que corresponda*/
</style>
<!--También puede usarse esta sintaxis-->
<style type="text/css"> 
  @media print { 
      /* reglas css */ 
  } 
<style>

Con estos estilos, por ejemplo, podemos hacer que un elemento aparezca en todas las páginas definiéndolo como fixed u ocultar lo que no tenga sentido mostrar en la impresión con display:none.

El uso de media print genera una caja CSS distinta a la de pantalla (media screen) para alojar los contenidos, a pesar de que su boxmodel será el mismo. Esta caja se conoce como page y podremos acceder a ella para modificar sus características mediante el selector @page.

Dicho selector nos permite, por ejemplo, definir la orientación de la página entre normal y apaisada:

/*Orientación vertical*/
@page {size: portrait;}
/*Orientación apaisada*/
@page {size: landscape;}

También podemos utilizar clases ligadas a la regla page, por ejemplo imaginemos que queremos imprimir un informe con todas las páginas en vertical pero con las tablas y las gráficas apaisadas en una hoja aparte:

@page apaisada {size: landscape;}
table {page: apaisada; page-break-before: right;}
/*las gráficas las diferenciaremos con una clase CSS*/
.poll {page: apaisada; page-break-before: right;}

A la hora de definir el tamaño de la página debemos tener en cuenta que su total será la suma del contenido más los bordes (margin y padding), y podemos definirlo con el atributo size. Podemos utilizar valores numéricos (porcentajes, puntos, centímetros, milímetros), excepto píxeles porque pertencen al ámbito de la pantalla, o utilizar los diversos valores que definen tamaños standares de papel (A4, A3, letter). En caso de no especificar nada el tamaño será auto, que es el valor por defecto. Lo suyo es utilizar las medidas de los textos en pt y el alto y ancho de página en cm, mm o in (pulgadas), piensa que trabajamos sobre un medio físico y no sobre una pantalla que puede tener diversos tamaños y resoluciones.

@page {
  size: 8.5in 11in;  /* ancho y alto en pulgadas */  
}
@page {
  size: 21cm 190mm; /*medidas en tamaño*/
}
@page {
  size: A4; /*standar A4*/
}

Disponemos además de las pseudoclases :first, :left y :right que nos permitirán perfeccionar nuestra maquetación para la impresión a dos caras y pudiendo usar unas reglas específicas para la primera página.

/*Para la primera página usaremos un margen superior e izquierdo muy grande*/
@page :first {
  margin-top: 6cm;
  margin-left: 7cm;
}

/*definimos los márgenes de la página izquierda*/
@page :left {
  margin-right: 4cm;
  margin-left: 3cm;
}

/*y para la derecha invertimos los valores
para que la impresión a doble página
quede bien*/
@page :right {
  margin-right: 3cm;
  margin-left: 4cm;
}

Y también podemos definir cuántas líneas de un párrafo queremos dejar al final de una página como mínimo o al principio, con la intención de no dejar líneas huérfanas o viudas. Para ello disponemos de las propiedades orphans y widows (que significan huérfanas y viudas en inglés).

@page{
  orphans:5;
  widows:4;
}

¿Cómo funcionaría el ejemplo de arriba? Imaginemos que al final de una página caben 15 líneas. Si tenemos justo 15 o menos entrarán en esa página. Si tenemos 17 entonces, para no violar la regla, se repartirían 13 en la página 1 y 4 en página 2 (para cumplir el mínimo), y su tuviéramos 19 o más no habría problema: 15 en la primera y el resto en la siguiente.

Finalmente hablaremos de los saltos de página, que ya vimos en uno de los ejemplos de arriba. Y es que los elementos de bloque pueden llevar asociado un salto de página, que puede ir antes, después o dentro del elemento. Para ponerlo antes usaremos page-break-before y para hacerlo después iría page-break-after. Para hacerlo dentro usaremos page-break-inside, que tiene la particularidad de que se puede heredar del elemento contenedor mientras que los otros dos no. Para page-break-after y page-break-before puede haber cuatro valores:

  • always: fuerza siempre un salto de página antes o después del elemento, según corresponda
  • avoid: evita siempre un salto de página antes o después del elemento, según corresponda
  • left: fuerza los saltos de página que sean necesarios para que la siguiente página sea compuesta como una página izquierda
  • right: fuerza los saltos de página que sean necesarios para que la siguiente página sea compuesta como una página derecha

Y creo que con esto hemos recorrido los puntos principales el tema de los estilos CSS para impresión.

Reparar el Grub en Ubuntu

Cuando yo estudiaba el desaparecido FP de Desarrollo de Aplicaciones Informáticas (hoy convertido en DAW y DAM en busca de una mayor especialización) teníamos una asignatura genérica de Sistemas y Redes el primer año. Era un batiburrillo donde veías de todo un poco, y tuvimos la suerte de tener un profesor muy bueno, un auténtico crack (una pena que dejara la docencia para trabajar en otros proyectos) que nos eseñó mucho. Curiosamente en mi trabajo he tenido que hacer mucho cacharreo en los últimos meses, y estas pequeñas lecciones me han servido de mucho.

Una de las cosas que recuerdo haber tenido que hacer en un examen era reparar el GRUB de un Ubuntu (9.04 por aquel entonces), ejercicio fundamental porque era el primero y como no fueras capaz de hacerlo no podías seguir con el examen.

Para este proceso vamos a necesitar una distribución Linux que podamos arrancar en modo Live (desde un disco o pendrive). Una vez cargada lanzamos un terminal y a cacharrear. Empezamos por averiguar en qué partición está instalado el SO haciendo sudo fdisk-l. Para el ejemplo vamos a utilizar sda1. El siguiente paso es «montar» el disco duro de nuestro equipo en esta distribución live:

#primero montamos el disco duro del SO
sudo mount /dev/sda1 /mnt

#luego el resto de dispositivos
sudo mount –bind /dev /mnt/dev

Tras esto debemos crear una jaula chroot, un comando que nos permite acceder como root al sistema de archivos del SO instalado:

sudo chroot /mnt

Y ya en esta situación lo único que nos queda por hacer es instalar el GRUB en el Master Boot Record para que se ejecute al arranque.

grub-install –recheck /dev/sda

Existen otras soluciones, como Super Grub Disk, sencillas y rápidas, pero la descrita arriba me ha funcionado en la mayoría de los casos sin problema.

Incluir un equipo Ubuntu 14.04 en un dominio Active Directory de Windows

En este sencillo tutorial vamos a ver cómo incluir un equipo con Ubuntu (14.04 en el ejemplo) dentro de un dominio Active Directory (servidor con Windows 2k8) utilizando PowerBroker IS Open Edition, que es el software que ha «jubilado» a Likewise-Open. Los datos que usaremos para el ejemplo (y que debéis cambiar por los que correspondan en vuestro caso) son los siguientes:

Dominio: DONNIE.local
DC: SERVIDOR.DONNIE.local
IP: 192.168.100.2

Antes de comenzar mirad que la ip de vuestro equipo esté en el mismo rango que la ip del servidor. Una vez confirmado esto (si no, configuradlo) comenzaremos.

Descargamos el script correspondiente desde la web oficial y le damos permisos de ejecución con un chmod +x. Luego nos situamos en la carpeta donde lo guardamos y lo ejecutamos (cambiad el nombre del archivo por el de la versións que hayáis descargado vosotros):

sudo ./pbis-open-8.0.1.2029.linux.x86_64.deb.sh

Tras esto nos unimos al dominio (cambia administrator y el nombre del domino por los que procedan):

sudo domainjoin-cli join DONNIE.local administrator

O si lo quieres desactivando ssh por defecto:

sudo domainjoin-cli join --disable ssh DONNIE.local administrator

En el siguiente paso hay que hacer un pequeño cambio en un archivo de configuración. En el archivo /etc/pam.d/common-session debes cambiar la línea que pone session sufficient pam_lsass.so por esta: session [success=ok default=ignore] pam_lsass.so.

Y desde la consola configuramos más datos para el acceso, recordad cambiar el dominio y el grupo de usuario por el que corresponda en vuestro caso:

sudo /opt/pbis/bin/config UserDomainPrefix DONNIE
sudo /opt/pbis/bin/config AssumeDefaultDomain true
sudo /opt/pbis/bin/config LoginShellTemplate /bin/bash
sudo /opt/pbis/bin/config HomeDirTemplate %H/%U
sudo /opt/pbis/bin/config RequireMembershipOf "DONNIE\\Usuarios" 

Ahora nos queda configurar lightdm para activar el login manual:

sudo vi /usr/share/lightdm/lightdm.conf.d/50-unity-greeter.conf

#Añade las siguients líneas (sin la marca de comentario)
#allow-guest=false
#greeter-show-manual-login=true

##Nota, en Lubuntu 14.04 el archivo a cambiar será  60-lightdm-gtk-greeter.conf 

Finalmente vamos a darle permisos de sudo al usuario del dominio (ojo, si procede) editando el archivo correspondiente con un sudo vi /etc/sudoers y añadiendo los datos que sean necearios siguiendo los ejemplos contenidos en el propio documento.

Tras esto, si reiniciamos el equipo, deberíamos ya poder hacer login con el usuario del Active Directory de Windows.

Las tres mejores películas sobre baloncesto

En este blog hablamos de cine alguna vez y de baloncesto algunas más. La semana que viene ya empiezan los amistosos de preparacion para el Mundial 2014 pero mientras estamos con este mono como King Kong y con el alma en vilo por saber dónde acabará Kevin Love (y si tendremos el próximo Big Three en los Cavs con Irving – Love – LeBron o no) podemos aprovechar para visionar alguna de estas películas:

  • Una mala jugada (1998): Aunque la mayoría de los fans NBA la conocen como «la peli de Ray Allen«, y es que el excelso y veterano tirador hizo sus pinitos como actor en este drama, titulado en inglés He Got Game. Dirigida por Spike Lee el protagonista es el siempre solvente Denzel Washington, que aquí interpreta a Jake, un alcohólico encarcelado tras asesinar accidentalmente a su mujer. El gobernador del estado le ofrecerá una rebaja de su condena si logra convencer a su hijo Jesus (Ray Allen) para que juegue en el equipo de su antigua universidad, ya que el chaval ha sido una estrella en el instituto y está dudando entre dar el salto directo a la NBA (recordemos que en la realidad Kobe y Garnett lo habían hecho poco tiempo antes) o formarse en la universidad. Completan el reparto Milla Jovovich, Rosario Dawson, John Turturro (otro seguro de vida como actor) y ex jugadores como Travis Best, Walter McCarthy o un Rick Fox al que siempre le tiró la cámara.
    Ray Allen y Denzel Washington
  • Camino a la Gloria (2006): Basada en hechos reales, producida por Jerry Bruckheimer y con un reparto sin grandes nombres, con mucho profesional de la televisión y secundario clásico, junto a un Jon Voight de capa caída, originalmente se trataba de una película destinada a salir directamente en vídeo y TV, pero finalmente acabó estrenándose en cines con una aceptable taquilla en los EEUU. La historia se remonta a los años 60, cuando apenas se ofrecían becas a los jugadores negros en las universidades americanas, y mucho menos en los estados del sur. El entrenador Don Haskins llegaba a Texas Western, una modesta universidad de El Paso, sin capacidad para reclutar a los más codiciados jugadores de instituto. La estrategia de Haskins consistiría en reclutar a talentosos jugadores de raza negra que eran rechazados por otras universidades por el color de su piel, lo que le permitió ensamblar un equipo capaz de acabar el torneo regional con un balance de 23-1 y meterse en el torneo de la NCAA, despertando por el camino una oleada de sentimientos racistas al tener más jugadores afroamericanos que blancos en la plantilla. Alcanzaron la final contra la universidad de Kentucky con medio país apostando que no ganarían «porque los negros no aguantan la presión» (argumento usado por la prensa en el sur del país) Haskins decide que los jugadores blancos no saldrán a la cancha en ese partido para dar una lección a todo el rebaño racista. Si bien la película tira del aplauso fácil en algunos momentos y exagera bastante para ganar dramatismo, pintando al entrenador de Kentucky Adolph Rupp como profundamente racista o sobredimensionando los incidentes alrededor del equipo, en conjunto es efectiva para palomitear una tarde de domingo.
    Josh Lucas en Glory Road
  • Hoosiers: más que ídolos (1986): Gene Hackman y Dennis Hopper (este último se llevó una nominación al Oscar a mejor secundario por su papel) en una historia sobre superación personal. Un drama mínimamente inspirado en la victoria del Instituto Milan en el campeonato estatal de Indiana de 1954, aunque de una forma muy fugaz. El excepcional talento de los dos actores (bien secundados por Barbara Hershey) lleva la historia en volandas hasta su épico final, todo con una excelente banda sonora de Jerry Goldsmith (también nominada al Oscar). Comentaba hace un rato «la mejor película de temática deportiva» y me replicaban «Toro Salvaje»… así que tendré que matizar como «la mejor película sobre un deporte de equipo«. Cada vez que veo a Popovich en el banquillo de San Antonio no puedo evitar acordarme de Hackman interpretando a «Coach» Dale.
    Dennis Hopper Gene Hackman

La lista podría ser más larga, y más si metemos documentales (algo que creo que dejaré para otro día, tengo una larga lista), pero puestos a elegir me quedaría con estas tres.

Windows Explorer de repente no funciona como cliente FTP en Windows 7

Era complicado ponerle un título a esto, pero es algo que me encontré por la mañana. Un cliente estaba trabajando con una aplicación web para Internet Explorer que debía abrir una carpeta de un servidor FTP, funcionaba bien en todos los equipos de una red menos en uno (pulsabas un enlace de la aplicación y se abría en Explorador de Windows en la carpeta FTP), así que fuera lo que fuera era algún problema local de ese equipo. Probé de todo pero nada parecía funcionar, aunque poco a poco tachaba cosas de la lista hasta llegar a una conclusión: por algún motivo Windows Explorer no quería funcionar como cliente FTP.

Probé cambiando varias entradas en el registro, probé diversas configuraciones y al final, tras mucho darle a Google encontré esta solución: crear una entrada en el registro de Windows. La cosa consiste en copiar el texto de abajo y guardarlo en un archivo con la extensión .reg, y luego ejecutar dicho archivo para que la entrada se añada. Con esto la cosa volvió a funcionar perfectamente.

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\ftp]
@="URL:File Transfer Protocol"
"AppUserModelID"="Microsoft.InternetExplorer.Default"
"EditFlags"=dword:00000002
"FriendlyTypeName"="@C:\\Windows\\system32\\ieframe.dll,-905"
"ShellFolder"="{63da6ec0-2e98-11cf-8d82-444553540000}"
"Source Filter"="{E436EBB6-524F-11CE-9F53-0020AF0BA770}"
"URL Protocol"=""
[HKEY_CLASSES_ROOT\ftp\DefaultIcon]
@=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,\
00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,75,00,72,00,\
6c,00,2e,00,64,00,6c,00,6c,00,2c,00,30,00,00,00
[HKEY_CLASSES_ROOT\ftp\shell]
@="open"
[HKEY_CLASSES_ROOT\ftp\shell\open]

¿Y por qué había dejado de funcionar el Windows Explorer como cliente FTP por defecto? Pues tras instalar Google Chrome y definirlo como navegador por defecto este había cambiado también la configuración del cliente FTP por defecto del equipo. Tras la ejecución del cambio en el registro todo volvió a funcionar con normalidad.

Clonar un disco duro .vdi de Virtual Box

Si bien cuando estudiaba hacíamos los clonados de disco en VirtualBox tal como se harían en una máquina real, tirando del Clonezilla, existe una forma más práctica de lograrlo.

En Windows la cosa es lanzar una consola de comandos (cmd) y situarnos en la carpeta en la que hubiéramos instalado VirtualBox. Una vez allí basta con usar el siguiente comando:

VBoxManage.exe clonehd ../rutadeldisclonar.vdi ../rutadelresultado.vdi 

Obviamente tenéis que cambiar ../rutadeldisclonar.vdi por la ruta real del disco .vdi que queréis clonar, y tres cuartos de lo mismo con ../rutadelresultado.vdi que es donde se creará el nuevo archivo.

En el caso de Linux la cosa es prácticamente igual: lanzáis el terminal, os ubicáis en la carpeta donde se instaló el VirtualBox y desde allí lanzáis

sudo VBoxManage clonehd ../rutadeldisclonar.vdi ../rutadelresultado.vdi 

Como antes, cambiando las rutas fictias por las que correspondan. Y listo, disco virtual clonado por si se os corrompe el que está en uso.

Esteganografía en Linux sin instalar software adicional

Ya en el pasado hablamos de software para ocultar archivos dentro de otros (la llamada esteganografía) en Linux, como SilentEye o Outguess. Pero realmente es posible ocultar un archivo dentro de una imagen sin necesidad de software extra, valiéndonos sólo de la consola.

Lo primero es comprimir el archivo que queremos ocultar, mismamente con la herramienta nativa de compresión de Ubuntu lo transformamos en un archivo .zip (y si queréis un extra de seguridad podéis añadirle una contraseña). Para el ejemplo lo llamaremos secreto.zip mismamente.

Ahora necesitamos un archivo de imagen, para el ejemplo tendremos una que se llamará base.png, y lanzamos un terminal.

La idea es simple: concatenamos el archivo zip a continuación de la imagen generando un nuevo archivo que tendrá la misma extensión que la imagen base (si la extensión de la imagen fuera distinta no se verá, por ejemplo si usamos un png de base pero de salida lo llamamos .jpg). Rápidamente lo entenderéis con un ejemplo de la operación:

cat base.png secreto.zip > resultado.png

A primera vista el archivo resultado.png es la misma imagen que base.png, si bien si miráis sus propiedades veréis que tamaño del nuevo archivo es más grande (porque lleva concatenado el archivo comprimido, lógicamente).

¿Cómo accedemos al archivo oculto? Pues simplemente renombrando el archivo resultado.png y cambiando la extensión de la imagen por la del archivo comprimido que usáramos (en este caso pasaría a ser resultado.zip). Tras este cambio si la abrís con el gestor de archivos comprimidos podréis acceder al archivo que habéis ocultado.

Tal vez ofrezca menos seguridad y optimización que el software específico para esteganografía, pero para un apuro puede ser una solución válida.

Hasta la vista, señor Winter

Seguimos con las noticias y las tristes efemérides. Si ayer recordábamos el genio de Jon Lord, la clase del señor Purple, hoy nos toca decirle adiós a una de las leyendas de la guitarra bluesera. Hoy nos deja el gran Johnny Winter a la edad de 70 años. Hace unos años pude disfrutar de su música en un concierto en Pontevedra y ya se veía que su estado de salud era bastante precario. A pesar de eso se mantenía activo y girando constantemente, este mismo año se había pateado media Europa y tenía un disco en el horno. Pero esta mañana en Zurich decía adiós, sucumbiendo ante las dolencias que llevaba años combatiendo. Despidámonos con un recuerdo de su música.