Bienvenida conceptos básicos y contexto histórico de las Bases de Datos

1

Bienvenida conceptos básicos y contexto histórico de las Bases de Datos

2

Playground: tu primera consulta en bases de datos

Introducción a las bases de datos relacionales

3

Historia de las bases de datos relacionales

4

Qué son entidades y atributos

5

Entidades de Platzi Blog

6

Relaciones

7

Múltiples muchos

8

Diagrama ER

9

Diagrama Físico: tipos de datos y constraints

10

Diagrama Físico: normalización

11

Formas normales en Bases de Datos relacionales

12

Diagrama Físico: normalizando Platziblog

RDBMS (MySQL) o cómo hacer lo anterior de manera práctica

13

¿Qué es RDB y RDBMS?

14

Instalación local de un RDBMS (Windows)

15

Instalación local de un RDBMS (Mac)

16

Instalación local de un RDBMS (Ubuntu)

17

Clientes gráficos

18

Servicios administrados

SQL hasta en la sopa

19

Historia de SQL

20

DDL create

21

Playground: CREATE TABLE

22

CREATE VIEW y DDL ALTER

23

DDL drop

24

Playground: VIEW, ALTER y DROP en SQL

25

DML

26

Playground: CRUD con SQL

27

¿Qué tan standard es SQL?

28

Creando Platziblog: tablas independientes

29

Creando Platziblog: tablas dependientes

30

Creando Platziblog: tablas transitivas

Consultas a una base de datos

31

¿Por qué las consultas son tan importantes?

32

Estructura básica de un Query

33

SELECT

34

Playground: SELECT en SQL

35

FROM y SQL JOINs

36

Utilizando la sentencia FROM

37

Playground: FROM y LEFT JOIN en SQL

38

WHERE

39

Utilizando la sentencia WHERE nulo y no nulo

40

Playground: Filtrando Datos con WHERE

41

GROUP BY

42

ORDER BY y HAVING

43

Playground: Agrupamiento y Ordenamiento de Datos

44

El interminable agujero de conejo (Nested queries)

45

¿Cómo convertir una pregunta en un query SQL?

46

Preguntándole a la base de datos

47

Consultando PlatziBlog

48

Playground: Prueba Final con PlatziBlog

Introducción a la bases de datos NO relacionales

49

¿Qué son y cuáles son los tipos de bases de datos no relacionales?

50

Servicios administrados y jerarquía de datos

Manejo de modelos de datos en bases de datos no relacionales

51

Top level collection con Firebase

52

Creando y borrando documentos en Firestore

53

Colecciones vs subcolecciones

54

Recreando Platziblog

55

Construyendo Platziblog en Firestore

56

Proyecto final: transformando tu proyecto en una db no relacional

Bases de datos en la vida real

57

Bases de datos en la vida real

58

Big Data

59

Data warehouse

60

Data mining

61

ETL

62

Business intelligence

63

Machine Learning

64

Data Science

65

¿Por qué aprender bases de datos hoy?

Bonus

66

Bases de datos relacionales vs no relacionales

67

Elegir una base de datos

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Creando Platziblog: tablas dependientes

29/67
Recursos
  • El comando “cascade” sirve para que cada que se haga un update en la tabla principal, se refleje también en la tabla en la que estamos creando la relación.

Aportes 202

Preguntas 70

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Las Foreing Key options son las siguientes:

On update: Significa qué pasará con las relaciones cuando una de estas sea modificada en sus campos relacionados, Por ejemplo, pueden utilizarse los valores:
cascade: Si el id de un usuario pasa de 11 a 12, entonces la relacion se actualizará y el post buscará el id nuevo en lugar de quedarse sin usuario.
_ restrict: _Si el id de un usuario pasa de 11 a 12, no lo permitirá hasta que no sean actualizados antes todos los post relacionados.
set null Si el id de un usuario pasa de 11 a 12, entonces los post solo no estará relacionados con nada.
no action: Si el id de un usuario pasa de 11 a 12, no se hará nada. Solo se romperá la relación.
On delete
_ cascade:
Si un usuario es eliminado entonces se borrarán todos los post relacionados.
restrict: No se podrá eliminar un usuario hasta que sean eliminados todos su post relacionados.
_ set null
: Si un usuario es eliminado, entonces los post solo no estará relacionados con nada.
no action: Si un usuario es eliminado, no se hará nada. Solo se romperá la relación.

Lo hice mediante código y me sirvió de esta manera

CREATE TABLE categorias(
id INT NOT NULL AUTO_INCREMENT,
nombre_categoria VARCHAR(30) NOT NULL,
PRIMARY KEY (id)
)

CREATE TABLE etiquetas(
id INT NOT NULL AUTO_INCREMENT,
nombre_etiqueta VARCHAR(30) NOT NULL,
PRIMARY KEY (id)
)
CREATE TABLE usuarios(
id INT NOT NULL AUTO_INCREMENT,
login VARCHAR(30) NOT NULL,
password VARCHAR(32) NOT NULL,
nickname VARCHAR(40) NOT NULL,
email VARCHAR(40) NOT NULL,
PRIMARY KEY (id),
UNIQUE (email)
)

