GUIs para el manejo de MySQL en GNU/Linux

Base de Datos, GNU/Linux No Comments

Existen dos cosas importantes para la realización de una Base de Datos:

1) El diseño de la base de datos (base de datos relacionales).
2) La administración de la base de datos.

Muchos pensarán que para gnu/linux no existen herramientas gráficas para estos fines, pues, les comento que están equivocados (tache, como dice un maestro xD). Tengo conocimiento de dos herramientas (para el uso de MySQL, principalmente), descritas enseguida:

Power Architect.
http://www.sqlpower.ca/page/architect

Esta herramienta nos sirve para el modelado de base de datos, según su sitio web tiene compatibilidad con los siguientes manejadores:

  • PostgreSQL
  • Oracle
  • MS SQL Server
  • MySQL
  • Otras

Para instalarlo en tres pasos:

  • Descargar
  • Descomprimir: tar xvzf Architect-generic-jdbc-0.9.9.tar.gz
  • Ejecutar: java -jar architect.jar

Entre sus características nos permite:

  • Diseñar la base de datos relacional (agregar los atributos de cada campo, así como sus respectivas relaciones).
  • Nos permite conectar a nuestro gestor de base de datos y poder crear (desde la misma aplicación) la base de datos a partir del diseño de nuestra base de datos.
  • Posibilidad de ejecutar comandos SQL en nuestro gestor de base de datos.
  • Creación de script SQL a partir del diseño de nuestra base de datos.
  • Ingenieria inversa

Screenshots:

Power Architect

Power Architect

Power Architect

MySQL GUI TOOLS.
http://www.mysql.com/products/tools/

Si son usuarios de windows, posiblemente ya tengan conocimiento de estas herramientas. Están orientadas para la administración en general del gestor de base de datos de MySQL (está vez, MySQL se ha preocupado también de sus usuarios en gnu/linux ;) ). En total son 3 herramientas:

  • MySQL Administrator (administración).
  • MySQL Query Browser (consultas).
  • MySQL Workbench (modelado).

Lastima que MySQL Workbench (para el modelado de base de datos), aún se encuentra algo verde, se espera con ansias (por eso el motivo de usar Power Architect :P ).

Screenshots:

MySQL Tools

MySQL Tools

Por último, quiero decir que no son las únicas y existen muchas otros herramientas para diferentes gestores, de muy buena pinta. Si alguien tiene conocimiento de alguna otra, que lo comente por acá. Nos vemos.

Califica el tema:
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

Usando Disparadores en MySQL (básico)

Base de Datos 3 Comments

Qué es un dispador? Los disparadores (también conocido como triggers) son conjunto de instrucciones (sql claro) que se ejecutan cuando se produce una de las siguientes acciones: INSERT, DELETE o UPDATE de ahí su utilidad. Para quién quiera saber más mirar:

http://dev.mysql.com/doc/refman/5.0/es/triggers.html
http://www.mysql-hispano.org/page.php?id=36&pag=1

Con ellos podemos ahorrar algunas líneas de programación si estamos usando MySQL y dejar el trabajo al propio manejador de Base de Datos. Veamos un ejemplo rápido y ustedes decidan si son útiles o no.

Para empezar necesitamos usar tablas tipo InnoDB, para saber si tenemos esa posibilidad podemos teclear desde la consola de MySQL:

mysql> SHOW VARIABLES LIKE '%innodb%';
+---------------------------------+---------------------------------+
| Variable_name                   | Value                           |
+---------------------------------+---------------------------------+
| have_innodb                     | YES                             |
| innodb_additional_mem_pool_size | 2097152                         |
| innodb_autoextend_increment     | 8                               |
| innodb_buffer_pool_awe_mem_mb   | 0                               |
| innodb_buffer_pool_size         | 16777216                        |
| innodb_checksums                | ON                              |
| innodb_commit_concurrency       | 0                               |
| innodb_concurrency_tickets      | 500                             |
| innodb_data_file_path           | ibdata1:10M:autoextend:max:128M |
| innodb_data_home_dir            |                                 |
| innodb_doublewrite              | ON                              |
| innodb_fast_shutdown            | 1                               |
| innodb_file_io_threads          | 4                               |
| innodb_file_per_table           | OFF                             |
| innodb_flush_log_at_trx_commit  | 1                               |
| innodb_flush_method             |                                 |
| innodb_force_recovery           | 0                               |
| innodb_lock_wait_timeout        | 50                              |
| innodb_locks_unsafe_for_binlog  | OFF                             |
| innodb_log_arch_dir             |                                 |
| innodb_log_archive              | OFF                             |
| innodb_log_buffer_size          | 8388608                         |
| innodb_log_file_size            | 5242880                         |
| innodb_log_files_in_group       | 2                               |
| innodb_log_group_home_dir       | ./                              |
| innodb_max_dirty_pages_pct      | 90                              |
| innodb_max_purge_lag            | 0                               |
| innodb_mirrored_log_groups      | 1                               |
| innodb_open_files               | 300                             |
| innodb_rollback_on_timeout      | OFF                             |
| innodb_support_xa               | ON                              |
| innodb_sync_spin_loops          | 20                              |
| innodb_table_locks              | ON                              |
| innodb_thread_concurrency       | 8                               |
| innodb_thread_sleep_delay       | 10000                           |
+---------------------------------+---------------------------------+
35 rows in set (0.00 sec)

