Relaciones Bases de Datos Relacionales: Sequelize y Express

Relaciones Bases de Datos Relacionales: Sequelize y Express

Tipos de Relaciones en Bases de Datos Relacionales: Implementación Práctica con Sequelize y Express

MANEJO DE BASE DE DATOS: 2011

¿Alguna vez te has preguntado cómo conectar tablas en una base de datos para construir aplicaciones complejas? Las relaciones entre tablas son la columna vertebral de las bases de datos relacionales. En este post, exploraremos los tres tipos de relaciones (uno a uno, uno a muchos y muchos a muchos) y cómo implementarlas paso a paso usando Sequelize en Express, con ejemplos prácticos y casos reales.

Tipos de Relaciones y Casos de Uso Reales

1. Relación Uno a Uno (1:1)

Definición: Un registro en una tabla se relaciona con un solo registro en otra tabla.

Caso real:

  • Usuario y Perfil: Cada usuario tiene un único perfil con datos adicionales (ej: biografía, avatar).

Implementación con Sequelize

Paso 1: Definir los modelos User y Profile.

				
					// models/User.js
const { Model, DataTypes } = require('sequelize');
const sequelize = require('../config/database');

class User extends Model {}
User.init({
  email: { type: DataTypes.STRING, unique: true },
  password: DataTypes.STRING,
}, { sequelize, modelName: 'user' });

module.exports = User;

// models/Profile.js
class Profile extends Model {}
Profile.init({
  bio: DataTypes.TEXT,
  avatarUrl: DataTypes.STRING,
  userId: DataTypes.INTEGER, // Clave foránea
}, { sequelize, modelName: 'profile' });

module.exports = Profile;

				
			

Paso 2: Establecer la relación en index.js (o donde inicialices los modelos):

				
					const User = require('./models/User');
const Profile = require('./models/Profile');

// Un usuario tiene un perfil
User.hasOne(Profile, { foreignKey: 'userId' });
// Un perfil pertenece a un usuario
Profile.belongsTo(User, { foreignKey: 'userId' });
				
			

Paso 3: Crear un usuario y su perfil:

				
					const user = await User.create({ email: 'ana@example.com', password: '123' });
const profile = await Profile.create({ bio: 'Desarrolladora backend', userId: user.id });
				
			

2. Relación Uno a Muchos (1:N)

Definición: Un registro en una tabla puede relacionarse con múltiples registros en otra tabla.

Caso real:

  • Blog y Posts: Un blog puede tener muchos posts, pero cada post pertenece a un solo blog.

Implementación con Sequelize

Paso 1: Modelos Blog y Post.

				
					// models/Blog.js
class Blog extends Model {}
Blog.init({
  name: DataTypes.STRING,
}, { sequelize, modelName: 'blog' });

// models/Post.js
class Post extends Model {}
Post.init({
  title: DataTypes.STRING,
  content: DataTypes.TEXT,
  blogId: DataTypes.INTEGER, // Clave foránea
}, { sequelize, modelName: 'post' });
				
			

Paso 2: Definir la relación:

				
					// models/Blog.js
class Blog extends Model {}
Blog.init({
  name: DataTypes.STRING,
}, { sequelize, modelName: 'blog' });

// models/Post.js
class Post extends Model {}
Post.init({
  title: DataTypes.STRING,
  content: DataTypes.TEXT,
  blogId: DataTypes.INTEGER, // Clave foránea
}, { sequelize, modelName: 'post' });
				
			

Paso 3: Crear un blog con posts asociados:

				
					const blog = await Blog.create({ name: 'Tecnología' });
const post1 = await Post.create({ title: 'Node.js', blogId: blog.id });
const post2 = await Post.create({ title: 'Express', blogId: blog.id });

				
			

Consulta con joins:

				
					const blogWithPosts = await Blog.findOne({
  where: { id: 1 },
  include: Post, // Incluye todos los posts del blog
});
				
			

3. Relación Muchos a Muchos (N:M)

Definición: Múltiples registros en una tabla se relacionan con múltiples registros en otra tabla, usando una tabla intermedia.

Caso real:

  • Estudiantes y Cursos: Un estudiante puede inscribirse en varios cursos, y un curso puede tener muchos estudiantes.

Implementación con Sequelize

Paso 1: Modelos Student y Course, más la tabla intermedia StudentCourse.

				
					// models/Student.js
class Student extends Model {}
Student.init({
  name: DataTypes.STRING,
}, { sequelize, modelName: 'student' });

// models/Course.js
class Course extends Model {}
Course.init({
  name: DataTypes.STRING,
}, { sequelize, modelName: 'course' });

// Tabla intermedia (automática con through)

				
			

Paso 2: Definir la relación usando belongsToMany:

				
					Student.belongsToMany(Course, { through: 'StudentCourse' });
Course.belongsToMany(Student, { through: 'StudentCourse' });

				
			

Paso 3: Crear registros y asociarlos:

				
					const ana = await Student.create({ name: 'Ana' });
const cursoNode = await Course.create({ name: 'Node.js' });
const cursoReact = await Course.create({ name: 'React' });

// Ana se inscribe en dos cursos
await ana.addCourses([cursoNode, cursoReact]);

				
			

Consulta para obtener cursos de un estudiante:

				
					const estudiante = await Student.findOne({
  where: { id: 1 },
  include: Course, // Trae todos los cursos asociados
});
				
			

Tabla Comparativa: Tipos de Relaciones

TipoCaso de UsoEjemplo SequelizeTabla Intermedia
1:1Usuario-PerfilhasOne + belongsToNo
1:NBlog-PostshasMany + belongsToNo
N:MEstudiantes-CursosbelongsToMany (automática)
 

Errores Comunes y Cómo Evitarlos

  1. Olvidar claves foráneas:

    • Asegúrate de incluir campos como userId o blogId en tus modelos.

  2. No definir relaciones bidireccionales:

    • Si usas hasMany, define también belongsTo en el modelo hijo.

  3. Ignorar opciones de cascada:

    • Ejemplo: onDelete: 'CASCADE' para eliminar registros hijos automáticamente.

Conclusión

Las relaciones en bases de datos son esenciales para modelar datos complejos en aplicaciones reales. Con Sequelize y Express, puedes implementar estos patrones de manera eficiente:

  • Usa hasOne y belongsTo para relaciones 1:1.

  • Aplica hasMany + belongsTo para 1:N.

  • Opta por belongsToMany con tablas intermedias para N:M.

Desafío práctico: Crea una API para una tienda online donde:

  • Un Producto pertenece a una Categoría (1:N).

  • Un Pedido puede incluir múltiples Productos (N:M).
    ¡Comparte tu solución en los comentarios!

Links de referencia: 

Facebook
X
LinkedIn
Reddit
Pinterest
Threads

Post relacionados

Post recientes

Search