CREATE TABLE posts(
id INT,
titulo VARCHAR(130) NOT NULL,
fecha_publicacion TIMESTAMP,
contenido TEXT NOT NULL,
estatus CHAR(8) DEFAULT "activo",
usuario_id INT NOT NULL,
categoria_id INT NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (usuario_id) REFERENCES usuarios(id) ON UPDATE CASCADE ON DELETE NO ACTION,
FOREIGN KEY (categoria_id) REFERENCES categorias(id)
)```

Al seleccionar el datatype en la versión actual te limita a usar el paréntesis en el caso de TIMESTAMP y en TEXT pero si se le borra el paréntesis funciona (porque sino no deja seleccionarlo).
No obstante, TIMESTAMP tiene un valor (n) que va de 0 a 6 decimales.
en TEXT hay diferentes tipos de TEXT como TINYTEXT, MEDIUMTEXT, y LONGTEXT, incluyendo el mismo TEXT 😃

Para que se vayan guiando

Notas
Crear tablas en orden:

  1. categorias
  2. etiquetas
  3. usuarios
  4. posts

ACTIONS:
NO ACTION: No hacer nada al borrar alguna de las partes de la relación
** SET NULL:** El campo de llave foranea se setea en NULO (NULL), esto solo si el campo tiene permitido los NULOS
CASCADE: Se hace efecto cascada, si la dependencia se borra entonces se borra también se borra el registro que es dependiente Ejemplo: Al borrar un Usuario se borrarían todos los POSTS en caso de seleccionar CASCADE
RESTRICT: En caso de intentar borrar la dependencia y existen registros dependientes, no se permite el borrado, Ejemplo: Si se intenta borrar un usuario y este tiene posts, entonces no se permite el borrado del usuario

Les comparto mi modelo para la Base de Datos del hospital donde trabajo en México!

El plan es hacer una base de datos para almacenar Historia Clínica Electrónica de los distintos pacientes

Para los que usen MySQL 8.0, en TIMESTAMP deben poner un valor entre 0 o 6 dentro del paréntesis. Este número corresponde a fracciones de segundos, es decir, si escogemos 6, tendríamos microsegundos.

En esta entrada les traigo como crear la tabla posts usando DDL. En este ejemplo podrán ver como crear un campo limitado por verificación usando el Check, así como también la forma de alterar las tablas usando DDL para agregar llaves foráneas. Uno puede agregar las foráneas cuándo crea la tabla, pero durante el proceso de mantenimiento de la base de datos es posible que tengas que crear nuevas tablas y agregar nuevas relaciones, para esto es necesario saber agregar constraints usando alter.

CREATE TABLE posts(
	id INT NOT NULL,
    categoria_id int not null,
    usuario_id int not null,
    titulo VARCHAR(255) NOT NULL,
    fecha_publicacion timestamp not null default now(),
    contenido TEXT null,
    estado CHAR(8) CHECK(estado in('activo','inactivo')),
    CONSTRAINT post_pk PRIMARY KEY(id)
);
ALTER TABLE posts 
ADD CONSTRAINT usuario_posts_fk 
FOREIGN KEY(usuario_id) 
REFERENCES usuarios(id);

ALTER TABLE posts
ADD CONSTRAINT categoria_posts_fk
FOREIGN KEY(categoria_id)
REFERENCES categorias(id);```