Por defecto creo desde MySQL 5.0 las tablas se crean de tipo InnoDB.

El escenario es el siguiente: Diseñamos una base de datos para poder controlar la facturación de una tienda, entonces realizamos la base de datos de la siguiente forma:

create database  FACTURA;

USE FACTURA;

Create table VENTA (

	Folio Char(30) NOT NULL UNIQUE,

	Fecha Datetime NOT NULL,

Primary Key  (Folio)

); 

Create table PRODUCTO (

	Codigo Integer NOT NULL UNIQUE,

	Descripccion Char(30) NOT NULL,

	Precio Float NOT NULL,

	Existencia Integer Default 0 NOT NULL,

Primary Key  (Codigo)

);

Create table DETALLE_DE_VENTA (

	Folio Char(30) NOT NULL,

	Codigo Integer NOT NULL,

	Cantidad Integer NOT NULL,

	Precio Float NOT NULL,

Primary Key  (Folio,Codigo)

);

Alter table DETALLE_DE_VENTA add  foreign key(Folio) references VENTA (Folio);

Alter table DETALLE_DE_VENTA add  foreign key(Codigo) references PRODUCTO (Codigo);

Creación de la base de datos:
[code]
UnderHouse sql # mysql -p < db.sql
[/code]

Ingresamos algunos datos ficticios para el ejercicio:

insert into PRODUCTO (Codigo, Descripccion,Precio) values (01,'MEMORIA RAM',500);

insert into PRODUCTO (Codigo, Descripccion,Precio) values (02,'MEMORIA USB',500);

insert into PRODUCTO (Codigo, Descripccion,Precio) values (03,'GABINETE',80);

insert into PRODUCTO (Codigo, Descripccion,Precio) values (04,'TARJETA DE VIDEO',1000);

insert into VENTA VALUES('200716100001','2007-10-16');

insert into VENTA VALUES('200716100002','2007-10-16');

insert into VENTA VALUES('200716100003','2007-10-16');

update PRODUCTO set existencia='10' where codigo=01;

update PRODUCTO set existencia='20' where codigo=02;

update PRODUCTO set existencia='5' where codigo=03;

Lógicamente analizando detenidamente la base de datos podemos crear un trigger cuando se presenta la siguiente situación:

Cuando una venta se lleva a cabo es necesario restar la cantidad de producto que se vendió a la existencia que tenemos del mismo, en caso de no haber existencia suficiente del producto, no permitir que el registro de la nueva venta se lleve a cabo.

El trigger correspondiente que soluciona la situación anterior es:

USE FACTURA;

DELIMITER |

create trigger disminuir_existencia BEFORE INSERT ON DETALLE_DE_VENTA 

FOR EACH ROW

BEGIN

	DECLARE Existencia_Producto Integer;

	select PRODUCTO.Existencia into Existencia_Producto from PRODUCTO where PRODUCTO.Codigo = NEW.Codigo;

	IF Existencia_Producto >= NEW.Cantidad THEN

		update PRODUCTO set Existencia=Existencia-NEW.Cantidad where PRODUCTO.Codigo = NEW.Codigo;

	ELSE

		set NEW.Folio = NULL ;

	END IF; 

END|

DELIMITER ;

Pueden copiarlo a un archivo *.sql y pasarlo de la siguiente forma:
[code]
UnderHouse sql # mysql -p < disparador.sql
[/code]

Lo que hace es:

1) Extrae la existencia del producto que se trata de vender y se le asigna a la variable Existencia_Producto.

2) Verifica si la cantidad que se quiere vender es menor o igual a la existencia disponile (IF).

3) Si la venta es posible, se actualiza el valor de la existencia del producto que se quiere vender y el registro se lleva a cabo correctamente.

4) Si la venta no es posible, se crea un error a propósito para impedir que el registro se lleve a cabo correctamente (nota: en sqlserver es posible usar ROLLBACK pero con mysql no encontré otra forma de detener el insert, si alguien lo sabe y desea compartirlo ps con un comentario basta).

Cuestiones a tomar en cuenta para crear un trigger:

También hay limitaciones sobre lo que puede aparecer dentro de la sentencia que el disparador ejecutará al activarse:

*

El disparador no puede referirse a tablas directamente por su nombre, incluyendo la misma tabla a la que está asociado. Sin embargo, se pueden emplear las palabras clave OLD y NEW. OLD se refiere a un registro existente que va a borrarse o que va a actualizarse antes de que esto ocurra. NEW se refiere a un registro nuevo que se insertará o a un registro modificado luego de que ocurre la modificación.
*

El disparador no puede invocar procedimientos almacenados utilizando la sentencia CALL. (Esto significa, por ejemplo, que no se puede utilizar un procedimiento almacenado para eludir la prohibición de referirse a tablas por su nombre).
*

El disparador no puede utilizar sentencias que inicien o finalicen una transacción, tal como START TRANSACTION, COMMIT, o ROLLBACK.

Veamos si funcionan realmente:


/* 

Valores iniciales

*/

mysql> select * from DETALLE_DE_VENTA;
+--------------+--------+----------+--------+
| Folio        | Codigo | Cantidad | Precio |
+--------------+--------+----------+--------+
| 200716100001 |      1 |        5 |    600 |
| 200716100001 |      2 |       10 |    600 |
| 200716100001 |      3 |        1 |    600 |
+--------------+--------+----------+--------+
3 rows in set (0.00 sec)

mysql> select * from PRODUCTO;
+--------+------------------+--------+------------+
| Codigo | Descripccion     | Precio | Existencia |
+--------+------------------+--------+------------+
|      1 | MEMORIA RAM      |    500 |          1 |
|      2 | MEMORIA USB      |    500 |          5 |
|      3 | GABINETE         |     80 |          4 |
|      4 | TARJETA DE VIDEO |   1000 |          0 |
+--------+------------------+--------+------------+

/* 

Damos de alta una nueva venta
Código Producto: 2 (Memoria USB)
Cantidad:1

*/

mysql> insert into DETALLE_DE_VENTA values ('200716100002',2,1,600);
Query OK, 1 row affected (0.00 sec)

/*

Miramos si hay modificaciones en MEMORIA USB
que anteriormente tenía existencia de 5 y si se
ingreso correctamente el registro.

*/

mysql> select * from DETALLE_DE_VENTA;
+--------------+--------+----------+--------+
| Folio        | Codigo | Cantidad | Precio |
+--------------+--------+----------+--------+
| 200716100001 |      1 |        5 |    600 |
| 200716100001 |      2 |       10 |    600 |
| 200716100002 |      2 |        1 |    600 |
| 200716100001 |      3 |        1 |    600 |
+--------------+--------+----------+--------+
4 rows in set (0.00 sec)

mysql> select * from PRODUCTO;
+--------+------------------+--------+------------+
| Codigo | Descripccion     | Precio | Existencia |
+--------+------------------+--------+------------+
|      1 | MEMORIA RAM      |    500 |          1 |
|      2 | MEMORIA USB      |    500 |          4 |
|      3 | GABINETE         |     80 |          4 |
|      4 | TARJETA DE VIDEO |   1000 |          0 |
+--------+------------------+--------+------------+
4 rows in set (0.00 sec)

/* 

Tratamos de ingresar una venta que exceda la existencia del producto

*/

mysql> insert into DETALLE_DE_VENTA values ('200716100002',3,5,600);
ERROR 1048 (23000): Column 'Folio' cannot be null

/* 

Otro más
Código: 3 (GABINETE)
Cantidad: 4

*/

mysql> insert into DETALLE_DE_VENTA values ('200716100002',3,4,600);
Query OK, 1 row affected (0.00 sec)

mysql> select * from DETALLE_DE_VENTA;
+--------------+--------+----------+--------+
| Folio        | Codigo | Cantidad | Precio |
+--------------+--------+----------+--------+
| 200716100001 |      1 |        5 |    600 |
| 200716100001 |      2 |       10 |    600 |
| 200716100002 |      2 |        1 |    600 |
| 200716100001 |      3 |        1 |    600 |
| 200716100002 |      3 |        4 |    600 |
+--------------+--------+----------+--------+
5 rows in set (0.00 sec)

mysql> select * from PRODUCTO;
+--------+------------------+--------+------------+
| Codigo | Descripccion     | Precio | Existencia |
+--------+------------------+--------+------------+
|      1 | MEMORIA RAM      |    500 |          1 |
|      2 | MEMORIA USB      |    500 |          4 |
|      3 | GABINETE         |     80 |          0 |
|      4 | TARJETA DE VIDEO |   1000 |          0 |
+--------+------------------+--------+------------+
4 rows in set (0.00 sec)

Eso es todo :P , como ejercicio pueden agregar que si la venta no se ingresa correctamente en la tabla DETALLE_DE_VENTA proceda a eliminar el registro de dicha venta en la tabla VENTA.

