Pular para o conteúdoPedro Farbo
Lição 11 / 2545 min

Relacionamentos no Banco de Dados

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! 🔐

Gostou do conteúdo? Sua contribuição ajuda a manter tudo online e gratuito!

PIX:0737160d-e98f-4a65-8392-5dba70e7ff3e