19/07/2019, 04:10 PM
(Última modificación: 22/07/2019, 12:47 AM por Kane. Edited 6 times in total.)
NIVEL: BÁSICO/MEDIO.
Bueno el fin de este post es mostrar un poco algunas cosas que hay en mysql pero que nadie sabe usar o no usa (porque no saben que existe). Es algo bastante simple y corto ya que el lenguaje SQL es casi infinito (por la cantidad de cosas y variantes que podes hacer). Cualquier duda/error avisen.
Para esta guía, vamos a necesitar algún gestor de DB sea MySQL Workbench o SQLYog.
DB (Base de Datos)
Una base de datos es un sistema de archivos y, en este caso está compuesto por:
- Tablas
- Vistas
- SP`s (Store Procedures)
- Funciones
- Triggers
- Eventos
¿Como creo una base de datos?
Código PHP:
CREATE DATABASE cs;
¿Como uso una base de datos?
Código PHP:
USE cs;
¿Porque aclaramos que DB vamos a usar?
Cuando abran algún editor sin tocar nada, hagan un select de alguna tabla de alguna db. Si no esta seteado que usaremos esa DB, nos tirará error.
¿Como muestro todas las DBs?
Código PHP:
SHOW DATABASES;
¿Como borro una DB?
Código PHP:
DROP DATABASE cs;
Tablas
¿Que es una tabla?
Habría que buscar una definición concreta de qué es y bla.. yo me la imagino como una matriz donde nosotros definimos las columnas e insertamos filas con datos correspondientes a cada columna.
¿Que tipo campos hay en una tabla?
Cada columna puede variar dependiendo de lo que necesitemos guardar. Estos son los tipos más usados (que no quiere decir que sean los mejores/únicos):
Otros tipos de campos
Tabla de ejemplo
Ahora bien, siempre hay estándares y demás para crear todo más lindo y ordenado. Yo no sé si cumplo todos pero al que le doy mucha bola es el de los nombres del campo en una tabla. Yo siempre sigo el de usar una descripción breve de la tabla antes del nombre del campo.
Ejemplo:
De esta forma cuando hagamos un JOIN u otra cosa se lee mucho más claro (en mi opinión).
Otra cosa, yo considero que una tabla está "mal hecha" si no tiene un ID que la identifique. En el ejemplo de Tabla de ejemplo su id es `usr_id`. Pero solo son consideraciones mías.
¿Es recomendable que mi PRIMARY KEY no sea un entero?
Y.. la verdad que no. Esto no implica que no se pueda hacer. Lo mejor es que sea el id de la tabla (por eso considero que si no tiene está mal hecha) ya que es mucho más fácil comparar un número que una string.
¿Como borro una tabla?
Esto eliminara la tabla 'usuarios'.
Habría que buscar una definición concreta de qué es y bla.. yo me la imagino como una matriz donde nosotros definimos las columnas e insertamos filas con datos correspondientes a cada columna.
¿Que tipo campos hay en una tabla?
Cada columna puede variar dependiendo de lo que necesitemos guardar. Estos son los tipos más usados (que no quiere decir que sean los mejores/únicos):
Código PHP:
TINYINT
SHORT
INT
DOUBLE [casi = a FLOAT]
VARCHAR(X) [x indica la cantidad de caracteres, como si fuera un array]
TEXT(X) [igual que arriba]
TIMESTAMP [se usa para guardar fechas/horas]
Otros tipos de campos
Código PHP:
UNIQUE [Nos dice que el campo es único, por ej: un usuario en un sistema de cuentas]
PRIMARY KEY [Nos dice que es la clave primaria de esa tabla (el identificador)]
FOREIGN KEY REFERENCES 'X' [Es una clave de la tabla que hace referencia a una clave primaria en otra tabla]
NOT NULL [El campo no puede estar vacío]
AUTOINCREMENT [Generalmente se usa para los IDs e indica que en cada insert su valor va a ser 1 (o X) más que el registro anterior]
DEFAULT 'Y' [Setea un valor por defecto al campo]
CURRENT TIMESTAMP [Acá el default imprime el tiempo actual]
SIGNED [Signado]
UNSIGNED [No signado]
Tabla de ejemplo
Código PHP:
CREATE TABLE `usuarios` (
`usr_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`usr_name` VARCHAR(32) UNIQUE NOT NULL,
`usr_pw` VARCHAR(32) NOT NULL,
`usr_email` VARCHAR(50) NOT NULL,
`usr_tcreated` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`usr_id`)) ENGINE=INNODB;
Ahora bien, siempre hay estándares y demás para crear todo más lindo y ordenado. Yo no sé si cumplo todos pero al que le doy mucha bola es el de los nombres del campo en una tabla. Yo siempre sigo el de usar una descripción breve de la tabla antes del nombre del campo.
Ejemplo:
Código:
Tabla => 'datos'
Los nombres de los campos en mi tabla van a empezar siempre con 'datos_'+nombre_del_campo
Ej => 'datos_nivel' o 'datos_color_hud'
Si tengo una FORGEIN KEY => 'datos_'+nombre_tabla_externa+nombre_del_campo
Ej => 'datos_usuario_id'
Otra cosa, yo considero que una tabla está "mal hecha" si no tiene un ID que la identifique. En el ejemplo de Tabla de ejemplo su id es `usr_id`. Pero solo son consideraciones mías.
¿Es recomendable que mi PRIMARY KEY no sea un entero?
Y.. la verdad que no. Esto no implica que no se pueda hacer. Lo mejor es que sea el id de la tabla (por eso considero que si no tiene está mal hecha) ya que es mucho más fácil comparar un número que una string.
¿Como borro una tabla?
Código PHP:
DROP TABLE usuarios;
Consultas
Consultas o también llamadas Queries es una búsqueda o pedidos de datos a una tabla, dentro de una base de datos.
Ejemplo de query que devuelve todos los campos ( * ) en una tabla
Ejemplo de query que devuelve el id y el email en una tabla
Bien, ahora veremos que tipo de sintaxis se aplica en las consultas.
Ejemplos de consultas simples
Para mostrar ejemplos de JOIN primero debemos crear otra tabla.
Ahora tenemos la tabla 'datos'.
Para mostrar LEFT JOIN:
Insertamos algunos datos en la tabla 'usuario' y en la de 'datos'.
Con los datos de arriba, si hacemos:
Obtenemos
Como vemos, no hay datos en la tabla 'datos' con los ids que buscamos por eso sale NULL.
Para mostrar RIGHT JOIN:
Insertamos algunos datos en la tabla 'usuario' y en la de 'datos'.
Con los datos de arriba, si hacemos:
Obtenemos
Como vemos, no hay datos en la tabla 'usuarios' con los ids que buscamos por eso sale NULL.
Para mostrar OUTTER JOIN:
Insertamos algunos datos en la tabla 'usuario' y en la de 'datos'.
Con los datos de arriba, si hacemos:
Obtenemos
Los que buscamos y no se encuentran sale NULL.
**LOS DATOS FUERON MODIFICADOS PARA MOSTRAR LOS FUNCIONAMIENTOS
- Bien ahora pasamos a otros aspectos importantes de las consultas.
Para esto debemos tener una tabla ya existente.
Ej con la tabla usuarios:
Nota: no podemos actualizar datos si no fueron insertados antes.
Ej con la tabla usuarios:
Si lo ejecutamos la nueva contraseña debería ser 'kane'.
Ej con la tabla usuarios:
Si lo ejecutamos debería borrar el registro con usuario igual a 'kane'. Obviamente acá en vez de '=' podemos usar LIKE y borrar más.
TIP: Para borrar todos los registros de una tabla (sin borrar la tabla)
¿Como muestro todas las tablas en una DB?
Hay muchísimas variantes y todo, pero este post sería eterno si las escribo.
SELECT
Ejemplo de query que devuelve todos los campos ( * ) en una tabla
Código PHP:
SELECT * FROM usuarios;
Ejemplo de query que devuelve el id y el email en una tabla
Código PHP:
SELECT usr_id, usr_email FROM usuarios;
Bien, ahora veremos que tipo de sintaxis se aplica en las consultas.
Código PHP:
FROM 'T' [Especificamos que usamos los datos de la tabla 'T']
WHERE [Un condicional. EJ: "WHERE usr_id=9;"]
ORDER BY 'Y' [Ordena la busqueda en referencia a la tabla Y]
LIMIT X [pone un limite de int:X datos]
TOP X [igual a limit]
RAND() [seleciona de forma alazar (generalmente se usa con LIMIT/TOP)]
(INNER) JOIN [El inner es opcional. Une dos tablas buscando relacion en sus claves (PRIMARY y FORGEIN)]
LEFT JOIN [Elige todos los datos de la tabla izquierda, tengan o no datos en la de la derecha]
RIGHT JOIN [Elige todos los datos de la tabla derecha, tengan o no datos en la de la izquierda]
OUTTER JOIN [Es lo mismo a hacer un LEFT JOIN+RIGHT JOIN juntos, trae todos los datos]
AND [Saben lo que es..]
OR [Saben lo que es..]
LIKE 'X' [Compara 'X' con lo que hay en los campos de la db]
IN (Rango) [Si esta dentro de un rango]
NOW() [Devuelve el TIMESTAMP actual en formato de fecha-hora]
BINARY [Se usa para eliminar el case-sentitive]
LAST_INSERT_ID() [Devuelve el último id insertado]
Ejemplos de consultas simples
Código PHP:
// WHERE
SELECT * FROM usuarios WHERE usr_id = 2;
// Usando el LIKE
// El '%' indica de que lado queremos que conicida la string.
// Si lo pongo adelante: '%kane' acepta cadenas como 'aaakane' 'basdkane'
// Si lo pongo atrás: 'kane%' acepta cadenas como 'kaneee' 'kane2' 'kaneasd'
// Si lo pongo en ambos: '%kane%' acepta cadenas como 'aaakaneaaa' 'basdkaned21'
SELECT * FROM usuarios WHERE usr_name LIKE '%kane%';
// AND ..
SELECT * FROM usuarios WHERE usr_id = 2 AND usr_email="[email protected]";
// OR ..
SELECT * FROM usuarios WHERE usr_id = 2 OR usr_email="[email protected]";
// ORDER BY + LIMIT
SELECT * FROM usuarios ORDER BY usr_name;
SELECT * FROM usuarios ORDER BY usr_name LIMIT 5; // Un máximo de 5
Para mostrar ejemplos de JOIN primero debemos crear otra tabla.
Código:
CREATE TABLE `data` (
`data_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`data_usr_id` INT UNSIGNED UNIQUE NOT NULL,
`data_ammopacks` INT UNSIGNED NOT NULL,
`data_level` INT UNSIGNED NOT NULL,
`data_reset` INT UNSIGNED NOT NULL,
PRIMARY KEY (`data_id`)) ENGINE=INNODB;
Para mostrar LEFT JOIN:
Insertamos algunos datos en la tabla 'usuario' y en la de 'datos'.
Código PHP:
INSERT INTO usuarios (usr_name, usr_pw, usr_email) VALUES ("kane", "Pw", "[email protected]");
INSERT INTO usuarios (usr_name, usr_pw, usr_email) VALUES ("cristiano ronaldo", "Pw2", "[email protected]");
INSERT INTO usuarios (usr_name, usr_pw, usr_email) VALUES ("tom cruise", "Pw3", "[email protected]");
INSERT INTO usuarios (usr_name, usr_pw, usr_email) VALUES ("roger federer", "Pw4", "[email protected]");
INSERT INTO DATA (data_usr_id, data_ammopacks, data_level, data_reset) VALUES (1, 5, 1, 0);
INSERT INTO DATA (data_usr_id, data_ammopacks, data_level, data_reset) VALUES (2, 5, 1, 0);
Con los datos de arriba, si hacemos:
Código PHP:
SELECT * FROM usuarios LEFT JOIN `data` ON usr_id = data_usr_id;
Obtenemos
Como vemos, no hay datos en la tabla 'datos' con los ids que buscamos por eso sale NULL.
Para mostrar RIGHT JOIN:
Insertamos algunos datos en la tabla 'usuario' y en la de 'datos'.
Código PHP:
INSERT INTO usuarios (usr_name, usr_pw, usr_email) VALUES ("kane", "Pw", "[email protected]");
INSERT INTO usuarios (usr_name, usr_pw, usr_email) VALUES ("cristiano ronaldo", "Pw2", "[email protected]");
INSERT INTO DATA (data_usr_id, data_ammopacks, data_level, data_reset) VALUES (1, 5, 1, 0);
INSERT INTO DATA (data_usr_id, data_ammopacks, data_level, data_reset) VALUES (2, 5, 1, 0);
INSERT INTO DATA (data_usr_id, data_ammopacks, data_level, data_reset) VALUES (3, 5, 1, 0);
INSERT INTO DATA (data_usr_id, data_ammopacks, data_level, data_reset) VALUES (4, 5, 1, 0);
Con los datos de arriba, si hacemos:
Código PHP:
SELECT * FROM usuarios RIGHT JOIN `data` ON usr_id = data_usr_id;
Obtenemos
Como vemos, no hay datos en la tabla 'usuarios' con los ids que buscamos por eso sale NULL.
Para mostrar OUTTER JOIN:
Insertamos algunos datos en la tabla 'usuario' y en la de 'datos'.
Código PHP:
INSERT INTO usuarios (usr_name, usr_pw, usr_email) VALUES ("kane", "Pw", "[email protected]");
INSERT INTO usuarios (usr_name, usr_pw, usr_email) VALUES ("cristiano ronaldo", "Pw2", "[email protected]");
INSERT INTO usuarios (usr_name, usr_pw, usr_email) VALUES ("roger federer", "Pw3", "[email protected]");
INSERT INTO DATA (data_usr_id, data_ammopacks, data_level, data_reset) VALUES (1, 5, 1, 0);
INSERT INTO DATA (data_usr_id, data_ammopacks, data_level, data_reset) VALUES (2, 5, 1, 0);
INSERT INTO DATA (data_usr_id, data_ammopacks, data_level, data_reset) VALUES (4, 5, 1, 0);
INSERT INTO DATA (data_usr_id, data_ammopacks, data_level, data_reset) VALUES (5, 5, 1, 0);
Con los datos de arriba, si hacemos:
Código PHP:
SELECT * FROM usuarios LEFT JOIN `data` ON usr_id = data_usr_id
UNION
SELECT * FROM usuarios RIGHT JOIN `data` ON usr_id = data_usr_id;
Obtenemos
Los que buscamos y no se encuentran sale NULL.
**LOS DATOS FUERON MODIFICADOS PARA MOSTRAR LOS FUNCIONAMIENTOS
- Bien ahora pasamos a otros aspectos importantes de las consultas.
INSERT
Acá una breve descripción de como insertar datos en una tabla.Código:
INSERT INTO table_name ( field1, field2,...fieldN )
VALUES
( value1, value2,...valueN );
Ej con la tabla usuarios:
Código PHP:
INSERT INTO usuarios (usr_name, usr_pw, usr_email) VALUES ("kane", "Pw", "[email protected]");
UPDATE
Acá una breve descripción de como actualizar datos en una tabla.Código:
UPDATE table_name
SET column1=value, column2=value2,...
WHERE some_column=some_value
Ej con la tabla usuarios:
Código PHP:
UPDATE usuarios
SET usr_pw = "kane"
WHERE usr_name = "kane";
DELETE
Acá una breve descripción de como eliminar datos de una tabla.Código:
DELETE FROM table_name
WHERE some_column = some_value
Ej con la tabla usuarios:
Código PHP:
DELETE FROM usuarios
WHERE usr_name = "kane";
TIP: Para borrar todos los registros de una tabla (sin borrar la tabla)
Código PHP:
DELETE FROM usuarios
WHERE 1=1;
¿Como muestro todas las tablas en una DB?
Código PHP:
USE nombre_db;
SHOW TABLES;
Hay muchísimas variantes y todo, pero este post sería eterno si las escribo.
SP´s
Los SP´s o Stored Procedures son subrutinas (como si fueran funciones) que tienen un nombre, parámetros y un resultado. Son muy rápidos, porque están precompilados y almacenados con el motor de la db.
Para crear un SP
Los parámetros de un SP pueden ser de entrada (IN) o salida (OUT) y hay que especificar que tipo es el que entra/sale (INT, VARCHAR(), DOUBLE, etc).
Ejemplo:
Este ejemplo es para guardar los datos de un jugador. Tiene 4 parámetros de entrada. Entonces para guardar los datos del jugador en vez de hacer un update enorme a simple viste y crear el típico szQuery[2048], hacemos:
Como ven, los SP`s se llaman usando la función CALL y no SELECT (aunque no estoy seguro si con select funcionaría).
Repito, hay muchísimas cosas para hacer y no voy a hacerlas todas. Es para que tengan una idea de como simplificar todo.
Para crear un SP
Código:
CREATE [DEFINER = { user | CURRENT_USER }]
PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
proc_parameter: [ IN | OUT | INOUT ] param_name type
type:
Any valid MySQL data type
characteristic:
COMMENT 'string'
| LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA
| MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
routine_body:
Valid SQL routine statement
Los parámetros de un SP pueden ser de entrada (IN) o salida (OUT) y hay que especificar que tipo es el que entra/sale (INT, VARCHAR(), DOUBLE, etc).
Ejemplo:
Código PHP:
DELIMITER $$
CREATE PROCEDURE guardar_datos (IN player_id INT, IN player_ammopacks INT, IN player_level INT, IN player_reset INT)
BEGIN
UPDATE `datos` SET data_ammopacks=player_ammopacks, data_level=player_level, data_reset=player_reset
WHERE data_usr_id = player_id;
END $$
DELIMITER ;
Código PHP:
// Guardad de datos
new query[100];
formatex(query, 99, "CALL guardar_datos(%d, %d, %d, %d);", g_player_id[id], g_ammopacks[id], g_level[id], g_reset[id]);
SQL_QueryAndIgnore(tupla, query);
Repito, hay muchísimas cosas para hacer y no voy a hacerlas todas. Es para que tengan una idea de como simplificar todo.
Vistas
Una vista almacena varias consultas que devuelven un conjunto de resultados, conformándose como una tabla.
Para crear una vista:
La 'consulta' se trata de hacer un SELECT que nos devuelva los datos.
Cuando se crea una vista con 'OR REPLACE', se creará la vista si no existe una con el mismo nombre y, si existe, se reemplazará por ésta.
¿Para que sirven las vistas?
Te ahorras hacer varias consultas ya que creas una 'tabla virtual' con todos los datos.
Ejemplo de una vista
De esta forma tenemos creada la vista.
Ahora bien, si yo inserto los siguientes datos:
Y llamo a la vista:
Obtengo:
La vista siempre se mantiene actualizada, porque es simplemente un select. Hay vistas que soportan ser actualizadas, borrar registro o insertar datos. Pero lo mejor es hacerlo en las tablas correspondientes y dejar que la vista solo muestre los resultados.
¿Como borro una vista?
¿Más información de vistas?
Acá
Para crear una vista:
Código:
CREATE [OR REPLACE] VIEW nombre_vista [lista_columnas]
AS consulta
Cuando se crea una vista con 'OR REPLACE', se creará la vista si no existe una con el mismo nombre y, si existe, se reemplazará por ésta.
¿Para que sirven las vistas?
Te ahorras hacer varias consultas ya que creas una 'tabla virtual' con todos los datos.
Ejemplo de una vista
Código:
CREATE VIEW player_data AS
SELECT * FROM usuarios JOIN `data` ON usr_id = data_usr_id;
Ahora bien, si yo inserto los siguientes datos:
Código PHP:
INSERT INTO usuarios (usr_name, usr_pw, usr_email) VALUES ("kane", "Pw", "[email protected]");
INSERT INTO usuarios (usr_name, usr_pw, usr_email) VALUES ("cristiano ronaldo", "Pw2", "[email protected]");
INSERT INTO usuarios (usr_name, usr_pw, usr_email) VALUES ("roger federer", "Pw3", "[email protected]");
INSERT INTO DATA (data_usr_id, data_ammopacks, data_level, data_reset) VALUES (1, 5, 1, 0);
INSERT INTO DATA (data_usr_id, data_ammopacks, data_level, data_reset) VALUES (2, 5, 1, 0);
INSERT INTO DATA (data_usr_id, data_ammopacks, data_level, data_reset) VALUES (3, 5, 1, 0);
Y llamo a la vista:
Código PHP:
SELECT * FROM player_data;
Obtengo:
La vista siempre se mantiene actualizada, porque es simplemente un select. Hay vistas que soportan ser actualizadas, borrar registro o insertar datos. Pero lo mejor es hacerlo en las tablas correspondientes y dejar que la vista solo muestre los resultados.
¿Como borro una vista?
Código:
DROP VIEW nombre_vista;
¿Más información de vistas?
Acá
Triggers
Trigger = Gatillo
Si apretás el gatillo se dispara algo, en éste caso una o varias consultas.
La principal diferencia entre un SP y un trigger, es que el trigger se hace de forma automática.
Para crear un trigger
Supongamos que tenemos un zp con las tablas usuarios y datos (las de arriba), entre otras. Yo me creo un usuarios y obtengo el ID. Pero ese ID lo tengo que meter en varias tablas. En vez de hacerlo manualmente una por una, creamos un trigger que las meta.
Ejemplo
Bien este trigger lo que hacer es insertar en la tabla datos el id del nuevo usuarios y LOS VALORES PREDETERMINADOS QUE YO FIJO en cada campo (generalmente ponen g_level[id] = 1; en client_putinserver, bueno eso ya no se usaría porque de acá seteamos los valores predeterminados). Puse que el reset con el que arranca es 0 y los ammopacks 5.
Para probarlo, creamos un nuevo usuario
Una vez que se haya creado exitosa-mente el usuario, hacemos un join:
Y nos debería aparecer nuestro nuevo usuario con los datos predeterminados en el trigger.
Esto es lo básico de lo básico, es como gatear. Se pueden hacer muchísimas cosas más interesantes, pero por algo hay que empezar.
Nota: Fíjense que use NEW.usr_id porque el trigger se hace DESPUÉS de insertar. Si fuera antes de actualizar (por ejemplo) tendría que usar OLD.usr_id.
Nota2: Hasta donde sé, solo puede haber un trigger del mismo tipo por tabla. Es decir, no puedo tener 2 triggers que utilicen AFTER INSERT en una misma tabla; pero si uno AFTER INSERT y otro BEFORE INSERT
Si apretás el gatillo se dispara algo, en éste caso una o varias consultas.
La principal diferencia entre un SP y un trigger, es que el trigger se hace de forma automática.
Para crear un trigger
Código:
DELIMITER $$
USE `nombre_de_mi_db`$$
DROP TRIGGER IF EXISTS `nombre_trigger`$$
CREATE
TRIGGER `nombre_trigger`
{BEFORE|AFTER} {INSERT|UPDATE|DELETE} ON `nombre_tabla`
FOR EACH ROW
BEGIN
ACÁ LA CONSULTA;
END;
$$
DELIMITER ;
Supongamos que tenemos un zp con las tablas usuarios y datos (las de arriba), entre otras. Yo me creo un usuarios y obtengo el ID. Pero ese ID lo tengo que meter en varias tablas. En vez de hacerlo manualmente una por una, creamos un trigger que las meta.
Ejemplo
Código PHP:
DELIMITER $$
USE `cs`$$
DROP TRIGGER /*!50032 IF EXISTS */ `meter_ids`$$
CREATE
/*!50017 DEFINER = 'root'@'localhost' */
TRIGGER `meter_ids` AFTER INSERT ON `usuarios`
FOR EACH ROW
BEGIN
INSERT INTO `data` (data_usr_id, data_ammopacks, data_level, data_reset) VALUES (NEW.usr_id, 5, 1, 0);
END;
$$
DELIMITER ;
Para probarlo, creamos un nuevo usuario
Código PHP:
INSERT INTO usuarios (usr_name, usr_pw, usr_email) VALUES ("jessie kriel", "Pw6", "[email protected]");
Una vez que se haya creado exitosa-mente el usuario, hacemos un join:
Código PHP:
SELECT * FROM usuarios JOIN `data` ON usr_id = data_usr_id;
Y nos debería aparecer nuestro nuevo usuario con los datos predeterminados en el trigger.
Esto es lo básico de lo básico, es como gatear. Se pueden hacer muchísimas cosas más interesantes, pero por algo hay que empezar.
Nota: Fíjense que use NEW.usr_id porque el trigger se hace DESPUÉS de insertar. Si fuera antes de actualizar (por ejemplo) tendría que usar OLD.usr_id.
Nota2: Hasta donde sé, solo puede haber un trigger del mismo tipo por tabla. Es decir, no puedo tener 2 triggers que utilicen AFTER INSERT en una misma tabla; pero si uno AFTER INSERT y otro BEFORE INSERT
Manejo de Tiempo
Bueno todos saben que el uso de fechas es algo bastante jodido (va, ami me cuesta). Una de las ventajas de MySQL es la cantidad de funciones que tiene acerca de este tema. Empezamos:
Huso horario
Bueno esto es importante y cuesta un poco entenderlo/aprenderlo (es un poco confuso).
Wikipedia dice: Un huso horario es cada una de las 24 áreas en que se divide la Tierra, por un meridiano y en las que rige por convención el mismo horario.
¿Que es UNIX_TIMESTAMP?
Wikipedia dice: El Tiempo Unix es un sistema para la descripción de instantes de tiempo: se define como la cantidad de segundos transcurridos desde la medianoche UTC del 1 de enero de 1970. Todos los husos horarios se definen en relación con el denominado tiempo universal coordinado (UTC), huso horario centrado sobre el meridiano de Greenwich.
Bien de este simple párrafo de wiki sacamos una sigla MUY importante => UTC
El UTC es el standard por el que se "intenta regular" el tiempo.
En Argentina por ejemplo, el uso horario es denominado HOA (hora oficial de argentina) y es igual a: UTC-03:00
Hay muchas cosas para explicar, pero no viene al caso con el post. Es muy interesante, les sugiero que investiguen. Esto lo menciono porque, no solo en programación, sino hasta en la TV cuando queremos ver un partido de fútbol que dice:
Mañana no te pierdas "real vs bla" a las '15 hs' Ciudad de México (GMT-5) y 'X' de buenos aires (UTC-3).
Es un ejemplo para que entiendan, y sepan que és. Por más que no vuelva a hacer referencia de ésto más adelante en el post.
UNIX_TIMESTAMP en MySQL
En mysql se puede usar esta funcion con el siguiente comando:
Con esto dicho, vamos a las funciones mas usadas:
Según la página de MySQL, dejó la siguiente nota:
Bien, hay muchisimas más funciones relacionadas al tiempo pero solo mostré las que consideraba mas importantes.
Como regalo le dejo todo esto hecho para crear admins (vi varios y son horrendos, hacen todo por pawn cuando mysql te lo resuelve en dos pasos). Esto está relacionado a la tabla usuarios de arriba de todo.
1º: Crear la tabla de admins
2º: Creamos un store procedure para crear el admin
3º: Creamos una vista que devuelva solo los admins con el vencimiento NO vencido.
Listo! Ahora solo con hacer:
Nos devuelven los admins que no se han vencido aún! Magia.
(Habría que pulirlo un poco pero funciona perfecto, por lo menos con las pruebas que hice).
Huso horario
Bueno esto es importante y cuesta un poco entenderlo/aprenderlo (es un poco confuso).
Wikipedia dice: Un huso horario es cada una de las 24 áreas en que se divide la Tierra, por un meridiano y en las que rige por convención el mismo horario.
¿Que es UNIX_TIMESTAMP?
Wikipedia dice: El Tiempo Unix es un sistema para la descripción de instantes de tiempo: se define como la cantidad de segundos transcurridos desde la medianoche UTC del 1 de enero de 1970. Todos los husos horarios se definen en relación con el denominado tiempo universal coordinado (UTC), huso horario centrado sobre el meridiano de Greenwich.
Bien de este simple párrafo de wiki sacamos una sigla MUY importante => UTC
El UTC es el standard por el que se "intenta regular" el tiempo.
En Argentina por ejemplo, el uso horario es denominado HOA (hora oficial de argentina) y es igual a: UTC-03:00
Hay muchas cosas para explicar, pero no viene al caso con el post. Es muy interesante, les sugiero que investiguen. Esto lo menciono porque, no solo en programación, sino hasta en la TV cuando queremos ver un partido de fútbol que dice:
Mañana no te pierdas "real vs bla" a las '15 hs' Ciudad de México (GMT-5) y 'X' de buenos aires (UTC-3).
Es un ejemplo para que entiendan, y sepan que és. Por más que no vuelva a hacer referencia de ésto más adelante en el post.
UNIX_TIMESTAMP en MySQL
En mysql se puede usar esta funcion con el siguiente comando:
Código:
// Sin parametros
SELECT UNIX_TIMESTAMP() as segundos;
// Son las 15:12 en Argentina
// Al ejecutar esto obtendremos:
+------------+
| segundos |
+------------+
| 1563732709 |
+------------+
// Si llamamos a UNIX_TIMESTAMP() sin argumentos devuelve un timestamp Unix como un entero no signado.
// ------------------------------------------------------
// Con parametros como fecha+hora
// Sintaxis: UNIX_TIMESTAMP(date)
// donde date es =>
// cadena DATE
// cadena DATETIME
// TIMESTAMP
// Número en formato YYYY-MM-DD
SELECT UNIX_TIMESTAMP('2019-07-21 15:14:00') as segundos;
+------------+
| segundos |
+------------+
| 1563732840 |
+------------+
// Si es llamada con un argumento fecha, devuelve el valor del argumento como segundos desde '1970-01-01 00:00:00' GMT
Con esto dicho, vamos a las funciones mas usadas:
Código PHP:
ADDDATE(expr, days) [Le suma 'days' días a la fecha pasa como 'expr']
Ej: SELECT ADDDATE('2019-07-21', 30);
Devuelve: '2019-08-20'
CURDATE() [Devuelve el día actual]
Ej: SELECT CURDATE();
Devuelve: 2019-07-21
// Tiene variantes como CURRENT_DATE() que es lo mismo.
CURTIME() [Devuelve la hora actual]
Ej: SELECT CURTIME();
Devuelve: 15:33:57
// Tiene variantes como CURRENT_DATE() que es lo mismo.
NOW() [Devuelve un timestamp con la fecha+hora]
Ej: SELECT NOW();
Devuelve: '2019-07-21 15:33:57'
// Tiene variantes como CURRENT_TIMESTAMP() o LOCALTIME() que es lo mismo.
DATE(expr) [Extrae la parte de la fecha de la expr]
Ej: SELECT DATE('2019-07-21 15:33:57');
Devuelve: '2019-07-21'
DATE_ADD(date, INTERVAL expr unit) [Lo mismo que ADDDATE pero con intervalos]
Ej: SELECT DATE_ADD('2019-07-21', INTERVAL 1 DAY);
Devuelve: '2019-07-22'
Ej2: SELECT DATE_ADD('2019-07-21', INTERVAL 1 MONTH);
Devuelve: '2019-08-21'
Ej3: SELECT DATE_ADD('2019-07-21', INTERVAL 1 YEAR);
Devuelve: '2020-07-21'
DATE_SUB(date, INTERVAL expr unit) [Igual a DATE_ADD pero en vez de sumar, resta los días]
FROM_UNIXTIME(unix_timestamp[,format])
Ej: SELECT FROM_UNIXTIME(1563721200);
Devuelve: '2019-07-21 12:00:00'
Ej2: SELECT FROM_UNIXTIME(1563721200, '%Y %D %M %h:%i:%s');
Devuelve: '2019 21st July 12:00:00'
TIMEDIFF(expr1,expr2) [Devuelve la diferencia de fechas expresada como tiempo]
Ej: SELECT TIMEDIFF('2019-07-21 00:00:00', '2019-07-01 00:00:00');
Devuelve: '480:00:00' -> eso implica que hay 480 hs de diferencia entre fechas (20 días)
UNIX_TIMESTAMP([expr,..]) [Esta explicado arriba]
Según la página de MySQL, dejó la siguiente nota:
Código:
If you use UNIX_TIMESTAMP() and FROM_UNIXTIME() to convert between values in a non-UTC time zone and Unix timestamp values, the conversion is lossy because the mapping is not one-to-one in both directions.
Bien, hay muchisimas más funciones relacionadas al tiempo pero solo mostré las que consideraba mas importantes.
Como regalo le dejo todo esto hecho para crear admins (vi varios y son horrendos, hacen todo por pawn cuando mysql te lo resuelve en dos pasos). Esto está relacionado a la tabla usuarios de arriba de todo.
1º: Crear la tabla de admins
Código PHP:
CREATE TABLE `admins` (
`adm_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`adm_usr_id` INT UNSIGNED NOT NULL UNIQUE,
`adm_pw` VARCHAR(32) NOT NULL,
`adm_flags` VARCHAR(32) NOT NULL,
`adm_creado` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
`adm_finaliza` TIMESTAMP NULL,
PRIMARY KEY (`adm_id`)) ENGINE=INNODB;
2º: Creamos un store procedure para crear el admin
Código PHP:
DELIMITER $$
CREATE PROCEDURE crear_admin( IN usr_id INT, IN adm_pass VARCHAR(32), IN adm_flags VARCHAR(32), IN meses INT )
BEGIN
-- Variables
DECLARE fecha_venc DATETIME;
-- Declaramos la fecha de vencimiento
SELECT DATE_ADD( NOW(), INTERVAL meses MONTH ) INTO fecha_venc;
-- Creamos el adm
REPLACE INTO admins (adm_usr_id, adm_pw, adm_flags, adm_finaliza) VALUES (usr_id, adm_pass, adm_flags, fecha_venc);
END $$
DELIMITER ;
3º: Creamos una vista que devuelva solo los admins con el vencimiento NO vencido.
Código PHP:
CREATE VIEW get_admins AS
SELECT usr_id, usr_name, adm_finaliza FROM usuarios JOIN admins ON usr_id = adm_usr_id WHERE adm_finaliza > NOW();
Listo! Ahora solo con hacer:
Código PHP:
SELECT * from get_admins;
(Habría que pulirlo un poco pero funciona perfecto, por lo menos con las pruebas que hice).
Éstos, a su vez, son cosas que pueden usar dentro de PAWN.
No subí ejemplos concretos de PAWN porque sino limito a un solo lenguaje. Pero lo hice lo más claro que pude y con referencias al zp para que a su vez sea mas entendible.
Espero que les haya gustado.
PD: Hay muchas opiniones personales, ésto no significa que sea la mejor/única forma de hacerlo.
PD2: Si tienen dudas pregunten, en lo posible intenten probar y después preguntar...
(19/06/2014, 11:08 PM)01011001 escribió: No tiene niveles infinitos, llega hasta 2147483648 (Y despues hace un integer overflow)
(19/06/2014, 11:08 PM)[R]ak escribió: Mis conocimientos aumentaron un 500% con este post