PD. Sobre tablas relaciones, mirar: http://soullost.org/base-de-datos/base-de-datos-con-mysql/

Califica el tema:
1 Star2 Stars3 Stars4 Stars5 Stars (3 votes, average: 4.33 out of 5)
Loading ... Loading ...

Migración a wordpress = Done!

Base de Datos, Blog, Programación 8 Comments

Ps ya, parece que después de pelear con las codificaciones de las tablas con mysql ha podido quedar como debería de ser :D ( de hecho la solución fue más simple que todas las que había intentado anteriormente ;) ).

Para aquellos como Th3r0rn que quieren migrar de gekko a wordpress les muestro el pequeño script que hice a partir del migrador de SERGIO MILARDOVICH..

Código:

$gekkodb = "";
$wpdb = "";
$gekkoprefix = "gekkocms_";
$wpprefix = "wp_";

$host = "localhost";
$user = "root";
$pass = "";

$link = mysql_connect(
$host,
$user,
$pass
);

$wppoststable = $wpprefix.'posts';
$gekkoblogtable = $gekkoprefix.'blog';

mysql_select_db($gekkodb);
$res = mysql_query("SELECT * FROM $gekkoblogtable ");
WHILE ($row = mysql_fetch_array($res)){
  $title = $row['title'];
  $content = str_replace("'","'",$row['content']);
  $date = $row['date_created'];
  $id = $row['id'] + 2;
  $title_nice = strtolower($title);

  echo 'migrando la noticia " ', $row['title'], '"...', '';
  mysql_select_db($wpdb);

  mysql_query("INSERT INTO `$wppoststable` ( `ID` , `post_author` , `post_date` , `post_date_gmt` , `post_content` , `post_title` , `post_category` , `post_excerpt` , `post_status` , `comment_status` , `ping_status` , `post_password` , `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_content_filtered`, `post_parent`, `guid`, `menu_order`, `post_type`, `post_mime_type`, `comment_count` )
  VALUES ( '$id', '1', '$date', '0000-00-00 00:00:00', '$content', '$title', '0', '', 'publish' , 'open', 'open', '', '$title_nice', '', '', '0000-00-00 00:00:00', '0000-00-00 00:00:00', '', '0', '', '0', 'post', '','0' );");

  if( mysql_errno() ){
    echo "Error: " , mysql_error();
    break;
  }
  else{
    $rel_id = $id -1;
    mysql_query(" INSERT INTO `wp_post2cat` ( `rel_id`, `post_id`, `category_id` ) VALUES ( '$rel_id', '$id', '1' );");
    mysql_query(" UPDATE `wp_categories` SET category_count='$rel_id' WHERE cat_ID='1'");
  }
}

?>

gekko_wp.zip

Como verán el script es muy sencillo:

Pasa de la tabla gekkocms_blog a la tabla de los posts en wordpres que es wp_posts.

Agrega las referencias entre los posts y las categorías en wp_post2cat.

Actualiza el contador de los números de posts en la categoría Uncategorized que es donde guardé todos los posts para después poder catalogarlos mejor (aunque para pasar las categorias del gekko a wp me dio weba xD)..

Notas para ejecutar el script sin modificaciones:

1) Las base de datos de los sistemas de blog (gekko y wordpress) deben estar en el mismo servidor.

2) El wordpress debe estar recien instalado. En caso contrario, habría que modificar las referencias entre ids (id real e id del núm. de post en la categoría) y el contador de la categoria Uncategorized.

Bueno :), ahora solo falta hacer un par de modificaciones al wordpress y mirar sus características, probarlo, acostumbrarme, acomodar y rectificar algunas entradas :) xD.

Califica el tema:
1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5 out of 5)
Loading ... Loading ...

Base de Datos con Mysql

Base de Datos 1 Comment

Bueno aqui les comparto unos pdfs que nos proporcion el ing. Padilla xD (profesor de la uni) para algunas unidades del curso de Fundamentos de Base de Datos :P

Contenido:
Practica_0_Uso_Basico_CASE_STUDIO.pdf
Practica_1_Descargar_MySQL.pdf
Practica_2_Instalacion_MySQL.pdf
Practica_3_Ejecutar_MySQL.pdf
Practica_4_Administrador_MySQL.pdf
Practica_5_De_ModeloER_a_MySQL.pdf
Practica_6_Llaves_Multiple_MySQL.pdf
Practica_7_Llaves_foraneas_MySQL.pdf

Se me olvidaba mencionar que como dice el maestro xD, explicado para nños de primaria XD (algo asi, no recuerdo bien xD)

Saludos!!

Califica el tema:
1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 5 out of 5)
Loading ... Loading ...