Relacionamentos no Banco de Dados
Entender relacionamentos é fundamental para modelar dados corretamente.
Tipos de Relacionamentos
1:1 (Um para Um)
prisma
model User { id String @id @default(uuid()) profile Profile?} model Profile { id String @id @default(uuid()) bio String? avatar String? userId String @unique user User @relation(fields: [userId], references: [id])}typescript
// Criar com relacionamentoconst user = await prisma.user.create({ data: { email: 'joao@email.com', profile: { create: { bio: 'Dev Backend' } } }, include: { profile: true }});1:N (Um para Muitos)
prisma
model User { id String @id @default(uuid()) orders Order[]} model Order { id String @id @default(uuid()) userId String user User @relation(fields: [userId], references: [id])}typescript
// Buscar usuário com pedidosconst user = await prisma.user.findUnique({ where: { id }, include: { orders: { orderBy: { createdAt: 'desc' }, take: 10 } }}); // Criar pedido para usuárioconst order = await prisma.order.create({ data: { user: { connect: { id: userId } }, total: 199.99 }});N:N (Muitos para Muitos)
Implícito:
prisma
model Product { id String @id tags Tag[]} model Tag { id String @id products Product[]}Explícito (com dados extras):
prisma
model Product { id String @id categories ProductCategory[]} model Category { id String @id products ProductCategory[]} model ProductCategory { productId String categoryId String featured Boolean @default(false) order Int @default(0) product Product @relation(fields: [productId], references: [id]) category Category @relation(fields: [categoryId], references: [id]) @@id([productId, categoryId])}Queries com Relacionamentos
Include (Eager Loading)
typescript
const product = await prisma.product.findUnique({ where: { id }, include: { category: true, reviews: { include: { user: { select: { name: true } } }, where: { rating: { gte: 4 } }, take: 5 } }});Select (Campos específicos)
typescript
const products = await prisma.product.findMany({ select: { id: true, name: true, price: true, category: { select: { name: true } }, _count: { select: { reviews: true } } }});Nested Writes
typescript
// Criar produto com categoria e reviewsconst product = await prisma.product.create({ data: { name: 'Notebook Pro', price: 4999.99, category: { connectOrCreate: { where: { slug: 'eletronicos' }, create: { name: 'Eletrônicos', slug: 'eletronicos' } } }, reviews: { create: [ { userId: 'user1', rating: 5, comment: 'Excelente!' } ] } }});Cascading
prisma
model User { orders Order[] // onDelete padrão: SetNull} model Order { user User @relation(fields: [userId], references: [id], onDelete: Cascade)}Opções: Cascade, SetNull, Restrict, NoAction
Self-Relations
prisma
model Category { id String @id parentId String? parent Category? @relation("CategoryHierarchy", fields: [parentId], references: [id]) children Category[] @relation("CategoryHierarchy")}typescript
// Buscar categoria com subcategoriasconst categories = await prisma.category.findMany({ where: { parentId: null }, include: { children: { include: { children: true } } }});Resumo
- ✅ Relacionamentos 1:1, 1:N, N:N
- ✅ Include e Select para carregar dados
- ✅ Nested writes para criar relacionados
- ✅ Cascading para deletar relacionados
- ✅ Self-relations para hierarquias
Próxima aula: Autenticação com JWT! 🔐