Esta vez vamos a ver un tema mas que medular a la hora de hacer un sistema o web y es donde vamos a almacenar los datos necesarios para el funcionamiento de nuestra pagina (estadísticas, registros, visitas, etc).
¿por que es medular? pues mucha gente no le da la importancia necesaria al diseño de la base de datos (que debería ser producto de un buen análisis de sistemas) o desconocen o no entienden correctamente la normalización y la integridad de los datos, los cuales si no son bien pensados a la hora de querer obtener datos y reportes, se vuelve en un verdadero caos y reto sacar la data de forma lógica.
Pues bien, para poder expresarme mejor y no nos sintamos tan aburridos como en las primeras partes de esta serie de “tips” comenzaremos a ponernos manos a la obra, se me ocurre hacer un proyecto lo mas completo posible para que podamos ver todas las funcionalidades, ventajas y mas bla bla bla que digo en un proyecto mas o menos real, ya que por ahí se encuentran solo porciones o pedazos que al final nos da mas dolor de cabeza intentando entenderlo que lo que las funcionalidades que tiene cuando ya lo logramos entender y hacer funcionar. Para no acongojarnos desde el inicio, empezaremos por lo mas básico de nuestro sitio que es el registro y login (ingreso) de usuarios, y para adelantarles, el sitio que haremos funcionará en varios países manteniendo usuarios individuales por país asi que manos a la obra.
Lo mas importante en todo lo que hacemos en la vida son los estándares (insisto) así que deben considerar y meterse en la cabeza que “debo hacer las cosas lo mas estándar posible” con esto me refiero a que la forma en que nombraremos nuestra base de datos, los usuarios de la base de datos, las tablas, etc mantenga un cierto orden lógico y estándar ¿por que? pues como siempre, porque lo digo yo :D, de esta manera cualquiera que vea nuestro diseño a parte de que le de envidia, lograremos que sea fácil de recordar los nombres de campos, tablas, etc asi que para nuestro caso adoptaremos como norma lo siguiente:
- A las bases de datos les pondremos el prefijo “bd_” (sin las comillas por favor). Ej: bd_mibase
- Los usuarios de la base de datos tendrán el prefijo “usr_”. Ej: usr_haroldcrow
- Las tablas principales se nombraran utilizando la palabra plural de la data que contienen y siempre en minúsculas. Ej: paises, usuarios, visitas
- Las tablas secundarias (tipos, estados, etc) se nombraran utilizando el prefijo “tipos_de/estados_de” seguido de la tabla principal en singular. Ej: estados_de_pais, tipos_de_visita, tipos_de_usuario, estados_de_usuario, etc.
- Para el caso de los procedimientos almacenados y funciones de base de datos establecer un estándar es un poco complicado, pero haremos lo siguiente, el prefijo será “sp/fu” (respectivamente) y luego debemos hacer 4 procedimientos para realizar las 4 funciones básicas de una base de datos SQL (Insert, Delete, Select, Update) los cuales nos ayudaran en la parte administrativa en todos los casos y solo algunos utilizaremos en el front-end pero es recomendable tener los 4 básicos siempre a la mano; entonces luego del prefijo continuaremos con la letra “I/D/S/U/*sall” segun corresponda y el nombre de la tabla. Ej: sp_ipaises, sp_dpaises, fu_upaises, etc. *sall: usaremos S cuando nos devuelva un registro en especifico y sall cuando nos devuelva varias filas.
Nota: el estándar que utilicen para sus tablas, bases de datos, funciones y SP, queda muy a su criterio y lógica, pero si no tienes uno o el que tienes no te satisface, te recomiendo que utilices este que te propongo pues yo ya tengo mas de 10 años con él y le ha sido útil a muchas personas.
Lo primero que haremos es crear las primeras tablas en nuestra base de datos con el heidi o comandos, las cuales serán:
- Paises: Contendrá la información básica de los paises donde operará la pagina y su configuracion.
- Usuarios: contendrá el listado de usuarios registrados en el sitio por pais.
- estados_de_usuario: contiene la lista de los diferentes estados que pueda tener un usuario (activo, inactivo, bloqueado, etc)
- tipos_de_usuario: esta tabla contiene los tipos de usuario que podemos tener por ejemplo si quisieramos diferenciar acciones que puedan realizar los usuarios dependiendo de esta clasificacion.
Código SQL para la base de datos y tablas:
Base de datos
CREATE DATABASE IF NOT EXISTS `db_shopping` /*!40100 DEFAULT CHARACTER SET utf8 */;
Tablas
CREATE TABLE `paises` (
`pais_id` INT(11) NOT NULL AUTO_INCREMENT,
`pais_nombre` VARCHAR(50) NULL DEFAULT NULL,
`pais_codigo` CHAR(2) NULL DEFAULT NULL,
`pais_simbolo_moneda` CHAR(10) NULL DEFAULT NULL,
`pais_moneda_nombre` CHAR(20) NULL DEFAULT NULL,
`pais_moneda_nombre_plural` CHAR(20) NULL DEFAULT NULL,
`pais_moneda_iso` CHAR(3) NULL DEFAULT NULL,
`pais_estado` ENUM('Testing','Produccion') NULL DEFAULT NULL,
`pais_activo` ENUM('Activo','Inactivo') NULL DEFAULT NULL,
`pais_url_testing` VARCHAR(100) NULL DEFAULT NULL,
`pais_url_produccion` VARCHAR(100) NULL DEFAULT NULL,
`pais_timezone` CHAR(50) NULL DEFAULT NULL,
`pais_email_contacto` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`pais_id`),
UNIQUE INDEX `codigo` (`codigo`),
UNIQUE INDEX `codigo_2` (`codigo`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
CREATE TABLE IF NOT EXISTS `estados_de_usuario` (
`usuario_estado_id` int(11) NOT NULL AUTO_INCREMENT,
`usuario_estado_nombre` varchar(50) DEFAULT NULL,
PRIMARY KEY (`usuario_estado_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
INSERT INTO `estados_de_usuario` (`usuario_estado_id`, `usuario_estado_nombre`) VALUES
(1, 'Creado'),
(2, 'Activado'),
(3, 'Bloqueado');
CREATE TABLE IF NOT EXISTS `tipos_de_usuario` (
`tipo_de_usuario_id` int(11) NOT NULL AUTO_INCREMENT,
`tipo_de_usuario_nombre` varchar(50) DEFAULT NULL,
PRIMARY KEY (`tipo_de_usuario_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `tipos_de_usuario` (`tipo_de_usuario_id`, `tipo_de_usuario_nombre`) VALUES
(1, 'Normal'),
(2,'Preferencial');
CREATE TABLE IF NOT EXISTS `usuarios` (
`pais_codigo` char(2) DEFAULT NULL,
`usuario_id` int(11) NOT NULL AUTO_INCREMENT,
`usuario_nombres` varchar(50) DEFAULT NULL,
`usuario_apellidos` varchar(50) DEFAULT NULL,
`usuario_email` varchar(100) DEFAULT NULL,
`usuario_clave` char(32) DEFAULT NULL,
`usuario_fecha_nacimiento` date DEFAULT NULL,
`usuario_telefono_casa` varchar(20) DEFAULT NULL,
`usuario_telefono_celular` varchar(20) DEFAULT NULL,
`usuario_sexo` enum('Femenino','Masculino') DEFAULT NULL,
`usuario_fecha_registro` datetime DEFAULT NULL,
`usuario_estado_id` int(11) DEFAULT NULL,
`usuario_fecha_activacion` datetime DEFAULT NULL,
`usuario_fecha_bloqueo` datetime DEFAULT NULL,
`usuario_codigo_activacion` varchar(100) DEFAULT NULL,
`usuario_spam` int(5) DEFAULT '0',
`usuario_facebook_id` varchar(50) DEFAULT NULL,
`tipo_de_usuario_id` int(11) DEFAULT NULL,
PRIMARY KEY (`usuario_id`),
UNIQUE KEY `cod_email` (`pais_codigo`,`usuario_email`),
KEY `codigo_3` (`pais_codigo`,`usuario_id`),
KEY `tipos_de_usuario_id` (`tipo_de_usuario_id`),
KEY `usuario_estado_id` (`usuario_estado_id`),
KEY `cod_ema_cla` (`pais_codigo`,`usuario_email`,`usuario_clave`),
CONSTRAINT `FK_usuarios_user_estados` FOREIGN KEY (`usuario_estado_id`) REFERENCES `estados_de_usuario` (`usuario_estado_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Con esto ya tenemos listas la base de datos y las primeras tablas a utilizar. Si quieres descargar el script para las tablas puedes hacerlo aquí.
Nota: Podrán notar un pequeño detalle, y es que si ven la tabla paises y la tabla usuarios, el campo codigo_pais se repite en la tabla usuarios, y realmente el par codigo_pais,usuario_email se volverá nuestro índice único (unique) y espero poder explicar esto bien, si hubiese en este momento una tabla adicional que jerárquicamente este arriba de usuarios (es decir se relacione con usuarios, siendo la tabla usuarios el parent) esta tabla deberá contener este par de campos también, y con este par realizaremos la relación y así sucesivamente, por favor mantener en mente esto para que cuando creemos las siguientes tablas puedan comprender un poco mejor el concepto.En la parte II crearemos los procedimientos almacenados a utilizar y probaremos su funcionamiento a nivel de código SQL.
Un saludo