diff --git a/01_Reading/00_comments.sql b/01_Reading/00_comments.sql index f3d71d0..e796fe9 100644 --- a/01_Reading/00_comments.sql +++ b/01_Reading/00_comments.sql @@ -1,3 +1,8 @@ +/* +COMENTAROS +Lección 10.1: https://youtu.be/OuJerKzV5T0?t=7512 +*/ + -- Comentario en una lína /* diff --git a/01_Reading/01_select.sql b/01_Reading/01_select.sql index a7acb80..5ce9fe1 100644 --- a/01_Reading/01_select.sql +++ b/01_Reading/01_select.sql @@ -1,6 +1,6 @@ /* SELECT -Clase 2: https://twitch.tv/videos/1949226275 +Lección 8: https://youtu.be/OuJerKzV5T0?t=5618 */ -- Obtiene todos los datos de la tabla "users" diff --git a/01_Reading/02_distinct.sql b/01_Reading/02_distinct.sql index 2f27482..51b0133 100644 --- a/01_Reading/02_distinct.sql +++ b/01_Reading/02_distinct.sql @@ -1,6 +1,6 @@ /* DISTINCT -Clase 2: https://twitch.tv/videos/1949226275 +Lección 9.1: https://youtu.be/OuJerKzV5T0?t=6089 */ -- Obtiene todos los datos distintos entre sí de la tabla "users" diff --git a/01_Reading/03_where.sql b/01_Reading/03_where.sql index 74e92c3..206b01b 100644 --- a/01_Reading/03_where.sql +++ b/01_Reading/03_where.sql @@ -1,6 +1,6 @@ /* WHERE -Clase 2: https://twitch.tv/videos/1949226275 +Lección 9.2: https://youtu.be/OuJerKzV5T0?t=6384 */ -- Filtra todos los datos de la tabla "users" con edad igual a 15 diff --git a/01_Reading/04_order_by.sql b/01_Reading/04_order_by.sql index d2bc92b..b98b996 100644 --- a/01_Reading/04_order_by.sql +++ b/01_Reading/04_order_by.sql @@ -1,6 +1,6 @@ /* ORDER BY -Clase 2: https://twitch.tv/videos/1949226275 +Lección 9.3: https://youtu.be/OuJerKzV5T0?t=6592 */ -- Ordena todos los datos de la tabla "users" por edad (ascendente por defecto) diff --git a/01_Reading/05_like.sql b/01_Reading/05_like.sql index 2bc4f73..543b1fa 100644 --- a/01_Reading/05_like.sql +++ b/01_Reading/05_like.sql @@ -1,6 +1,6 @@ /* LIKE -Clase 2: https://twitch.tv/videos/1949226275 +Lección 9.4: https://youtu.be/OuJerKzV5T0?t=6894 */ -- Obtiene todos datos de la tabla "users" que contienen un email con el texto "gmail.com" en su parte final diff --git a/01_Reading/06_and_or_not.sql b/01_Reading/06_and_or_not.sql index 27fb06e..8bf6224 100644 --- a/01_Reading/06_and_or_not.sql +++ b/01_Reading/06_and_or_not.sql @@ -1,6 +1,6 @@ /* NOT, AND, OR -Clase 2: https://twitch.tv/videos/1949226275 +Lección 9.5: https://youtu.be/OuJerKzV5T0?t=7194 */ -- Obtiene todos datos de la tabla "users" con email distinto a sara@gmail.com diff --git a/01_Reading/07_limit.sql b/01_Reading/07_limit.sql index 401beeb..4166e54 100644 --- a/01_Reading/07_limit.sql +++ b/01_Reading/07_limit.sql @@ -1,10 +1,10 @@ /* LIMIT -Clase 2: https://twitch.tv/videos/1949226275 +Lección 9.6: https://youtu.be/OuJerKzV5T0?t=7395 */ -- Obtiene las 3 primeras filas de la tabla "users" SELECT * FROM users LIMIT 3; --- Obtiene las 32 primeras filas de la tabla "users" con email distinto a sara@gmail.com o edad igual a 15 +-- Obtiene las 2 primeras filas de la tabla "users" con email distinto a sara@gmail.com o edad igual a 15 SELECT * FROM users WHERE NOT email = 'sara@gmail.com' OR age = 15 LIMIT 2; \ No newline at end of file diff --git a/01_Reading/08_null.sql b/01_Reading/08_null.sql index aeac087..9f3c98e 100644 --- a/01_Reading/08_null.sql +++ b/01_Reading/08_null.sql @@ -1,6 +1,6 @@ /* NULL -Clase 3: https://twitch.tv/videos/1953432950 +Lección 10.2: https://youtu.be/OuJerKzV5T0?t=7615 */ -- Obtiene todos datos de la tabla "users" de la tabla "users" con email nulo @@ -12,5 +12,10 @@ SELECT * FROM users WHERE email IS NOT NULL; -- Obtiene todos datos de la tabla "users" de la tabla "users" con email no nulo y edad igual a 15 SELECT * FROM users WHERE email IS NOT NULL AND age = 15; +/* +IFNULL +Lección 10.14: https://youtu.be/OuJerKzV5T0?t=10023 +*/ + -- Obtiene el nombre, apellido y edad de la tabla "users", y si la edad es nula la muestra como 0 SELECT name, surname, IFNULL(age, 0) AS age FROM users; \ No newline at end of file diff --git a/01_Reading/09_min_max.sql b/01_Reading/09_min_max.sql index 792d8d6..d05db77 100644 --- a/01_Reading/09_min_max.sql +++ b/01_Reading/09_min_max.sql @@ -1,6 +1,6 @@ /* -MIN MAX -Clase 3: https://twitch.tv/videos/1953432950 +MIN, MAX +Lección 10.3: https://youtu.be/OuJerKzV5T0?t=7834 */ -- Obtiene el valor menor del campo edad de la tabla "users" diff --git a/01_Reading/10_count.sql b/01_Reading/10_count.sql index dcaa057..7fe9791 100644 --- a/01_Reading/10_count.sql +++ b/01_Reading/10_count.sql @@ -1,6 +1,6 @@ /* COUNT -Clase 3: https://twitch.tv/videos/1953432950 +Lección 10.4: https://youtu.be/OuJerKzV5T0?t=8043 */ -- Cuenta cuantas filas contiene la tabla "users" diff --git a/01_Reading/11_sum.sql b/01_Reading/11_sum.sql index 64b82c3..e276706 100644 --- a/01_Reading/11_sum.sql +++ b/01_Reading/11_sum.sql @@ -1,6 +1,6 @@ /* SUM -Clase 3: https://twitch.tv/videos/1953432950 +Lección 10.5: https://youtu.be/OuJerKzV5T0?t=8128 */ -- Suma todos los valores del campo edad de la tabla "users" diff --git a/01_Reading/12_avg.sql b/01_Reading/12_avg.sql index 67af839..462a6ae 100644 --- a/01_Reading/12_avg.sql +++ b/01_Reading/12_avg.sql @@ -1,6 +1,6 @@ /* AVG -Clase 3: https://twitch.tv/videos/1953432950 +Lección 10.6: https://youtu.be/OuJerKzV5T0?t=8293 */ -- Obitne la media de edad de la tabla "users" diff --git a/01_Reading/13_in.sql b/01_Reading/13_in.sql index 0acb06f..de75a65 100644 --- a/01_Reading/13_in.sql +++ b/01_Reading/13_in.sql @@ -1,6 +1,6 @@ /* IN -Clase 3: https://twitch.tv/videos/1953432950 +Lección 10.7: https://youtu.be/OuJerKzV5T0?t=8335 */ -- Ordena todos los datos de la tabla "users" con nombre igual a brais y sara diff --git a/01_Reading/14_between.sql b/01_Reading/14_between.sql index 0213f4e..4c0acdf 100644 --- a/01_Reading/14_between.sql +++ b/01_Reading/14_between.sql @@ -1,6 +1,6 @@ /* BETWEEN -Clase 3: https://twitch.tv/videos/1953432950 +Lección 10.8: https://youtu.be/OuJerKzV5T0?t=8559 */ -- Ordena todos los datos de la tabla "users" con edad comprendida entre 20 y 30 diff --git a/01_Reading/15_alias.sql b/01_Reading/15_alias.sql index 7a49398..fce4288 100644 --- a/01_Reading/15_alias.sql +++ b/01_Reading/15_alias.sql @@ -1,16 +1,10 @@ /* ALIAS -Clase 3: https://twitch.tv/videos/1953432950 +Lección 10.9: https://youtu.be/OuJerKzV5T0?t=8667 */ -- Establece el alias 'Fecha de inicio en programación' a la columna init_date SELECT name, init_date AS 'Fecha de inicio en programación' FROM users WHERE name = 'Brais' -- Consulta igual que la anterior. Representa la posibilidad de usar comillas dobles para cadenas -SELECT name, init_date AS "Fecha de inicio en programación" FROM users WHERE name = "Brais" - --- Concatena en una sola columa los campos nombre y apellido -SELECT CONCAT('Nombre: ', name, ', Apellidos: ', surname) FROM users - --- Concatena en una sola columa los campos nombre y apellido y le establece el alias 'Nombre completo' -SELECT CONCAT('Nombre: ', name, ', Apellidos: ', surname) AS 'Nombre completo' FROM users \ No newline at end of file +SELECT name, init_date AS "Fecha de inicio en programación" FROM users WHERE name = "Brais" \ No newline at end of file diff --git a/01_Reading/16_concat.sql b/01_Reading/16_concat.sql new file mode 100644 index 0000000..85186a6 --- /dev/null +++ b/01_Reading/16_concat.sql @@ -0,0 +1,10 @@ +/* +CONCAT +Lección 10.10: https://youtu.be/OuJerKzV5T0?t=8826 +*/ + +-- Concatena en una sola columa los campos nombre y apellido +SELECT CONCAT('Nombre: ', name, ', Apellidos: ', surname) FROM users + +-- Concatena en una sola columa los campos nombre y apellido y le establece el alias 'Nombre completo' +SELECT CONCAT('Nombre: ', name, ', Apellidos: ', surname) AS 'Nombre completo' FROM users \ No newline at end of file diff --git a/01_Reading/16_group_by.sql b/01_Reading/17_group_by.sql similarity index 92% rename from 01_Reading/16_group_by.sql rename to 01_Reading/17_group_by.sql index b9970ba..2e9e62d 100644 --- a/01_Reading/16_group_by.sql +++ b/01_Reading/17_group_by.sql @@ -1,6 +1,6 @@ /* GROUP BY -Clase 3: https://twitch.tv/videos/1953432950 +Lección 10.11: https://youtu.be/OuJerKzV5T0?t=8960 */ -- Agrupa los resultados por edad diferente diff --git a/01_Reading/17_having.sql b/01_Reading/18_having.sql similarity index 75% rename from 01_Reading/17_having.sql rename to 01_Reading/18_having.sql index e1034e8..a569c53 100644 --- a/01_Reading/17_having.sql +++ b/01_Reading/18_having.sql @@ -1,6 +1,6 @@ /* HAVING -Clase 3: https://twitch.tv/videos/1953432950 +Lección 10.12: https://youtu.be/OuJerKzV5T0?t=9265 */ -- Cuenta cuantas filas contienen un dato no nulo en el campo edad de la tabla "users" mayor que 3 diff --git a/01_Reading/18_case.sql b/01_Reading/19_case.sql similarity index 91% rename from 01_Reading/18_case.sql rename to 01_Reading/19_case.sql index 5cbe387..983712a 100644 --- a/01_Reading/18_case.sql +++ b/01_Reading/19_case.sql @@ -1,6 +1,6 @@ /* CASE -Clase 3: https://twitch.tv/videos/1953432950 +Lección 10.13: https://youtu.be/OuJerKzV5T0?t=9486 */ -- Obtiene todos los datos de la tabla "users" y establece condiciones de visualización de cadenas de texto según el valor de la edad diff --git a/02_Writing/01_insert_into.sql b/02_Writing/01_insert.sql similarity index 88% rename from 02_Writing/01_insert_into.sql rename to 02_Writing/01_insert.sql index d788792..25610eb 100644 --- a/02_Writing/01_insert_into.sql +++ b/02_Writing/01_insert.sql @@ -1,6 +1,6 @@ /* -INSERT INTO -Clase 3: https://twitch.tv/videos/1953432950 +INSERT +Lección 11.1: https://youtu.be/OuJerKzV5T0?t=10370 */ -- Inserta un registro con identificador, nombre y apellido en la tabla "users" diff --git a/02_Writing/02_update.sql b/02_Writing/02_update.sql index 95bf42d..22ca463 100644 --- a/02_Writing/02_update.sql +++ b/02_Writing/02_update.sql @@ -1,6 +1,6 @@ /* UPDATE -Clase 3: https://twitch.tv/videos/1953432950 +Lección 11.2: https://youtu.be/OuJerKzV5T0?t=10621 */ -- Estable el valor 21 para la edad del registro de la tabla "users" con identificador igual a 11 diff --git a/02_Writing/03_delete.sql b/02_Writing/03_delete.sql index 5957739..7eaa8ec 100644 --- a/02_Writing/03_delete.sql +++ b/02_Writing/03_delete.sql @@ -1,6 +1,6 @@ /* DELETE -Clase 3: https://twitch.tv/videos/1953432950 +Lección 11.3: https://youtu.be/OuJerKzV5T0?t=10920 */ -- Elimina el registro de la tabla "users" con identificador igual a 11 diff --git a/03_Database/01_create_database.sql b/03_Database/01_create_database.sql index e6109ed..341e308 100644 --- a/03_Database/01_create_database.sql +++ b/03_Database/01_create_database.sql @@ -1,6 +1,6 @@ /* CREATE DATABASE -Clase 4: https://twitch.tv/videos/1959296112 +Lección 12.1: https://youtu.be/OuJerKzV5T0?t=11064 */ -- Crea una base de datos llamada "test" diff --git a/03_Database/02_drop_database.sql b/03_Database/02_drop_database.sql index ba47ffd..a5ffede 100644 --- a/03_Database/02_drop_database.sql +++ b/03_Database/02_drop_database.sql @@ -1,6 +1,6 @@ /* DROP DATABASE -Clase 4: https://twitch.tv/videos/1959296112 +Lección 12.2: https://youtu.be/OuJerKzV5T0?t=11180 */ -- Elimina la base de datos llamada "test" diff --git a/04_Tables/01_create_table.sql b/04_Tables/01_create_table.sql index 4b8be69..d07a6c3 100644 --- a/04_Tables/01_create_table.sql +++ b/04_Tables/01_create_table.sql @@ -1,6 +1,6 @@ /* CREATE TABLE -Clase 4: https://twitch.tv/videos/1959296112 +Lección 13.1: https://youtu.be/OuJerKzV5T0?t=11292 */ -- Crea una tabla llamada "persons" con nombre de columna (atributos) de tipo int, varchar y date @@ -16,6 +16,11 @@ CREATE TABLE persons ( CONSTRAINTS: Restricciones */ +/* +NOT NULL +Lección 13.2: https://youtu.be/OuJerKzV5T0?t=11619 +*/ + -- NOT NULL: Obliga a que el campo id posea siempre un valor no nulo CREATE TABLE persons2 ( id int NOT NULL, @@ -25,6 +30,11 @@ CREATE TABLE persons2 ( created date ); +/* +UNIQUE +Lección 13.3: https://youtu.be/OuJerKzV5T0?t=11787 +*/ + -- UNIQUE: Obliga a que el campo id posea valores diferentes CREATE TABLE persons3 ( id int NOT NULL, @@ -35,6 +45,11 @@ CREATE TABLE persons3 ( UNIQUE(id) ); +/* +PRIMARY KEY +Lección 13.4: https://youtu.be/OuJerKzV5T0?t=11911 +*/ + -- PRIMARY KEY: Establece el campo id como clave primaria para futuras relaciones con otras tablas CREATE TABLE persons4 ( id int NOT NULL, @@ -46,6 +61,11 @@ CREATE TABLE persons4 ( PRIMARY KEY(id) ); +/* +CHECK +Lección 13.5: https://youtu.be/OuJerKzV5T0?t=12121 +*/ + -- CHECK: Establece que el campo age sólo podrá contener valores mayores o iguales a 18 CREATE TABLE persons5 ( id int NOT NULL, @@ -58,6 +78,11 @@ CREATE TABLE persons5 ( CHECK(age>=18) ); +/* +DEFAULT +Lección 13.6: https://youtu.be/OuJerKzV5T0?t=12243 +*/ + -- DEFAULT: Establece un valor por defecto en el campo created correspondiente a la fecha del sistema CREATE TABLE persons6 ( id int NOT NULL, @@ -70,6 +95,11 @@ CREATE TABLE persons6 ( CHECK(age>=18) ); +/* +AUTO INCREMENT +Lección 13.7: https://youtu.be/OuJerKzV5T0?t=12362 +*/ + -- AUTO_INCREMENT: Indica que el campo id siempre se va a incrementar en 1 con cada nuevo inserto CREATE TABLE persons7 ( id int NOT NULL AUTO_INCREMENT, diff --git a/04_Tables/02_drop_table.sql b/04_Tables/02_drop_table.sql index fe8a6a8..e3ea1a4 100644 --- a/04_Tables/02_drop_table.sql +++ b/04_Tables/02_drop_table.sql @@ -1,6 +1,6 @@ /* DROP TABLE -Clase 4: https://twitch.tv/videos/1959296112 +Lección 13.8: https://youtu.be/OuJerKzV5T0?t=12412 */ -- Elimina la tabla llamada "persons8" diff --git a/04_Tables/03_alter_table.sql b/04_Tables/03_alter_table.sql index 2af02b5..56e0a12 100644 --- a/04_Tables/03_alter_table.sql +++ b/04_Tables/03_alter_table.sql @@ -1,20 +1,40 @@ /* ALTER TABLE -Clase 4: https://twitch.tv/videos/1959296112 +Lección 13.9: https://youtu.be/OuJerKzV5T0?t=12461 +*/ + +/* +ADD +Lección 13.10: https://youtu.be/OuJerKzV5T0?t=12578 */ -- ADD: Añade un nuevo atributo surname a la tabla "persons8" ALTER TABLE persons8 ADD surname varchar(150); +/* +RENAME COLUMN +Lección 13.11: https://youtu.be/OuJerKzV5T0?t=12624 +*/ + -- RENAME COLUMN: Renombra el atributo surname a description en la tabla "persons8" ALTER TABLE persons8 RENAME COLUMN surname TO description; +/* +MODIFY COLUMN +Lección 13.12: https://youtu.be/OuJerKzV5T0?t=12675 +*/ + -- MODIFY COLUMN: Modifica el tipo de dato del atributo description en la tabla "persons8" ALTER TABLE persons8 MODIFY COLUMN description varchar(250); +/* +DROP COLUMN +Lección 13.13: https://youtu.be/OuJerKzV5T0?t=12712 +*/ + -- DROP COLUMN: Elimina el atributo description en la tabla "persons8" ALTER TABLE persons8 DROP COLUMN description; \ No newline at end of file diff --git a/04_Tables/04_relationships.sql b/04_Tables/04_relationships.sql index 30540d8..b47c8ee 100644 --- a/04_Tables/04_relationships.sql +++ b/04_Tables/04_relationships.sql @@ -1,10 +1,10 @@ /* -TIPO DE RELACIONES -Clase 4: https://twitch.tv/videos/1959296112 +TIPOS DE RELACIONES */ /* Relación 1:1 (uno a uno) +Lección 15.1: https://youtu.be/OuJerKzV5T0?t=13490 Relación que indica que un registro en la tabla A se relaciona con un sólo registro en la tabla B y viceversa. */ @@ -21,6 +21,7 @@ CREATE TABLE dni( /* Relación 1:N (uno a muchos) +Lección 15.2: https://youtu.be/OuJerKzV5T0?t=13732 Relación que indica que un registro en la tabla A puede tener varios registros relacionados en la tabla B, pero un registro en la tabla B se relaciona con un sólo registro en la tabla A. */ @@ -29,6 +30,8 @@ CREATE TABLE companies( company_id int AUTO_INCREMENT PRIMARY KEY, name varchar(100) NOT NULL ); +ALTER TABLE users +ADD company_id int; -- El campo company_id de la tabla "users" es clave foránea de la clave primaria company_id de la tabla "companies" -- (Un empleado (usuario) sólo puede tener una empresa, pero una empresa puede tener muchos empleados (usuarios)) @@ -38,6 +41,7 @@ FOREIGN KEY(company_id) REFERENCES companies(company_id) /* Relación N:M (muchos a muchos) +Lección 15.3: https://youtu.be/OuJerKzV5T0?t=14313 Relación que indica que un un registro en la tabla A puede relacionarse con varios registros en la tabla B y viceversa. Requiere una tabla intermedia o de unión para establecer la relación. @@ -68,7 +72,11 @@ relacionarse con otro registro de la tabla A. /* INSERT y UPDATE para trabajar con JOIN -Clase 5: https://twitch.tv/videos/1965141039 +*/ + +/* +1:1 +Lección 16.1: https://youtu.be/OuJerKzV5T0?t=14994 */ -- "dni" (Relación 1:1) @@ -77,6 +85,11 @@ INSERT INTO dni (dni_number, user_id) VALUES (22222222, 2); INSERT INTO dni (dni_number, user_id) VALUES (33333333, 3); INSERT INTO dni (dni_number) VALUES (44444444); +/* +1:N +Lección 16.2: https://youtu.be/OuJerKzV5T0?t=15203 +*/ + -- "companies" y "users" (Relación 1:N) INSERT INTO companies (name) VALUES ('MoureDev'); INSERT INTO companies (name) VALUES ('Apple'); @@ -87,6 +100,11 @@ UPDATE users SET company_id = 2 WHERE user_id = 3; UPDATE users SET company_id = 3 WHERE user_id = 4; UPDATE users SET company_id = 1 WHERE user_id = 7; +/* +N:M +Lección 16.3: https://youtu.be/OuJerKzV5T0?t=15474 +*/ + -- "languages" y "users_languages" (Relación N:M) INSERT INTO languages (name) VALUES ('Swift'); INSERT INTO languages (name) VALUES ('Kotlin'); diff --git a/05_Join/01_inner_join.sql b/05_Join/01_inner_join.sql index b4608f0..b123e84 100644 --- a/05_Join/01_inner_join.sql +++ b/05_Join/01_inner_join.sql @@ -1,6 +1,6 @@ /* INNER JOIN (JOIN) -Clase 5: https://twitch.tv/videos/1965141039 +Lección 17.1: https://youtu.be/OuJerKzV5T0?t=16101 */ -- Realiza un JOIN de manera incorrecta, ya que no existe un campo de relación diff --git a/05_Join/02_left_join.sql b/05_Join/02_left_join.sql index c1a6ea0..d327c66 100644 --- a/05_Join/02_left_join.sql +++ b/05_Join/02_left_join.sql @@ -1,6 +1,6 @@ /* LEFT JOIN -Clase 5: https://twitch.tv/videos/1965141039 +Lección 17.2: https://youtu.be/OuJerKzV5T0?t=17045 */ -- Obtiene los datos de todos los usuarios junto a su dni (lo tenga o no) diff --git a/05_Join/03_right_join.sql b/05_Join/03_right_join.sql index 208c961..16d7368 100644 --- a/05_Join/03_right_join.sql +++ b/05_Join/03_right_join.sql @@ -1,6 +1,6 @@ /* RIGHT JOIN -Clase 5: https://twitch.tv/videos/1965141039 +Lección 17.3: https://youtu.be/OuJerKzV5T0?t=17399 */ -- Obtiene todos los dni junto a su usuario (lo tenga o no) diff --git a/05_Join/04_union.sql b/05_Join/04_union.sql index 42798e4..a4ad53e 100644 --- a/05_Join/04_union.sql +++ b/05_Join/04_union.sql @@ -1,6 +1,6 @@ /* UNION (FULL JOIN) -Clase 5: https://twitch.tv/videos/1965141039 +Lección 17.4: https://youtu.be/OuJerKzV5T0?t=17536 */ -- UNION elimina duplicados diff --git a/06_Advanced/01_index.sql b/06_Advanced/01_index.sql new file mode 100644 index 0000000..d882e17 --- /dev/null +++ b/06_Advanced/01_index.sql @@ -0,0 +1,16 @@ +/* +INDEX +Lección 18.1: https://youtu.be/OuJerKzV5T0?t=18219 +*/ + +-- Crea un índice llamado "idx_name" en la tabla "users" asociado al campo "name" +CREATE INDEX idx_name ON users(name); + +-- Crea un índice único llamado "idx_name" en la tabla "users" asociado al campo "name" +CREATE UNIQUE INDEX idx_name ON users(name); + +-- Crea un índice llamado "idx_name_surname" en la tabla "users" asociado a los campos "name" y "surname" +CREATE UNIQUE INDEX idx_name_surname ON users(name, surname); + +-- Elimina el índice llamado "idx_name" +DROP INDEX idx_name ON users; \ No newline at end of file diff --git a/06_Advanced/02_triggers.sql b/06_Advanced/02_triggers.sql new file mode 100644 index 0000000..f76f79f --- /dev/null +++ b/06_Advanced/02_triggers.sql @@ -0,0 +1,35 @@ +/* +TRIGGERS +Lección 18.2: https://youtu.be/OuJerKzV5T0?t=18961 +*/ + +-- Crea una tabla de historial para usar en el ejemplo +CREATE TABLE `hello_mysql`.`email_history` ( +`email_history_id` INT NOT NULL AUTO_INCREMENT, +`user_id` INT NOT NULL, +`email` VARCHAR(100) NULL, +PRIMARY KEY (`email_history_id`), +UNIQUE INDEX `email_history_id_UNIQUE` (`email_history_id` ASC) VISIBLE); + +-- Crea un trigger llamado "tg_email" que guarda el email previo en la tabla "email_history" siempre +-- que se actualiza el campo "email" en la tabla "users" + +-- DELIMITER es una directiva que sirve para cambiar el delimitador de instrucciones SQL, que por defecto es ; +-- Se utiliza cuando se define un bloque de código como un procedimiento donde se requieren múltiples +-- instrucciones SQL terminadas con punto y coma dentro de un mismo bloque. +DELIMITER // +CREATE TRIGGER tg_email +AFTER UPDATE ON users +FOR EACH ROW +BEGIN + IF OLD.email <> NEW.email THEN + INSERT INTO email_history (user_id, email) + VALUES (OLD.user_id, OLD.email); + END IF; +END// + +-- Actualiza el campo "email" del usuario 1 la tabla "users" para probar el trigger +UPDATE users SET email = 'mouredev@gmail.com' WHERE user_id = 1 + +-- Elimina el trigger llamado "tg_email" +DROP TRIGGER tg_email; \ No newline at end of file diff --git a/06_Advanced/03_views.sql b/06_Advanced/03_views.sql new file mode 100644 index 0000000..e4336da --- /dev/null +++ b/06_Advanced/03_views.sql @@ -0,0 +1,16 @@ +/* +VIEWS +Lección 18.3: https://youtu.be/OuJerKzV5T0?t=19663 +*/ + +-- Crea unaa vista llamada "v_adult_users" con los nombres y edades de usuarios de la table "users" +-- que tienen una edad igual o mayor a 18 años. +CREATE VIEW v_adult_users AS +SELECT name, age +FROM users +WHERE age >= 18; + +SELECT * FROM v_adult_users; + +-- Elimina la vista llamada "v_adult_users" +DROP VIEW v_adult_users; \ No newline at end of file diff --git a/06_Advanced/04_stored_procedures.sql b/06_Advanced/04_stored_procedures.sql new file mode 100644 index 0000000..f991b1a --- /dev/null +++ b/06_Advanced/04_stored_procedures.sql @@ -0,0 +1,28 @@ +/* +STORED PROCEDURES +Lección 18.4: https://youtu.be/OuJerKzV5T0?t=20033 +*/ + +-- Crea un procedimiento almacenado llamado "p_all_users" que obtiene todos los datos de "users" +DELIMITER // +CREATE PROCEDURE p_all_users() +BEGIN + SELECT * FROM users; +END// + +-- Invoca al procedimiento almacenado llamado "p_all_users" +CALL p_all_users; + +-- Crea un procedimiento almacenado llamado "p_age_users" parametrizado para +-- obtener usuarios con edad variable +DELIMITER // +CREATE PROCEDURE p_age_users(IN age_param int) +BEGIN + SELECT * FROM users WHERE age = age_param; +END// + +-- Invoca al procedimiento almacenado llamado "p_age_users" con un parámetro de valor 30 +CALL p_age_users(30); + +-- Elimina el procedimiento almacenado llamado "p_age_users" +DROP PROCEDURE p_age_users; \ No newline at end of file diff --git a/06_Advanced/05_transactions.sql b/06_Advanced/05_transactions.sql new file mode 100644 index 0000000..242a355 --- /dev/null +++ b/06_Advanced/05_transactions.sql @@ -0,0 +1,16 @@ +/* +TRANSACTIONS +Lección 18.5: https://youtu.be/OuJerKzV5T0?t=20501 +*/ + +-- Inicia una nueva transacción. Desde este punto, todas las modificaciones realizadas en la +-- base de datos son temporales y solo son visibles dentro de esta transacción +START TRANSACTION + +-- Finaliza una transacción con éxito. Cuando se ejecuta, todos los cambios realizados en la +-- base de datos durante la transacción actual se hacen permanentes y visibles +COMMIT + +-- Deshace las operaciones realizadas en una transacción, revirtiendo la base de datos +-- al estado en que se encontraba antes de iniciar la transacción +ROLLBACK \ No newline at end of file diff --git a/06_Advanced/06_connectors.py b/06_Advanced/06_connectors.py new file mode 100644 index 0000000..f65c020 --- /dev/null +++ b/06_Advanced/06_connectors.py @@ -0,0 +1,44 @@ +# CONNECTORS +# Lección 19.1: https://youtu.be/OuJerKzV5T0?t=20876 +# Lección 19.2: https://youtu.be/OuJerKzV5T0?t=21149 + +# Ejemplo de conexión desde Python a una base de datos local +# Se ejemplifica cómo evitar SQL INJECTION +import mysql.connector + + +def print_user(user): + + config = { + "host": "127.0.0.1", + "port": "3306", + "database": "hello_mysql", + "user": "root", + "password": "root1234" + } + + # config = { + # "host": "bpw0hq9h09e7mqicjhtl-mysql.services.clever-cloud.com", + # "port": "3306", + # "database": "bpw0hq9h09e7mqicjhtl", + # "user": "uqzby88erlhvkrty", + # "password": "oePXiCOHdU1WRV80NPyv" + # } + + connection = mysql.connector.connect(**config) + cursor = connection.cursor() + + query = "SELECT * FROM users WHERE name=%s;" + print(query) + cursor.execute(query, (user,)) + result = cursor.fetchall() + + for row in result: + print(row) + + cursor.close() + connection.close() + + +print_user("Brais") +# print_user("'; UPDATE users SET age = '15' WHERE user_id = 1; --") diff --git a/Images/header.jpg b/Images/header.jpg index 06e4eff..f89a99a 100644 Binary files a/Images/header.jpg and b/Images/header.jpg differ diff --git a/Images/pro.jpg b/Images/pro.jpg new file mode 100644 index 0000000..986b770 Binary files /dev/null and b/Images/pro.jpg differ diff --git a/README.md b/README.md index e9ce526..e543625 100644 --- a/README.md +++ b/README.md @@ -3,44 +3,118 @@ [![SQL](https://img.shields.io/badge/MySQL-8.0+-f29221?style=for-the-badge&logo=mysql&logoColor=white&labelColor=101010)](https://mysql.com) [![SQL](https://img.shields.io/badge/PostgreSQL-16+-699eca?style=for-the-badge&logo=postgresql&logoColor=white&labelColor=101010)](https://postgresql.org) -## Curso para aprender los fundamentos del lenguaje SQL y bases de datos relacionales +## Curso completo para aprender los fundamentos del lenguaje SQL y bases de datos relacionales ![](./Images/header.jpg) +### 7 horas | +80 lecciones | +50 comandos | con código | desde cero | completo | gratis + ### Proyecto realizado durante emisiones en directo desde [Twitch](https://twitch.tv/mouredev) > ##### Si consideras útil el curso, apóyalo haciendo "★ Star" en el repositorio. ¡Gracias! -## Próxima Clase: Muy pronto -### Avisaré en redes sociales y actualizaré este repositorio con la siguiente fecha. - -## Clases anteriores - -### Clase 1 (05/10/2023): Introducción, fundamentos e instalación MySQL -#### ▶️ [Ver clase en vídeo](https://www.twitch.tv/videos/1943373276?t=00h19m44s) - -### Clase 2 (12/10/2023): Instalación MySQL Workbench, creación BBDD, tablas y comandos SELECT -#### ▶️ [Ver clase en vídeo](https://www.twitch.tv/videos/1949226275?t=00h25m17s) - -### Clase 3 (17/10/2023): Comandos SELECT y de escritura (INSERT, UPDATE y DELETE) -#### ▶️ [Ver clase en vídeo](https://www.twitch.tv/videos/1953432950?t=00h23m40s) - -### Clase 4 (25/10/2023): Comandos DATABASE, TABLE y tipos de relación entre tablas -#### ▶️ [Ver clase en vídeo](https://www.twitch.tv/videos/1959296112?t=00h19m20s) - -### Clase 5 (31/10/2023): Comandos JOIN -#### ▶️ [Ver clase en vídeo](https://www.twitch.tv/videos/1965141039?t=00h23m19s) +## Curso completo en vídeo + + + +**Este es el curso completo en [vídeo](https://youtu.be/OuJerKzV5T0) de 7 horas en YouTube asociado al código de este repositorio.** + +## Lecciones y código + +[INTRODUCCIÓN](https://youtu.be/OuJerKzV5T0) + +1. [Bases de datos SQL](https://youtu.be/OuJerKzV5T0?t=234) +2. [Sistema de gestión de base de datos](https://youtu.be/OuJerKzV5T0?t=1011) +3. [Fundamentos de SQL y bases de datos](https://youtu.be/OuJerKzV5T0?t=1347) +4. [Configuración e instalación](https://youtu.be/OuJerKzV5T0?t=2753) +5. [Primeros pasos](https://youtu.be/OuJerKzV5T0?t=3282) +6. [Conexión y cliente SQL](https://youtu.be/OuJerKzV5T0?t=3555) +7. [Inicialización de datos](https://youtu.be/OuJerKzV5T0?t=4381) +8. [Consulta de datos: `SELECT`](https://youtu.be/OuJerKzV5T0?t=5618) ➔ [[Código]](./01_Reading/01_select.sql) +9. [Modificadores: Parte 1](https://youtu.be/OuJerKzV5T0?t=6074) + 1. [`DISTINCT`](https://youtu.be/OuJerKzV5T0?t=6089) ➔ [[Código]](./01_Reading/02_distinct.sql) + 2. [`WHERE`](https://youtu.be/OuJerKzV5T0?t=6384) ➔ [[Código]](./01_Reading/03_where.sql) + 3. [`ORDER BY`](https://youtu.be/OuJerKzV5T0?t=6592) ➔ [[Código]](./01_Reading/04_order_by.sql) + 4. [`LIKE`](https://youtu.be/OuJerKzV5T0?t=6894) ➔ [[Código]](./01_Reading/05_like.sql) + 5. [`AND, OR, NOT`](https://youtu.be/OuJerKzV5T0?t=7194) ➔ [[Código]](./01_Reading/06_and_or_not.sql) + 6. [`LIMIT`](https://youtu.be/OuJerKzV5T0?t=7395) ➔ [[Código]](./01_Reading/07_limit.sql) +10. [Modificadores: Parte 2](https://youtu.be/OuJerKzV5T0?t=7503) + 1. [`COMMENTS`](https://youtu.be/OuJerKzV5T0?t=7512) ➔ [[Código]](./01_Reading/00_comments.sql) + 2. [`NULL`](https://youtu.be/OuJerKzV5T0?t=7615) ➔ [[Código]](./01_Reading/08_null.sql) + 3. [`MIN, MAX`](https://youtu.be/OuJerKzV5T0?t=7834) ➔ [[Código]](./01_Reading/09_min_max.sql) + 4. [`COUNT`](https://youtu.be/OuJerKzV5T0?t=8043) ➔ [[Código]](./01_Reading/10_count.sql) + 5. [`SUM`](https://youtu.be/OuJerKzV5T0?t=8128) ➔ [[Código]](./01_Reading/11_sum.sql) + 6. [`AVG`](https://youtu.be/OuJerKzV5T0?t=8293) ➔ [[Código]](./01_Reading/12_avg.sql) + 7. [`IN`](https://youtu.be/OuJerKzV5T0?t=8335) ➔ [[Código]](./01_Reading/13_in.sql) + 8. [`BETWEEN`](https://youtu.be/OuJerKzV5T0?t=8559) ➔ [[Código]](./01_Reading/14_between.sql) + 9. [`ALIAS`](https://youtu.be/OuJerKzV5T0?t=8667) ➔ [[Código]](./01_Reading/15_alias.sql) + 10. [`CONCAT`](https://youtu.be/OuJerKzV5T0?t=8826) ➔ [[Código]](./01_Reading/16_concat.sql) + 11. [`GROUP BY`](https://youtu.be/OuJerKzV5T0?t=8960) ➔ [[Código]](./01_Reading/17_group_by.sql) + 12. [`HAVING`](https://youtu.be/OuJerKzV5T0?t=9265) ➔ [[Código]](./01_Reading/18_having.sql) + 13. [`CASE`](https://youtu.be/OuJerKzV5T0?t=9486) ➔ [[Código]](./01_Reading/19_case.sql) + 14. [`IFNULL`](https://youtu.be/OuJerKzV5T0?t=10023) ➔ [[Código]](./01_Reading/08_null.sql) + 15. [Otros modificadores](https://youtu.be/OuJerKzV5T0?t=10191) +11. [Escritura de datos](https://youtu.be/OuJerKzV5T0?t=10289) + 1. [`INSERT`](https://youtu.be/OuJerKzV5T0?t=10370) ➔ [[Código]](./02_Writing/01_insert.sql) + 2. [`UPDATE`](https://youtu.be/OuJerKzV5T0?t=10621) ➔ [[Código]](./02_Writing/02_update.sql) + 3. [`DELETE`](https://youtu.be/OuJerKzV5T0?t=10920) ➔ [[Código]](./02_Writing/03_delete.sql) +12. [Administración de la base de datos](https://youtu.be/OuJerKzV5T0?t=11021) + 1. [`CREATE DATABASE`](https://youtu.be/OuJerKzV5T0?t=11064) ➔ [[Código]](./03_Database/01_create_database.sql) + 2. [`DROP DATABASE`](https://youtu.be/OuJerKzV5T0?t=11180) ➔ [[Código]](./03_Database/02_drop_database.sql) +13. [Administración de tablas](https://youtu.be/OuJerKzV5T0?t=11021) + 1. [`CREATE TABLE`](https://youtu.be/OuJerKzV5T0?t=11292) ➔ [[Código]](./04_Tables/01_create_table.sql) + 2. [`NOT NULL`](https://youtu.be/OuJerKzV5T0?t=11619) ➔ [[Código]](./04_Tables/01_create_table.sql) + 3. [`UNIQUE`](https://youtu.be/OuJerKzV5T0?t=11787) ➔ [[Código]](./04_Tables/01_create_table.sql) + 4. [`PRIMARY KEY`](https://youtu.be/OuJerKzV5T0?t=11911) ➔ [[Código]](./04_Tables/01_create_table.sql) + 5. [`CHECK`](https://youtu.be/OuJerKzV5T0?t=12121) ➔ [[Código]](./04_Tables/01_create_table.sql) + 6. [`DEFAULT`](https://youtu.be/OuJerKzV5T0?t=12243) ➔ [[Código]](./04_Tables/01_create_table.sql) + 7. [`AUTO INCREMENT`](https://youtu.be/OuJerKzV5T0?t=12362) ➔ [[Código]](./04_Tables/01_create_table.sql) + 8. [`DROP TABLE`](https://youtu.be/OuJerKzV5T0?t=12412) ➔ [[Código]](./04_Tables/02_drop_table.sql) + 9. [`ALTER TABLE`](https://youtu.be/OuJerKzV5T0?t=12461) ➔ [[Código]](./04_Tables/03_alter_table.sql) + 10. [`ADD`](https://youtu.be/OuJerKzV5T0?t=12578) ➔ [[Código]](./04_Tables/03_alter_table.sql) + 11. [`RENAME COLUMN`](https://youtu.be/OuJerKzV5T0?t=12624) ➔ [[Código]](./04_Tables/03_alter_table.sql) + 12. [`MODIFY COLUMN`](https://youtu.be/OuJerKzV5T0?t=12675) ➔ [[Código]](./04_Tables/03_alter_table.sql) + 13. [`DROP COLUMN`](https://youtu.be/OuJerKzV5T0?t=12712) ➔ [[Código]](./04_Tables/03_alter_table.sql) +14. [Relaciones entre tablas](https://youtu.be/OuJerKzV5T0?t=12781) + 1. [RELACIÓN `1:1`](https://youtu.be/OuJerKzV5T0?t=12852) + 2. [RELACIÓN `1:N`](https://youtu.be/OuJerKzV5T0?t=13117) + 3. [RELACIÓN `N:M`](https://youtu.be/OuJerKzV5T0?t=13208) + 4. [AUTOREFERENCIA](https://youtu.be/OuJerKzV5T0?t=13343) +15. [Creación de tablas relacionadas](https://youtu.be/OuJerKzV5T0?t=13428) + 1. [TABLAS `1:1`](https://youtu.be/OuJerKzV5T0?t=13490) ➔ [[Código]](./04_Tables/04_relationships.sql) + 2. [TABLAS `1:N`](https://youtu.be/OuJerKzV5T0?t=13732) ➔ [[Código]](./04_Tables/04_relationships.sql) + 3. [TABLAS `N:M`](https://youtu.be/OuJerKzV5T0?t=14313) ➔ [[Código]](./04_Tables/04_relationships.sql) +16. [Almacenamiento de datos relacionados](https://youtu.be/OuJerKzV5T0?t=14635) + 1. [DATOS `1:1`](https://youtu.be/OuJerKzV5T0?t=14994) ➔ [[Código]](./04_Tables/04_relationships.sql) + 2. [DATOS `1:N`](https://youtu.be/OuJerKzV5T0?t=15203) ➔ [[Código]](./04_Tables/04_relationships.sql) + 3. [DATOS `N:M`](https://youtu.be/OuJerKzV5T0?t=15474) ➔ [[Código]](./04_Tables/04_relationships.sql) +17. [Consulta de datos relacionados](https://youtu.be/OuJerKzV5T0?t=16013) + 1. [`INNER JOIN`](https://youtu.be/OuJerKzV5T0?t=16101) ➔ [[Código]](./05_Join/01_inner_join.sql) + 2. [`LEFT JOIN`](https://youtu.be/OuJerKzV5T0?t=17045) ➔ [[Código]](./05_Join/02_left_join.sql) + 3. [`RIGHT JOIN`](https://youtu.be/OuJerKzV5T0?t=17399) ➔ [[Código]](./05_Join/03_right_join.sql) + 4. [`UNION`](https://youtu.be/OuJerKzV5T0?t=17536) ➔ [[Código]](./05_Join/04_union.sql) +18. [Conceptos avanzados](https://youtu.be/OuJerKzV5T0?t=18196) + 1. [`INDEX`](https://youtu.be/OuJerKzV5T0?t=18219) ➔ [[Código]](./06_Advanced/01_index.sql) + 2. [`TRIGGER`](https://youtu.be/OuJerKzV5T0?t=18961) ➔ [[Código]](./06_Advanced/02_triggers.sql) + 3. [`VIEW`](https://youtu.be/OuJerKzV5T0?t=19663) ➔ [[Código]](./06_Advanced/03_views.sql) + 4. [`STORED PROCEDURE`](https://youtu.be/OuJerKzV5T0?t=20033) ➔ [[Código]](./06_Advanced/04_stored_procedures.sql) + 5. [TRANSACCIONES](https://youtu.be/OuJerKzV5T0?t=20501) ➔ [[Código]](./06_Advanced/05_transactions.sql) + 6. [CONCURRENCIA](https://youtu.be/OuJerKzV5T0?t=20701) +19. [Conexión desde código](https://youtu.be/OuJerKzV5T0?t=20847) + 1. [CONECTORES](https://youtu.be/OuJerKzV5T0?t=20876) ➔ [[Código]](./06_Advanced/06_connectors.py) + 2. [SQL INJECTION](https://youtu.be/OuJerKzV5T0?t=21149) ➔ [[Código]](./06_Advanced/06_connectors.py) +20. [Otros clientes SQL](https://youtu.be/OuJerKzV5T0?t=21641) +21. [PostgresSQL](https://youtu.be/OuJerKzV5T0?t=22070) +22. [Despliegue en la nube](https://youtu.be/OuJerKzV5T0?t=23214) +23. [Próximos pasos](https://youtu.be/OuJerKzV5T0?t=24283) + +[CONCLUSIONES](https://youtu.be/OuJerKzV5T0?t=24678) Durante el curso aprenderemos los fundamentos del lenguaje SQL y las bases de datos relacionales con ejemplos prácticos. -Nos centraremos en MySQL para llevar a cabo las clases, ya que es uno de los más usados en enseñanza y a nivel profesional. También utilizaremos PostgreSQL ya que es una de las bases de datos más populares de la actualidad. De todas formas, no debe preocuparte el motor de bases de datos utilizado, ya que SQL es un lenguaje estándar, por lo que se utilizará prácticamente igual en todas ellas. Una vez lo conozcas no tendrá dificultad alguna llevar esos conocimientos a otros sistemas. -Todo el código estará disponible para que cualquiera pueda usarlo. - -## Información importante y preguntas frecuentes - -Este curso se encuentra en desarrollo. Todo el contenido se crea en directo desde [Twitch](https://www.twitch.tv/mouredev), y en este repositorio podrás encontrar las clases en vídeo, el código programado, enlaces de interés y la información de la próxima clase. +Nos centraremos en MySQL para llevar a cabo las clases, ya que es uno de los más usados en enseñanza y a nivel profesional. También utilizaremos PostgreSQL, por ser una de las bases de datos más populares de la actualidad. De todas formas, no debe preocuparte el motor de bases de datos utilizado, ya que SQL es un lenguaje estándar, por lo que se utilizará prácticamente igual en todas ellas. Una vez lo conozcas no tendrá dificultad alguna llevar esos conocimientos a otros sistemas. -Una vez se finalice, se creará un vídeo que agrupe todas las clases y se publicará en [YouTube](https://www.youtube.com/@mouredev). +Todo el código creado durante el curso está disponible para que puedas consultarlo junto a su explicación. -* Recuerda que he creado en el [Discord](https://discord.gg/mouredev) un canal "💾bases-de-datos" para que puedas comentar lo que quieras. +> En el servidor de la comunidad de [Discord](https://discord.gg/mouredev) dispones de un canal llamado "💾bases-de-datos" para que puedas comentar lo que quieras. ## Enlaces de interés @@ -49,16 +123,18 @@ Una vez se finalice, se creará un vídeo que agrupe todas las clases y se publi * [Descarga MySQL](https://dev.mysql.com/downloads/mysql/) * [CLI MySQL](https://dev.mysql.com/doc/refman/8.0/en/mysql.html) * [MySQL Workbench](https://dev.mysql.com/downloads/workbench) +* [PostgreSQL](https://www.postgresql.org) +* [Clever Cloud](https://www.clever-cloud.com) -#### Puedes apoyar mi trabajo haciendo "☆ Star" en el repo o nominarme a "GitHub Star". ¡Gracias! +## Únete al campus de programación de la comunidad -[![GitHub Star](https://img.shields.io/badge/GitHub-Nominar_a_star-yellow?style=for-the-badge&logo=github&logoColor=white&labelColor=101010)](https://stars.github.com/nominate/) +![https://mouredev.pro](./Images/pro.jpg) -Si quieres unirte a nuestra comunidad de desarrollo, aprender programación de Apps, mejorar tus habilidades y ayudar a la continuidad del proyecto, puedes encontrarnos en: +#### Te presento [mouredev pro](https://mouredev.pro), mi proyecto más importante para ayudarte a estudiar programación y desarrollo de software de manera diferente. -[![Twitch](https://img.shields.io/badge/Twitch-Programación_en_directo-9146FF?style=for-the-badge&logo=twitch&logoColor=white&labelColor=101010)](https://twitch.tv/mouredev) -[![Discord](https://img.shields.io/badge/Discord-Servidor_de_la_comunidad-5865F2?style=for-the-badge&logo=discord&logoColor=white&labelColor=101010)](https://mouredev.com/discord) -[![Link](https://img.shields.io/badge/Links_de_interés-moure.dev-39E09B?style=for-the-badge&logo=Linktree&logoColor=white&labelColor=101010)](https://moure.dev) +> **¿Buscas un extra?** Aquí encontrarás mis cursos editados por lecciones individuales, para avanzar a tu ritmo y guardar el progreso. También dispondrás de ejercicios y correcciones, test para validar tus conocimientos, examen y certificado público de finalización, soporte, foro de estudiantes, reunionnes grupales, cursos exclusivos y mucho más. +> +> Entra en **[mouredev.pro](https://mouredev.pro)** y utiliza el cupón **"PRO"** con un 10% de descuento en tu primera suscripción. ## ![https://mouredev.com](https://raw.githubusercontent.com/mouredev/mouredev/master/mouredev_emote.png) Hola, mi nombre es Brais Moure. ### Freelance full-stack iOS & Android engineer @@ -70,8 +146,10 @@ Si quieres unirte a nuestra comunidad de desarrollo, aprender programación de A ![GitHub Followers](https://img.shields.io/github/followers/mouredev?style=social) ![GitHub Followers](https://img.shields.io/github/stars/mouredev?style=social) -Soy ingeniero de software desde hace más de 13 años. Desde hace 5 años combino mi trabajo desarrollando Apps con creación de contenido formativo sobre programación y tecnología en diferentes redes sociales como **[@mouredev](https://moure.dev)**. +Soy ingeniero de software desde 2010. Desde 2018 combino mi trabajo desarrollando Apps con la creación de contenido formativo sobre programación y tecnología en diferentes redes sociales como **[@mouredev](https://moure.dev)**. -### En mi perfil de GitHub tienes más información +Si quieres unirte a nuestra comunidad de desarrollo, aprender programación, mejorar tus habilidades y ayudar a la continuidad del proyecto, puedes encontrarnos en: -[![Web](https://img.shields.io/badge/GitHub-MoureDev-14a1f0?style=for-the-badge&logo=github&logoColor=white&labelColor=101010)](https://github.com/mouredev) +[![Twitch](https://img.shields.io/badge/Twitch-Programación_en_directo-9146FF?style=for-the-badge&logo=twitch&logoColor=white&labelColor=101010)](https://twitch.tv/mouredev) +[![Discord](https://img.shields.io/badge/Discord-Servidor_de_la_comunidad-5865F2?style=for-the-badge&logo=discord&logoColor=white&labelColor=101010)](https://mouredev.com/discord) [![Pro](https://img.shields.io/badge/Cursos-mouredev.pro-FF5500?style=for-the-badge&logo=gnometerminal&logoColor=white&labelColor=101010)](https://moure.dev) +[![Link](https://img.shields.io/badge/Links_de_interés-moure.dev-14a1f0?style=for-the-badge&logo=Linktree&logoColor=white&labelColor=101010)](https://moure.dev) [![Web](https://img.shields.io/badge/GitHub-MoureDev-087ec4?style=for-the-badge&logo=github&logoColor=white&labelColor=101010)](https://github.com/mouredev)