Mostrando entradas con la etiqueta MYSQL. Mostrar todas las entradas
Mostrando entradas con la etiqueta MYSQL. Mostrar todas las entradas

martes, 10 de abril de 2012

Trabajo con Fechas PHP, MYSQL

Cuando los programadores tenemos que realizar una página web donde se trabaja con Fechas, siempre nos enfrentamos a problemas de formato, ya sea por la forma en que MySQL almacena los tipo "DATE", o la forma en que se quiere mostrar la fecha al usuario.

Casualmente hoy, me ha dado un error que he logrado solucionar, lo comento por si les pasa ya tengan la solución.

Primero, hacerles un breve resumen de la situación:

 Como todos saben MYSQL almacena lor registros de tipo DATE en formato "YYYY-MM-DD" (Año-Mes-Dia), por ejemplo, (2012-04-10): Fechas ISO 8601. 

Imaginemos que queremos realizar una consulta para extraer de la tabla "tusuario" la fecha de nacimiento de todos los usuarios de la tabla:

SELECT tusuario.fechaNacimiento FROM tusuario.

Si esta consulta la escribimos dentro de un fichero PHP:

require_once(conexionBD.php"); //para llamar al archivo que ejecuta la conexión a la BD.
$sql="SELECT tusuario.fechaNacimiento FROM tusuario";
$consulta=mysql_query($sql, $conexion) or die (mysql_error()); //crea conexión
 if(mysql_num_rows($consulta)>0){
      while($fila=mysql_fetch_array($consulta)){
             echo $fila[fechaNacimiento];
      }
}
 En pantalla se mostrará la fecha en formato "YYYY-MM-DD"; ahora bien, si el usuario final desea que le fecha se muestre en formato "DD/MM/YYYY" en muchos sitios se recomienda utilizar la siguiente función

echo (date(("d/m/Y"),strtotime( $fila[fechaNacimiento])));
VER: strtotime

Sin embargo, cuando utilicé dicha función, me devolvía la fecha "01/01/1970" para todos los casos, por tanto comencé a buscar opciones e hice lo siguiente:

 list($anno, $mes, $dia) = explode('-', $fila[fechaProximaLlamada]);
echo "$dia/$mes/$anno";
 Y de esa forma salieron las fechas con el formato adecuado.

Por el contrario, si queremos almacenar la fecha en nuestra BD y se ecnuentra en formato DD/MM/YYYY lo que tenemos que hacer para cambiarla es lo siguiente:

$fechaNacimiento=$_GET["fechaNacimiento"]; //En caso de que se reciba por GET o por POST
 $partes=explode("/", $fechaNacimiento);
 $fecha=$partes[2]."-".$partes[1]."-".$partes[0]; //para que la fecha se guarde en la BD como YYYY-MM-DD 

jueves, 5 de abril de 2012

Relaciones entre tablas PHPMyAdmin

PHPMyAdmin nos permite crear relaciones entre tablas. Para ello, abrir una tabla y seleccionar la pestaña "Estructura". En esa ventana aparecerá la opción "Vista de Relaciones".

Antes de comenzar asegúrese de estar usando el Motor de almacenamiento INNODB (que es el que soporta las relaciones), para ello la pestaña "Operaciones" les muestra en "Opciones de la tabla" el dato anteriormente mencionado.

Volviendo a la vista de relaciones, podrá seleccionar la llave foránea correspondiente, permitiendo hacer cambios en cascada al agregar o eliminar registros en nuestra base de datos asi como conservar integridad de la información almacenada en ella.

La integridad de datos es importante ya que no permite tener incoherencia en la información o falta de ella, permitiendo que todos los datos estén relacionados en nuestra Base de datos.

Por lo general, cuando se selecciona el índice destino para la relación y las acciones correspondientes de "ON DELETE" y "ON UPDATE" se selecciona la opción "CASCADE" que permite actualizar los valores. Lo que significa que si una fila en la tabla padre es eliminada, entonces se eliminarán las filas de la tabla hijo cuya clave foránea sea igual al valor de la clave referenciada en la tabla padre.

También se encuentran las opciones siguientes:

  • SET NULL: Actualiza los valores relacionados a "null". Requiere que el campo indicado en FOREIGN KEY permita valores nulos. Si está definido con flag NOT NULL daría un mensaje de error. 
  • NO ACTION: no realiza ninguna acción.
  • RESTRICT: restringe o impide que se ejecuten acciones.

Un error frecuente que suele aparecer es "#1452 - Cannot add or update a child row: a foreign key constraint fails"

La respuesta la suele tener la "integridad referencial" (Por ejemplo, Si cargas la tabla B, pero en esa tabla un campo es FK de la tabla A, hasta que la tabla A no tenga en su PK el valor correspondiente que usarás en B, no puedes cargar la tabla B).

La integridad referencial ha de establecerse siempre entre dos tablas. Una de ellas ha de comportarse como tabla principal o tabla padre y la otra sería la tabla vinculada o tabla hijo. Siendo necesario que::
  •  La tabla padre tenga un índice primario (PRIMARY KEY)
  • La tabla hijo tenga un índice (no es necesario que sea ni único ni primario) asociado a campos de tipo idéntico a los que se usen para índice de la tabla principal.

El error #1452 de MySQL ocurrirá si se intenta añadir un registro a la tabla hijo sin que exista el campo en la tabla padre. Por tanto, tenemos que añadir primero el registro en la tabla padre y luego en la tabla hijo.  
Es importante señalar que en la columna que se estableció como índice podemos insertar duplicados ya que no establecimos la condición de índice PRIMARIO ó UNICO.

Del tema "integridad referencial" hablaré más adelante.

Vista Indexada


Mejorar el rendimiento de una vista.

Si al ejecutar una vista demora en devolver los resultados, una solución podría ser hacerla indexada, para que guarde la información y no tenga que unir todas las tablas que componen la vista cada vez.

Los índices se utilizan para buscar las filas con valores de columna específica rápidamente. Sin un índice, MySQL debe comenzar con el primer registro y luego leer a través de toda la tabla para buscar las filas correspondientes, y si la tabla es muy grande este proceso se demorará más.

Si la tabla tiene un índice para las columnas que se trate, MySQL puede determinar rápidamente la posición de buscar en el medio del archivo de datos sin tener que mirar todos los datos. Por tanto, los índices aumentan la velocidad de la consulta y si no están bien configurados o no se tienen, puede traer como consecuencia el bloqueo de MYSQL, que la Web vaya lenta o incluso que el servidor se bloque o se caiga.

En caso de que la consulta SQL continúe lenta y no se pueda solucionar mediante una vista indexada, habría que pensar en hacer Triggers.

Los índices se crearían en los campos que se utilizan para unir tablas (por ejemplo, si en una tabla se usa el idUsuario para unirlo con la otra que también tiene idUsuario, se crearían dos índices, ambos con idUsuario, para que la BD pueda unir las tablas más rápidamente). Esto sólo es necesario en caso de que no sean campos de clave primaria, ya que éstos se indexan automáticamente. Creo que se ganaría bastante si en las uniones se están usando campos que no son clave primaria...

Se puede probar a crear los índices de las tablas de una vista, porque eso se haría rápido (si por ejemplo una vista une 5 tablas, sería crear 5 índices o pocos más) y es fácil de comprobar si va bien o no. Y si no funciona o no optimiza lo suficiente, pues hay que intentar lo otro.

Problemas encontrados:

  • En SQL SERVER 2005, por ejemplo, si hay tablas que se unen con OUTER JOIN no es posible tenerlo en vistas indexadas ya que las filas pueden desaparecer de forma lógica de una vista indizada basada en OUTER JOIN cuando inserte datos en una tabla de base. Esto hace que las vistas OUTER JOIN que son relativamente complejas de implementar se actualicen de forma incremental y el rendimiento de la implementación sería más lento que para las vistas basadas en (INNER) JOIN estándar.
  • Hay ocasiones que si en vez de utilizar OUTER JOIN utilizamos INNER JOIN nos devolve menos registros de los que necesitamos.
  • Otro problema es la dependencia de vistas con otras vistas. Es decir, si tengo una vista definida sobre otra vista. SQL Server no permite indizar la vista del nivel superior. En este artículo (http://www.microsoft.com/latam/technet/productos/servers/sql/2005/impprfiv.mspx) dicen que hay que expandir la definición de la vista anidada a mano en la vista del nivel superior y luego crear un índice, indizando la vista interna o no.

viernes, 23 de marzo de 2012

Migrar BD de SQL Server 2005 a MySQL

Para Migrar una BD de SQL Server 2005 a MySQL (en este caso la tendremos en el PHPMyAdmin) se necesita utilizar el Microsoft Access y seguir los siguientes pasos:
  1. Abrir el SQL Server 2005 y exportar la BD a formato que sea reconocido por el Microsoft Access, recuerde seleccionar todas las tablas que desee exportar.
  2. Crear una BD en el Microsoft Access con plantilla en Blanco (de extensión .mdb), si la BD anterior tiene Usuario de administración a las BD, le recomiendo que a esta BD en la opción "Usuarios y Permisos" le añada el mismo usuario y contraseña de la anterior. De ser posible, nombre la BD igual a la exportada.
  3. Crear también en PHPMyAdmin una BD vacía, a la cuál irán a parar los datos que se encontrarán en la BD de Access.
  4. Necesita tener instalado el "MySql Connect ODBC" que sirve para crear la conexión entre la BD que estará en Microsoft Access y la de MySQL. (Recomiendo instalarlo con la opción "Typical").

  5. Nota: "mysql-connector-odbc-5.1.5-win32.msi" (se encuentra aquí: http://www.filestube.com/04334ce69d05311a03ea,g/mysql-connector-odbc-5-1-5-win32.html)
  6. Terminada la instalación vamos al Panel de Control/Herramientas Administrativas/Origenes de Datos(ODBC).
  7. Seleccionamos la pestaña "DSN de archivo" y damos clic en agregar.
  8. En la lista que aparece, seleccionamos "MySQL ODBC 5.1 Driver" y clic en "Siguiente".
  9. Aparecerá una ventana para escribir la ruta donde queremos guardar nuestra conexión, le damos a "Examinar" y por defecto estará en una carpeta llamada "Data Source", ponemos un nombre y la guardamos en esa carpeta.
  10. Al seleccionar "Guardar" volveremos a la ventana donde pedía escribir la ruta, pero esta vez con al ruta escrita, por tanto, damos clic en "Siguiente" y llegamos a una ventana de Confirmación, donde damos clic en "Finalizar". Con esto volveremos a la ventana donde entramos para agregar la conexión, esta vez con la conexión ya creada.
  11. Seleccionamos la conexión y le damos clic en "Configurar"
  12. Registramos los datos que se nos pide:
    • Server: Es la dirección donde se encuentra su base de datos, si es un"servidor local, la direccion es "Localhost".
    • User: El usuario que nos permite el acceso a la base de datos.
    • Password: La contraseña del Usuario.
    • Database: En este lugar debemos escribir el nombre de la base de datos a la que nos vamos a conectar.
  13. Para confirmar que todo está correcto, clic en "Test".
  14. Con esto ya tenemos creada nuestra conexión, ahora vamos a usarla. Entramos a nuestra BD en Access y vamos al menú Base de Datos, abajo aparecerán las tablas de la base de datos, Clic derecho en la primera y seleccionamos Exportar/Base de Datos OBDC.
  15. Al hacer esto, nos preguntara el nombre con el que guardaremos la tabla en MySQL, escribimos el mismo nombre. En esta ventana se le da el nombre a la tabla, con este nombre se guardara en MySQL y damos clic en "Aceptar".
  16. Aparecerá una ventana donde debemos escoger que conexión usaremos, seleccionamos la conexión que creamos y clic en "Aceptar", una ventana de confirmación nos avisará que la tabla fue migrada con éxito.
  17. Repetimos el proceso con todas las tablas, el contenido de éstas se traspasará automáticamente junto con ellas, no asi las relaciones o los tipos de claves.

Al terminar con nuestras tablas ya tenemos nuestra BD migrada de Access a MySQL.