La verdad solo dibujè mi diagrama en EER y creo las tablas y rompio el Muchos a muchos automaticamente, se hace todo muy facil, les comparto el mio para ordenes de despacho en un almacen de repuestos de equipos CAT, les agradezco cualquier comentario
![](

create table posts 
(
  id int not null auto_increment,
  titulo varchar(130) not null,
  fecha_publicacion timestamp null default null,
  contenido text not null,
  estatus char(8) default "activo",
  usuario_id int default null,
  categoria_id int default null,
  constraint primary key (id),
  constraint foreign key (categoria_id) references categorias (id) on delete no action on update no action,
  constraint foreign key (usuario_id) references usuarios (id) on delete no action on update cascade
  );

create table comentarios
(
  id int not null auto_increment,
  cuerpo_comentario text not null,
  usuario_id int not null,
  post_id int not null,
  primary key (id),
  constraint foreign key (post_id) references posts (id) on delete no action on update no action,
  constraint foreign key (usuario_id) references usuarios (id) on delete no action on update no action
)```

Por favor note que al momento de crear la tabla posts, Israel no utiliza los nombres de variables que se definio en el diagrama fisico. En lugar de crear la tabla posts con las FK llamadas usuarios_id y categorias_id, las llama usuario_id y categoria_id. En singular. Cuando eres nuevo en este tema, estos detalles tienden a confundirte, pues no puedes seguir todos los pasos y correlacionar lo nuevo con lo que estudiaste antes. Tampoco se explica un hecho importante y es que las FK tal como se definen en el Diagrama Fisico, se limitan a un nombre i.e. usuarios_id identificada con FK. En el software, para crear las FK se debe crear una CONSTRAINT llamada ‘posts_usuarios’ y tambien un INDEX llamado ‘post_usuarios_idx’. Nota que la documentacion del Diagrama Fisico no contiene estas nuevas variables, por tanto hay que tener cuidado con saber que estan ahi.

Acciones:
- CASCADE: Si se actualiza en un lado, el otro le sigue
- SET NULL: Cambia el dato a nulo
- RESTRICT: No deja que se cambie, hasta que se resuelva primero aquí
- DO NOTHING

A alguien más le pasa que agrega la palabra VISIBLE; Seguido de el usuario_id ASC?

ALTER TABLE `platziblog`.`posts` 
ADD INDEX `posts_usuarios_idx` (`usuarios_id` ASC) VISIBLE;
;
ALTER TABLE `platziblog`.`posts` 
ADD CONSTRAINT `posts_usuarios`
  FOREIGN KEY (`usuarios_id`)
  REFERENCES `platziblog`.`usuarios` (`id`)
  ON DELETE NO ACTION
  ON UPDATE CASCADE;

Creo que es recomendable mantener el estándar a la hora de crear los nombres de las entidades y atributos, ejemplo en los nombres, si decido crearlos en ingles debería ser el estándar para todos y no combinar unas entidades y atributos en ingles y otros en español.

Es importante tener en cuenta que para que pueda haber una relacion las tablas deben tener las mismas propiedades, un error comun que descubri que puede pasar esq al crear las tablas se ponen por defecto en MyISAM o InnoDB y si al relacionarlas son diferentes va generar un error tipo: MySQL ERROR: Error 1215: Cannot add foreign key constraint

Saludos.
Una explicación excelente sobre restricciones de integridad referencial la tenemos en el siguiente enlace
Link

Estupenda explicación instructor Israel, yo no conocía esa funcionalidad o actions que se establece con las llaves foráneas tanto para los casos de edición como los de eliminación, le daré un buen uso a esta información.

Por cierto, si establecen las llaves foráneas por el comando:
alter table (nombre tabla) add foreign key (nombre id fk) references nombre_tabla_de_ la_fk (nombre id pk)
y no añaden nada más, esta quedara con los actions tanto en update como delete en restrict.

tabla posts

CREATE TABLE posts(
	id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
    titulo VARCHAR(150) NOT NULL,
    fecha_publicacion TIMESTAMP NOT NULL,
    contenido TEXT NOT NULL,
    estatus CHAR(8) NOT NULL DEFAULT 'Activo',
    usuarios_id	INTEGER NOT NULL,
    categorias_id INTEGER NOT NULL,
    constraint foreign key (usuarios_id) 
    references usuarios(id) 
    on delete no action on update cascade,

    constraint foreign key (categorias_id) 
    references categoria(id) 
    on delete no action on update no action
);

Tengo una duda
¿Si yo defino las claves foráneas así funciona?

CREATE TABLE posts (
	id INT NOT NULL AUTO_INCREMENT,
	titulo VARCHAR(130) NOT NULL,
	fecha_publicacion TIMESTAMP NULL,
	contenido TEXT NOT NULL,
	estatus CHAR(8) NULL DEFAULT 'activo',
	usuario_id INT NOT NULL,
	categoria_id INT NOT NULL,
	PRIMARY KEY(id),
	FOREIGN KEY (usuario_id) REFERENCES usuarios(id),
	FOREIGN KEY (categoria_id) REFERENCES categorias(id)
);

Es que siempre he usado esta forma para crear las claves foráneas y no sé como funciona lo de INDEX.

Transformando el diagrama físico en un modelo conceptual agregando prefix y utilizando otros tipos de datos(BIT, TIMESTAMP Y TEXT, BIGINT) (a decisión individual a modo de prueba):

Me gusta cuando las clases son practicas.

“Tu capacidad de mejorar es incrementada cuando tu vida corre peligro” … Porque nos obligaron a escribir código en papel para después explicarlo y si no funcionaba, reprobabas. Eso sí es sentir el código jaja

![](

Para los que usan un manejador que no les permite usar el constraint “CHECK”, pueden utilizar un tipo de dato llamado “ENUM”, que cumple una funcionalidad similar

Apuntes:
Las claves (o llaves) foráneas son columnas o grupos de columnas en una tabla que tienen valores que coinciden con las llaves primarias (normalmente) de otra entidad. Estas llaves se usan para combinar tablas.
Nota: Para hacer mas fácil el mantenimiento en una DB es muy importante y recomendable elegir nombres para las llaves primarias y foráneas de modo que la relación entre ellas sea aparente.

Había tenido una dificultad creando las claves foraneas de post_categorias, pero era por un error que tenía en mi tabla de categorías, pequeño detalle, pero lo pude solucionar… DROP!

Para el campo de estatus en posts me gusta más un campo booleano, pues es menos espacio y el status de activo o inactivo se maneja en el frontend.

Para practicar con una base de datos en linea les dejo esta plataforma donde pueden crear una Base de Datos o desplegar algun proyecto de prueba GRATIS
Link: Railway

Creadas las tablas

CREATE TABLE posts (
  id int(11) NOT NULL AUTO_INCREMENT,
  titulo varchar(130) NOT NULL,
  fecha_publicacion timestamp NULL DEFAULT NULL,
  contenido text NOT NULL,
  estatus char(8) DEFAULT 'activo',
  usuario_id int(11) DEFAULT NULL,
  categoria_id int(11) DEFAULT NULL,
  PRIMARY KEY (id),
  KEY posts_usuarios_idx (usuario_id),
  KEY posts_categorias_idx (categoria_id),
  CONSTRAINT posts_categorias FOREIGN KEY (categoria_id) REFERENCES categorias (id) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT posts_usuarios FOREIGN KEY (usuario_id) REFERENCES usuarios (id) ON DELETE NO ACTION ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=65 DEFAULT CHARSET=utf8;

CREATE TABLE comentarios (
  id int(11) NOT NULL AUTO_INCREMENT,
  cuerpo_comentario text NOT NULL,
  usuario_id int(11) NOT NULL,
  post_id int(11) NOT NULL,
  PRIMARY KEY (id),
  KEY comentarios_usuario_idx (usuario_id),
  KEY comentarios_post_idx (post_id),
  CONSTRAINT comentarios_post FOREIGN KEY (post_id) REFERENCES posts (id) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT comentarios_usuario FOREIGN KEY (usuario_id) REFERENCES usuarios (id) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;```

Sigo diciendo que es muy buen curso, creo que es conciso en los temas y lo explica de una manera muy sencilla

Yo decidí hacer todo con código. Se los dejó por si tienen algún comentario y también dejo como quedó mi diagrama.

create database fifa character set utf8;

use fifa;

create table fifa.players(
	player_id int primary key auto_increment,
    full_name varchar(200) not null,
    short_name varchar(100) not null,
    birthday date not null,
    age int not null,
    value_eur int not null,
    player_position varchar(20),
    team_fk int,
    foreign key (team_fk) references teams(team_id)
);

create table fifa.teams(
	team_id int primary key auto_increment,
    team_name varchar(100) not null,
    league_fk int,
	foreign key(league_fk) references leagues(league_id),
    country_fk varchar(50)
);


create table fifa.leagues(
	league_id int primary key auto_increment,
    league_name varchar(100) not null,
    country_fk int
);

de esta manera pude realizarlo mediante código, espero les ayude!

create table categorias(
idCategoria INT NOT NULL auto_increment,
nombreCategoria varchar(30) NOT NULL,
constraint PK_idCategoria primary key (idCategoria)
);

create table etiquetas(
idEtiqueta INT NOT NULL auto_increment,
nombreEtiqueta varchar(30) NOT NULL,
constraint PK_idEtiqueta primary key (idEtiqueta)
);

create table usuarios(
idUsuario INT NOT NULL auto_increment,
loginUsuario varchar(30) NOT NULL,
passwordUsuario varchar(32) NOT NULL,
nicknameUsuario varchar(40) NOT NULL UNIQUE,
emailUsuario varchar(40) NOT NULL UNIQUE,
constraint PK_idUsuario primary key (idUsuario)
);

create table post(
idPost INT NOT NULL auto_increment,
tituloPost varchar(150) NOT NULL,
fecha_publicacionPost timestamp,
contenidoPost text NOT NULL,
statusPost char(8) DEFAULT ‘activo’,
idUsuario INT NOT NULL,
idCategoria INT NOT NULL,
constraint PK_idPost primary key (idPost),
constraint FK_idUsuario foreign key (idUsuario) references usuarios(idUsuario) ON UPDATE CASCADE ON DELETE NO ACTION,
constraint FK_idCategoria foreign key (idCategoria) references categorias(idCategoria) ON UPDATE NO ACTION ON DELETE NO ACTION
);

Aunque el profe nos da una excelente explicación, recomiendo leer (a la par del curso) el libro de Antonio Padial Solier sobre SQL. Funciona como un manual súper práctico y sencillo para ampliar nuestra visión y entendimiento sobre el tema. Saludos

Donde dice Foreign Key Opitons hay dos opciones

On Update: Significa qué pasará con las relaciones cuando una de estas sea modificada en sus campos relacionados, por ejemplo, pueden utilizarse los valores:

Cascade: Si el id de un usuario pasa de 11 a 12, entonces la relación se actualizará y el post buscará el id nuevo en lugar de quedarse sin usuario.

Restrict: Si el id de un usuario pasa de 11 a 12, no lo permitirá hasta que no sean actualizados antes todos los post relacionados asociados a él.

Set null: Si el id de un usuario pasa de 11 a 12, entonces los post solo no estará relacionados con nada.

No Action: Si el id de un usuario pasa de 11 a 12, no se hará nada. Solo se romperá la relación.

On Delete: Significa qué pasará con las relaciones cuando una de estas sea eliminadas en sus campos relacionados, por ejemplo, pueden utilizarse los valores

Cascade: Si un usuario es eliminado entonces se borrarán todos los post relacionados.

Restrict: No se podrá eliminar un usuario hasta que sean eliminados todos su post relacionados.

Set Null: Si un usuario es eliminado, entonces los post solo no estará relacionados con nada.

No Action: Si un usuario es eliminado, no se hará nada. Solo se romperá la relación.

Cascade es importante colocarlo a la hora de ligar las llaves foráneas, ya qué, nos permitirá, cada vez que se realicen modificaciones en los datos de una tabla y, no se va a romper la relación. (On update) o, a la hora de borrarlo (on delete)

Por concepto entiendo que una Llave Primaria PK es la union de dos constrains que son : UNIQUE y NOT NULL, pero si le coloco a un atributo esos dos constrains pero no selecciono PK en el cliente gráfico se considera o entiendo yo que puede ser una PK de la tabla pero seria inmediatamente una PK de la tabla tambien?

Vengo del futuro, debes crear las tablas y columnas exactamente con el mismo nombre que las crea Israel. Luego será un problema tratar de insertar datos usando el script que nos dispone Israel cuando las columnas no coincidan. Por ejemplo con el uso de la S. Ejemplo: categoria_id != categoriaS_id

En algun punto en mis clases de base de datos habia oido algo de cascada y en algunas ocasiones tuve problemas cuando trataba de eliminar una tupla y no me dejaba y no sabia el porque, ya que la base no las daba el profesor para practicas de consultas me imagino que en la definicion estaba estos constrains, ahora todo tiene sentido, excelente explicacion

Esta es mi tabla creada desde HeidiSQL

CREATE TABLE `posts` (
	`id` INT(11) NOT NULL AUTO_INCREMENT,
	`titulo` VARCHAR(150) NOT NULL DEFAULT '',
	`fecha_publicacion` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
	`contenido` TEXT NOT NULL DEFAULT '',
	`estatus` CHAR(8) NOT NULL DEFAULT 'ACTIVO',
	`usuarios_id` INT(11) NOT NULL DEFAULT 0,
	`categorias_id` INT(11) NOT NULL DEFAULT 0,
	PRIMARY KEY (`id`),
	INDEX `FK_post_1` (`usuarios_id`),
	INDEX `FK_post_2` (`categorias_id`),
	CONSTRAINT `FK_post_1` FOREIGN KEY (`usuarios_id`) REFERENCES `usuarios` (`id`),
	CONSTRAINT `FK_post_2` FOREIGN KEY (`categorias_id`) REFERENCES `categorias` (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;```

En heidi seria asi:

CREATE TABLE `post` (
	`id` INT NOT NULL AUTO_INCREMENT,
	`titulo` VARCHAR(150) NOT NULL DEFAULT '0',
	`fecha_publicacion` TIMESTAMP NOT NULL,
	`contenido` TEXT NOT NULL DEFAULT '0',
	`estatus` CHAR(8) NOT NULL DEFAULT 'Activo',
	`usuario_id` INT NOT NULL DEFAULT 0,
	`categorias_id` INT NOT NULL DEFAULT 0,
	PRIMARY KEY (`id`),
	CONSTRAINT `FK__usuario` FOREIGN KEY (`usuario_id`) REFERENCES `usuario` (`id`) ON UPDATE CASCADE ON DELETE NO ACTION,
	CONSTRAINT `FK__categoria` FOREIGN KEY (`categorias_id`) REFERENCES `categoria` (`id`) ON UPDATE NO ACTION ON DELETE NO ACTION
)
COLLATE='utf8_spanish_ci'
;

Espero sus comentarios y sugerencias

Es importante definir qué tipo de relación va a existir entre las diferentes entidades de nuestra BD desde el diseño en papel y lápiz.

Hola a todos, una consulta alguien sabe cuando uno tiene que eligir en sus modelos que entidad va a ser el centro y va a tener las claves foraneas de las otras entidades? ( por ejemplo porque posts y no usuarios?.

Hola, anexo comentarios, es una base de datos de clientes, con su sucursales, contactos y segmento al cual pertenece el cliente.

![](

Que facil es esto con un editor grafico.

De acuerdo, ya entiendo la lógica de primero crear las entidades que no tienen llave foránea y luego las tablas dependientes (las cuales tienen llave foránea).

En este enlace se especifica que son los constrains y como funcionan.

buen curso

Sé que algunos se lo preguntan, así que…

La diferencia entre TIMESTAMP y TIMESTAMP() es que la primera es un tipo de dato (eso es lo que necesitamos actualmente) mientras que la segunda es una función (parecida a las existentes en Excel).

La función TIMESTAMP() puede tomar uno o dos argumentos y devuelve un valor TIMESTAMP calculado a partir de los argumentos proporcionados.

ON DELETE:

  • CASCADE: Si un usuario es eliminado, se borrarán todos los post relacionados.
  • RESTRICT: No se podrá eliminar un usuario hasta que sean eliminados todos sus posts publicados.
  • SET NULL: Si un usuario es eliminado, los campos relacionados con la entidad dependiente, se establecerán en nulos.
  • NO ACTION: Si un usuario es eliminado, no se hará nada. Solo se romperá la relación.

(Aporte ligeramente modificado.)
ON UPDATE: Significa qué pasará con la entidad dependiente cuando su entidad principal sea modificada en sus campos relacionados. Por ejemplo; Pueden utilizarse los valores:

  • CASCADE: Si el id de un usuario pasa de 11 a 12, la relación con la entidad dependiente se actualizará y el post buscará el id nuevo en lugar de quedarse sin usuario.
  • RESTRICT: Si el id de un usuario intenta pasar de 11 a 12, no se permitirá hasta que no sean actualizados todos los post publicados por dicho usuario.
  • SET NULL: Si el id de un usuario pasa de 11 a 12, los campos relacionados con la entidad dependiente, se establecerán en nulos.
  • NO ACTION: Si el id de un usuario pasa de 11 a 12, no se hará nada. Solo se romperá la relación.

Resulta un poco difícil seguir el paso ya que la versión del software ha cambiado y no es igual.

Se va poniendo cada vez mas bueno

Hola chicos.

Me estaba rompiendo la cabeza porque practicando al crear relaciones (en mi proyecto personal) en la terminal obtenía el siguiente error.

Error Code: 1824. Failed to open the referenced table ‘mundiales’

En internet hay una solución común y es que se debe revisar que las tablas en cuestión tengan configurado el mismo motor (InnoDB, etc)

Pero mi error era de Typo, se me fue una letra demás en el nombre de la BD.

Solo comparto para que tengan en cuenta.

Holaaaa, estoy usando mysql con mysql workbench 8.0 CE, si a alguno ha querido correr el script que le muestra a Israel al momento de crear la clave foranea se va a dar cuenta que le tira error cuando se intenta agregar el INDEX diciendo que ese atributo no existe en la tabla. Estuve investigando el por que de esto y la cuestion es que ahora se crea automaticamente cuando creas la clave foranea, por ejemplo: les quedara de la siguiente manera en el apartado Indexes(tienen los mismos nombres que los contratos de las claves foraneas.

Borrar los paréntesis en Timestamp y Text

Si quieren utilizar el CHECK en mysql, lo pueden usar de la siguiente forma

CREATE TABLES posts(
  ...
  status CHAR(8) CHECK(status="active" OR status="inactive")
);

Acciones que suceden al modificar una table que tiene relación con otra

CASCADE: Cuando se haga una acción en un lado tambien lo hara en la tabla presente

SET NULL: Marcar como nulo el campo relacionado

RESTRICT: Impide que se realizcen acciones hasta tener la tabla o campo relacionado vacío, tengo entendido que se deja en muchos casos por seguridad

NO ACTION: No hacer nada, dejar que se rompa la relación

Comparto el código de la clase pasada:

  • No usar ñ

  • No usar acentos

create table categorias
(
id int not null auto_increment,
nom_categoria varchar(30) not null,
constraint primary key (id)
);

create table etiquetas
(
id int not null auto_increment,
nom_etiquetas varchar(30) not null,
constraint primary key (id)
);

create table usuarios 
(
  id int not null auto_increment,
  login varchar(30) not null,
  pasword varchar(32) not null,
  nickname varchar(40) not null,
  email varchar(40) not null,
  primary key (id),
  unique key email_unique (email)
);

Aca el script completo

CREATE TABLE `platziblog`.`post` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `titulo` VARCHAR(45) NULL,
  `fecha_publicacion` timestamp NULL,
  `contenido` VARCHAR(45) NULL,
  `estatus` CHAR(8) NULL,
  `usuario_id` INT NULL,
  `categoria_id` INT NULL,
  PRIMARY KEY (`id`),
  INDEX `USUARIO_ID_COMENT_idx` (`usuario_id` ASC),
  CONSTRAINT `USUARIO_ID_POST`
    FOREIGN KEY (`usuario_id`)
    REFERENCES `platziblog`.`usuario` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  INDEX `CATEGORIA_ID_POST_idx` (`categoria_id` ASC),
	CONSTRAINT `CATEGORIA_ID_POST`
    FOREIGN KEY (`categoria_id`)
    REFERENCES `platziblog`.`categoria` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION);



CREATE TABLE `platziblog`.`usuario` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `login` VARCHAR(255) NOT NULL,
  `password` VARCHAR(255) NOT NULL,
  `nickname` VARCHAR(255) NOT NULL,
  `email` VARCHAR(255) NOT NULL,
  PRIMARY KEY (`id`));
  
  
CREATE TABLE `platziblog`.`comentario` (
  `id` INT NOT NULL,
  `comentario` TEXT NULL,
  `usuario_id` INT NULL,
  `post_id` INT NULL,
  PRIMARY KEY (`id`),
  INDEX `USUARIO_ID_idx` (`usuario_id` ASC),
  CONSTRAINT `USUARIO_ID`
    FOREIGN KEY (`usuario_id`)
    REFERENCES `platziblog`.`usuario` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION);


CREATE TABLE `platziblog`.`categoria` (
  `id` INT NOT NULL,
  `nombre` VARCHAR(45) NULL,
  PRIMARY KEY (`id`));
  
  
 CREATE TABLE `platziblog`.`etiqueta` (
  `id` INT NOT NULL,
  `nombre` VARCHAR(45) NULL,
  PRIMARY KEY (`id`));
  
  CREATE TABLE `platziblog`.`post_etiqueta` (
  `id_post` INT NOT NULL,
  `id_etiqueta` INT NULL,
  INDEX `ID_POST_idx` (`id_post` ASC),
  INDEX `ID_ETIQUETA_idx` (`id_etiqueta` ASC),
  CONSTRAINT `ID_POST`
    FOREIGN KEY (`id_post`)
    REFERENCES `platziblog`.`post` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `ID_ETIQUETA`
    FOREIGN KEY (`id_etiqueta`)
    REFERENCES `platziblog`.`etiqueta` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION);


Mejor que en mi universidad x1000

Tengo una duda, las llaves foraneas se crean antes de llenar los valores de las tablas ?

TIMESTAMP :
nos va apermitir tener la fecha y hora en que se publico!

Status va aser activo o inactivo, y en este caso usamos un CHAR de 8 y agregamos un constrait defaul! Por si lo mandamos vacio!
Entonces si viene activo aparecera el estado defaul que pusimos 'activo’
Luego se puede cambiar a ‘inactivo’ podemos hacer un update a la tabla!

DEFAULT
Se puede decir que no es una restricción, ya que solo se ingresa un valor en caso de que ninguno otro sea especificado. Si una columna permite NULL y el valor a insertar no se especifica, se puede sustituir con un valor predeterminado.
CREATE TABLE nombreTabla
(
nombreColumna1 INT NULL CONSTRAINT DF_nombreRestriccion DEFAULT(0),
nombreColumna2 VARCHAR(100) NOT NULL,
nombreColumna3 NVARCHAR(200) NOT NULL,
);
Para obtener una lista de las restricciones DEFAULT:
SELECT *
FROM sys.default_constraints
WHERE parent_object_id = OBJECT_ID(‘nombreEsquema.nombreTabla’);

Crear una relación:

ALTER TABLE table_name
ADD CONSTRAINT fkey_name
FOREIGN KEY ( column_name ) REFERENCES table_name ( references_table’s column)
ON DELETE { NO ACTION / CASCADE / SET NULL / RESTRIC }
ON UPDATE { CASCADE / NO ACTION / SET NULL / RESTRIC };

Eliminar FK:
ALTER TABLE table_name
DROP FOREIGN KEY fkey_name;

Base de datos sobre la policia 😅

Cuando colocan el datatype en fecha de publicacion te limita a usar el paréntesis en el caso de TIMESTAMP y en TEXT pero si se le borra el paréntesis funciona.

En la consola, lo hice de esta manera 😄

Chicos/as.
Recuerden que también puede ejecutar las instrucciones para creación de claves foráneas directamente en el editor de Workbench.

-- CLAVES FORANEAS ENTRE POST, USUARIOS Y CATEGORIAS
ALTER TABLE posts ADD CONSTRAINT fk_posts_usuarios FOREIGN KEY (usuario_id) REFERENCES usuarios (usuario_id)
ON DELETE NO ACTION
ON UPDATE CASCADE;

ALTER TABLE posts ADD CONSTRAINT fk_posts_categorias FOREIGN KEY (categoria_id) REFERENCES usuarios (usuario_id)
ON DELETE NO ACTION
ON UPDATE CASCADE;

No se porque me pasa que a las Foreing Keys le pongo “NO ACTION” y después en el panel de la izquierda aparece “RESTRICT”

Ejercicio

create table posts (
id int not null auto_increment primary key,
titulo varchar(150) not null,
fecha_publicacion timestamp,
contenido text not null,
status char(8) default 'activo' check('activo'),
usuario_id int not null,
categoria_id int not null,
foreign key (usuario_id) references usuarios(id) on delete no action on update cascade,
foreign key (categoria_id) references categorias(id) on delete no action on update cascade
);

CREATE TABLE posts (
post_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
post_title VARCHAR(150) NOT NULL
post_publication_date timestamp,
post_content TEXT NOT NULL,
post_status char(8) default’activo’check(‘activo’),
user_id INT NOT NULL,
categories_id INT NOT NULL,
foreign key (user_id) references user(id) on delete no action on update cascade,
foreign key (categories_id) references categories(id) on delete no action on update cascade
);

Así tambien pueden crear una tabla con llave foranea:

CREATE TABLE post (
id INT NOT NULL AUTO_INCREMENT,
title VARCHAR(130),
date_publication TIMESTAMP,
content TEXT NOT NULL,
status_ CHAR(8) NULL DEFAULT “activo”,
usuario_id INT NOT NULL,
categoria_id INT NOT NULL,
PRIMARY KEY(id),
CONSTRAINT fk_user FOREIGN KEY (usuario_id) REFERENCES users (id),
CONSTRAINT fk_categoria FOREIGN KEY (categoria_id) REFERENCES category (id)
ON UPDATE CASCADE
);

Mismo ejercicio en PostgreSQL

CREATE TABLE posts (
	id SERIAL PRIMARY KEY NOT NULL,
	titulo VARCHAR(15) NOT NULL,
	fecha_publicacion TIMESTAMP NOT NULL,
	contenido TEXT,
	estado CHAR(8) 
		CHECK(estado = 'activo' OR estado = 'inactivo')
		DEFAULT 'activo',
	usuarios_id INT NOT NULL,
	categorias_id INT NOT NULL
);

ALTER TABLE posts
ADD FOREIGN KEY (usuarios_id)
	REFERENCES usuarios(id)
	ON DELETE NO ACTION
	ON UPDATE CASCADE;

ALTER TABLE posts
ADD FOREIGN KEY (categorias_id)
	REFERENCES categorias(id)
	ON DELETE NO ACTION
	ON UPDATE NO ACTION;```

es lógico comenzar con la tablas dependientes ya que estas no
tienen campos dependientes de otras, para luego seguir con las dependientes que si dependen de las independientes

CASCADE: Para cuando actualices un llave primaria, se actualice también la llave foránea correspondiente en otra tabla.

pregunta;
¿¿¿no debería ser la llave foránea también autoincremental???

\-- 📂 Tabla de Categorías CREATE TABLE `platziblog`.`categorias` ( `id` INT NOT NULL AUTO\_INCREMENT, -- 🔑 ID único para cada categoría `categoria` VARCHAR(30) NOT NULL, -- 📂 Nombre de la categoría PRIMARY KEY (`id`) -- 🔑 Llave primaria ); \-- 👤 Tabla de Usuarios CREATE TABLE `platziblog`.`usuarios` ( `id` INT NOT NULL AUTO\_INCREMENT, -- 🔑 ID único para cada usuario `login` VARCHAR(30) NOT NULL, -- 👤 Nombre de usuario (login) `password` VARCHAR(32) NOT NULL, -- 🔒 Contraseña del usuario `nickname` VARCHAR(40) NOT NULL, -- 🏷 Apodo visible para otros usuarios `email` VARCHAR(40) NOT NULL UNIQUE, -- 📧 Correo electrónico único PRIMARY KEY (`id`) -- 🔑 Llave primaria ); \-- 📝 Tabla de Posts CREATE TABLE `platziblog`.`posts` ( `id` INT NOT NULL AUTO\_INCREMENT, -- 🔑 ID único para cada post `titulo` VARCHAR(150) NOT NULL, -- 📝 Título del post `fecha\_publicacion` TIMESTAMP NOT NULL DEFAULT CURRENT\_TIMESTAMP, -- 🕒 Fecha y hora de publicación `contenido` TEXT NOT NULL, -- 📄 Contenido del post `estatus` CHAR(8) CHECK (estatus IN ('activo', 'inactivo')) NOT NULL, -- ✅ Estado del post (activo o inactivo) `usuarios\_id` INT NOT NULL, -- 👤 Referencia al usuario que creó el post `categorias\_id` INT NOT NULL, -- 📂 Referencia a la categoría del post PRIMARY KEY (`id`), -- 🔑 Llave primaria FOREIGN KEY (`usuarios\_id`) REFERENCES `usuarios`(`id`), -- 🔗 Relación con la tabla usuarios FOREIGN KEY (`categorias\_id`) REFERENCES `categorias`(`id`) -- 🔗 Relación con la tabla categorías ); \-- 💬 Tabla de Comentarios CREATE TABLE `platziblog`.`comentarios` ( `id` INT NOT NULL AUTO\_INCREMENT, -- 🔑 ID único para cada comentario `comentario` TEXT NOT NULL, -- 💬 Texto del comentario `usuarios\_id` INT NOT NULL, -- 👤 Usuario que dejó el comentario `posts\_id` INT NOT NULL, -- 📝 Post al que pertenece el comentario PRIMARY KEY (`id`), -- 🔑 Llave primaria FOREIGN KEY (`usuarios\_id`) REFERENCES `usuarios`(`id`), -- 🔗 Relación con la tabla usuarios FOREIGN KEY (`posts\_id`) REFERENCES `posts`(`id`) -- 🔗 Relación con la tabla posts ); \-- 🔖 Tabla de Etiquetas CREATE TABLE `platziblog`.`etiquetas` ( `id` INT NOT NULL AUTO\_INCREMENT, -- 🔑 ID único para cada etiqueta `nombre\_etiqueta` VARCHAR(30) NOT NULL, -- 🔖 Nombre de la etiqueta PRIMARY KEY (`id`) -- 🔑 Llave primaria ); \-- 🌐 Tabla Intermedia: Posts\_Etiquetas (Relación Muchos a Muchos) CREATE TABLE `platziblog`.`posts\_etiquetas` ( `posts\_id` INT NOT NULL, -- 📝 Post relacionado `etiquetas\_id` INT NOT NULL, -- 🔖 Etiqueta relacionada FOREIGN KEY (`posts\_id`) REFERENCES `posts`(`id`), -- 🔗 Relación con la tabla posts FOREIGN KEY (`etiquetas\_id`) REFERENCES `etiquetas`(`id`), -- 🔗 Relación con la tabla etiquetas PRIMARY KEY (`posts\_id`, `etiquetas\_id`) -- 🔑 Llave primaria compuesta );
Para estas clases donde se explican ejemplos que resultan bastante específicos en la aplicación y en las cuales no hay tanto contenido recomiendo poner la velocidad en 1.25. El profe es excelente explicando y por eso tiene un ritmo que ayuda mucho cuando desarrolla, pero que quizás resulta un poco lento a la hora de los ejemplos. 😊🚀💪
Lo hice a partir de codigo en SQL server de la siguiente forma, seguramente contenga errores: ```js CREATE TABLE categorias( id INT PRIMARY KEY NOT NULL IDENTITY(1,1), nombre_categoria VARCHAR(40) NOT NULL ); CREATE TABLE usuarios( id INT PRIMARY KEY NOT NULL IDENTITY(1,1), [login] VARCHAR(30) NOT NULL, [password] VARCHAR(32) NOT NULL, nickname VARCHAR(30) NOT NULL, email VARCHAR(40) NOT NULL UNIQUE ); CREATE TABLE posts( id INT PRIMARY KEY NOT NULL IDENTITY(1,1), fecha_publicacion TIMESTAMP, contenido TEXT NOT NULL, estatus CHAR(8) DEFAULT 'activo', usuario_id INT NOT NULL, categoria_id INT NOT NULL, FOREIGN KEY (usuario_id) REFERENCES usuarios(id) ON UPDATE CASCADE ON DELETE NO ACTION, FOREIGN KEY (categoria_id) REFERENCES categorias(id) ); CREATE TABLE comentarios( id INT PRIMARY KEY NOT NULL, comentario TEXT, usuario_id INTEGER, post_id INTEGER, FOREIGN KEY (usuario_id) REFERENCES usuarios(id), FOREIGN KEY (post_id) REFERENCES posts(id) ); ```CREATE TABLE categorias( id INT PRIMARY KEY NOT NULL IDENTITY(1,1), nombre\_categoria VARCHAR(40) NOT NULL ); CREATE TABLE usuarios( id INT PRIMARY KEY NOT NULL IDENTITY(1,1), \[login] VARCHAR(30) NOT NULL, \[password] VARCHAR(32) NOT NULL, nickname VARCHAR(30) NOT NULL, email VARCHAR(40) NOT NULL UNIQUE ); CREATE TABLE posts( id INT PRIMARY KEY NOT NULL IDENTITY(1,1), fecha\_publicacion TIMESTAMP, contenido TEXT NOT NULL, estatus CHAR(8) DEFAULT 'activo', usuario\_id INT NOT NULL, categoria\_id INT NOT NULL, FOREIGN KEY (usuario\_id) REFERENCES usuarios(id) ON UPDATE CASCADE ON DELETE NO ACTION, FOREIGN KEY (categoria\_id) REFERENCES categorias(id) ); CREATE TABLE comentarios( id INT PRIMARY KEY NOT NULL, comentario TEXT, usuario\_id INTEGER, post\_id INTEGER, FOREIGN KEY (usuario\_id) REFERENCES usuarios(id), FOREIGN KEY (post\_id) REFERENCES posts(id) );
Chicos a alguno le ha aparecido este error, que puedo hacer para corregirlo, hasta el momento venia trabajando bien siguiendo la clase, pero hoy me apareció este error, agradezco si alguno sabe como solucionarlo. ![](https://static.platzi.com/media/user_upload/image-7b9e7328-f304-4425-9e02-a85c35347d3c.jpg)
Alguien sabe porque usa CHAR(8) ???? PORQUE EL NUMERO 8
buenos recursos
esta es la ingeniería inversa de mi base de datos para una página de compra venta de autos usados: ![](https://static.platzi.com/media/user_upload/image-c05dede4-a5a3-47c0-a5dd-2bed2a5fd010.jpg)
En la version que tengo no he logrado conseguir donde se visualiza el código SQL, (applying SQL script to database) ![](https://static.platzi.com/media/user_upload/image-25b8f181-71a8-4f47-89c1-e257c5f6731b.jpg)
* El orden en que se deben crear las tablas dependientes debe ser tomando en cuenta las tablas que ya se han creado, ya no se recomienda crear un tabla dependiente de otra que todavía no se ha creado * Para crear un vínculo con los id de otras tablas hay que ir a Foreing Keys donde vamos a dar un nombre a esa llave foránea, referenciamos la tabla y ligamos la columna creada para recibir la información con la columna de la llave principal * Hay opciones que nos permiten decidir que hacer cuando se actualice la tabla o cuando se borre * CASCADE va permitir que se actualice la información en todas las tablas * SET NULL va a dejar sin información a la tabla * NO ACTION no va a realizar ninguna acción * RESTRICT no se puede hacer una acción hasta que esta no afecte a la tabla actual 📌 **RESUMEN: Para ligar los id de llaves primarias a otra tabla como llaves foráneas, se realiza en la pestaña de Foreign Keys donde se crean las tablas**
# **Tablas Dependientes y Opciones de Claves Foráneas en SQL** **Tablas Dependientes:** * En bases de datos SQL, las "tablas dependientes" se refieren a aquellas que están vinculadas a otras mediante claves foráneas. * Establecen una relación de dependencia con otra tabla, donde la primera tiene una columna que referencia la clave principal de la segunda. **Claves Foráneas (Foreign Keys):** * Restricciones aplicadas a una columna o conjunto de columnas en una tabla. * Se utilizan para establecer relaciones entre datos en una tabla y datos en otra. **Opciones de Clave Foránea:** 1. **ON DELETE:** * **CASCADE:** Elimina automáticamente filas correspondientes en la tabla secundaria al eliminar una fila en la tabla principal. * **SET NULL:** Establece en NULL los valores de las columnas correspondientes en la tabla secundaria al eliminar una fila en la tabla principal. * **SET DEFAULT:** Similar a SET NULL, pero establece los valores en el valor predeterminado definido. * **NO ACTION/RESTRICT:** No permite la eliminación si hay filas dependientes. 2. **ON UPDATE:** * **CASCADE:** Actualiza automáticamente las claves foráneas en la tabla secundaria al actualizar la clave principal. * **SET NULL:** Similar a ON DELETE SET NULL, pero para actualizaciones. * **SET DEFAULT:** Similar a ON DELETE SET DEFAULT, pero para actualizaciones. * **NO ACTION/RESTRICT:** No permite la actualización si hay claves foráneas correspondientes. Estas opciones aseguran la integridad referencial y mantienen la coherencia de los datos en la base de datos.
Cuando comencé a usar ORMs noté que no había llaves foraneas, y con esta clase veo que es porque hoy en día no hay deletes solo soft deletes por lo que no es realmente necesario un cascade.

Estas opciones permiten definir el comportamiento de las relaciones en la base de datos en función de las actualizaciones y eliminaciones, lo que ayuda a mantener la integridad referencial de la base de datos.

En actualización :

Cascada :

  • Si el valor de la clave primaria se actualiza, los valores en las tablas relacionadas también se actualizan automáticamente. Por ejemplo, si el ID de un usuario pasa de 11 a 12, todos los registros relacionados con ese usuario se actualizarán con el nuevo ID.

Restringir :

  • No se permite actualizar el valor de la clave primaria hasta que se hayan actualizado todos los registros relacionados. Por ejemplo, si intentas cambiar el ID de un usuario de 11 a 12 y existen registros relacionados, no se permitirá la actualización hasta que esos registros se actualicen o eliminen.

Set null :

  • Si el valor de la clave primaria se actualiza, los registros relacionados tendrán sus campos relacionados establecidos en nulo. Por ejemplo, si el ID de un usuario se actualiza de 11 a 12, los registros relacionados tendrán el campo de usuario establecido en nulo.

Sin acción :

  • No se realizará ninguna acción automáticamente. Solo se romperá la relación si la actualización no es válida. Por ejemplo, si intentas actualizar el ID de un usuario de 11 a 12 y existen registros relacionados, se producirá un error y la relación se romperá.

Al eliminar :

Cascada :

  • Si un registro relacionado se elimina, todos los registros relacionados en otras tablas también se eliminarán automáticamente. Por ejemplo, si elimina un usuario, se borrarán todos los registros relacionados con ese usuario en otras tablas.

Restringir :

  • No se permite eliminar el registro relacionado hasta que se hayan eliminado todos los registros relacionados en otras tablas. Por ejemplo, si intentas eliminar un usuario y existen registros relacionados en otras tablas, no se permitirá la eliminación hasta que esos registros se eliminen.

Establecer nulo :

  • Si un registro relacionado se elimina, los campos relacionados en otros registros se establecerán en nulo. Por ejemplo, si elimina un usuario, los registros relacionados tendrán el campo de usuario establecido en nulo.

Sin acción :

  • No se realizará ninguna acción automáticamente al eliminar un registro relacionado. Solo se romperá la relación si la eliminación no es válida. Por ejemplo, si intentas eliminar un usuario y existen registros relacionados en otras tablas, se producirá un error y la relación se romperá.
Si decido crear la tabla post desde cero solo usando la sintaxis de SQL seria así: `CREATE TABLE post (` `id int auto_increment not null,` `post_title VARCHAR(150) not null,` `post_date TIMESTAMP ,` `coten TEXT not null,` `status VARCHAR(8) DEFAULT 'activo',` `user_id int not null,` `category_id int not null,` `primary key (id),` `foreign key(user_id) REFERENCES TheBlog.user(id)` `ON DELETE NO ACTION` `ON UPDATE CASCADE,` `foreign key(category_id) REFERENCES TheBlog.category(id_category)` `ON DELETE NO ACTION` `ON UPDATE NO ACTION);`

Me gustó mucho esta clase…!