개발자공부일기
자바스크립트에서 데이터 N중참조 본문
개발 하는중에 데이터의 n중참조할일이 생겼는데 뭔가 은근히 헷갈리는게 확실히 하고 싶어서 알아봤다.
N중 참조는 데이터베이스에서 하나의 테이블이 다른 테이블을 참조하고, 그 참조된 테이블이 다시 다른 테이블을 참조하는 관계를 의미합니다. 이런 관계는 특히 데이터가 여러 단계로 연결되어 있을 때 유용하게 사용됩니다.
이제 각 단계를 좀 더 자세히 설명하고, 이를 JavaScript와 Prisma를 활용해 어떻게 구현하는지 하나씩 살펴보겠습니다.
1. 외래 키 관계 기본 개념
외래 키 (Foreign Key)
외래 키는 한 테이블의 필드가 다른 테이블의 기본 키를 참조하는 관계입니다. 예를 들어, User 테이블에 departmentId라는 필드가 있다고 할 때, 이 필드는 Department 테이블의 id를 참조하는 외래 키입니다.
N중 참조 (Multiple Foreign Key Relationships)
N중 참조는 여러 단계에 걸쳐 참조가 이루어지는 구조입니다. 예를 들어, User가 Department를 참조하고, Department는 Company를 참조하며, Company는 Region을 참조하는 경우를 생각해 볼 수 있습니다. 이를 통해 사용자는 간접적으로 Region까지 참조하게 됩니다.
2. Prisma에서 N중 참조 관계 설정
Prisma에서 여러 테이블 간의 N중 참조 관계를 설정하려면, 각 모델에 @relation을 명시적으로 연결해야 합니다. 이를 통해 Prisma가 관계를 추적하고, 우리가 원하는 데이터를 쉽게 쿼리할 수 있도록 도와줍니다.
예시: User, Department, Company, Region 모델 설정
우리는 네 개의 모델 (User, Department, Company, Region) 간에 외래 키 관계를 설정하고, 이를 통해 User와 관련된 모든 정보를 조회할 수 있는 API를 만들 것입니다.
1. schema.prisma 설정
model Region {
id Int @id @default(autoincrement()) // 지역 ID
name String // 지역 이름
companies Company[] // 하나의 지역에는 여러 회사가 있을 수 있음
}
model Company {
id Int @id @default(autoincrement()) // 회사 ID
name String // 회사 이름
regionId Int // 지역 ID (외래 키)
region Region @relation(fields: [regionId], references: [id]) // 회사는 하나의 지역에 속함
departments Department[] // 회사는 여러 부서를 가질 수 있음
}
model Department {
id Int @id @default(autoincrement()) // 부서 ID
name String // 부서 이름
companyId Int // 회사 ID (외래 키)
company Company @relation(fields: [companyId], references: [id]) // 부서는 하나의 회사에 속함
users User[] // 부서는 여러 명의 사용자를 가질 수 있음
}
model User {
id Int @id @default(autoincrement()) // 사용자 ID
name String // 사용자 이름
departmentId Int // 부서 ID (외래 키)
department Department @relation(fields: [departmentId], references: [id]) // 사용자는 하나의 부서에 속함
}
위 설정에서 중요한 점은 **@relation**을 사용하여 각 테이블 간의 관계를 명시적으로 정의한 것입니다. User -> Department -> Company -> Region 순으로 외래 키가 설정됩니다.
3. 관계 설명
1) User -> Department
- User는 Department에 속합니다. 즉, 각 사용자는 하나의 부서에 속하며, departmentId 필드로 외래 키 관계가 설정됩니다.
2) Department -> Company
- 각 Department는 하나의 Company에 속합니다. 즉, 부서는 하나의 회사에 속하며, companyId 필드로 외래 키 관계가 설정됩니다.
3) Company -> Region
- 각 Company는 하나의 Region에 속합니다. 즉, 회사는 하나의 지역에 속하며, regionId 필드로 외래 키 관계가 설정됩니다.
이렇게 User는 Department, Department는 Company, Company는 Region과 관계를 가지게 됩니다. 결국 User는 간접적으로 Region에 속하게 됩니다.
4. N중 참조 예시
이제 이 관계를 사용해서 User에 대한 정보를 요청할 때, User가 속한 Department, Department가 속한 Company, Company가 속한 Region 정보를 함께 반환하는 API를 만들어 보겠습니다.
1) Node.js API 코드 (Express + Prisma)
const express = require('express');
const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
const app = express();
const port = 3000;
// JSON 요청을 받을 수 있도록 설정
app.use(express.json());
// 특정 사용자의 부서, 회사, 지역 정보 조회 API
app.get('/user/:id', async (req, res) => {
const userId = parseInt(req.params.id);
try {
const user = await prisma.user.findUnique({
where: { id: userId },
include: {
department: {
include: {
company: {
include: {
region: true, // 회사가 속한 지역까지 포함
},
},
},
},
},
});
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.json(user); // 사용자의 부서, 회사, 지역 정보를 포함한 응답
} catch (error) {
res.status(500).json({ error: 'Internal server error' });
}
});
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
});
설명:
- GET /user/:id: 사용자의 정보를 조회하면서, 그 사용자가 속한 부서와 그 부서가 속한 회사, 회사가 속한 지역 정보를 함께 조회합니다.
- findUnique 메서드로 사용자를 찾고, include 옵션을 사용해 그와 관련된 부서, 회사, 지역까지 모두 조회합니다.
- department, company, region을 순차적으로 include 하여, 사용자의 부서, 그 부서가 속한 회사, 회사가 속한 지역까지 모두 반환합니다.
예시 응답:
{
"id": 1,
"name": "John Doe",
"department": {
"id": 2,
"name": "Engineering",
"company": {
"id": 3,
"name": "Tech Corp",
"region": {
"id": 1,
"name": "North America"
}
}
}
}
위와 같은 방식으로, User를 기준으로 Department, Company, Region까지의 관계를 탐색하고, 그 관계를 바탕으로 사용자가 속한 부서, 회사, 지역 정보를 동시에 반환할 수 있습니다.
5. 결론
- N중 참조는 여러 테이블 간의 외래 키 관계가 여러 단계에 걸쳐 이루어지는 경우를 의미합니다.
- Prisma에서 @relation을 사용하여 각 모델 간의 관계를 설정하고, include 옵션을 사용하여 다단계로 연결된 데이터를 한 번에 조회할 수 있습니다.
- 이 방식은 데이터베이스 모델링과 API 설계에서 매우 유용하게 활용될 수 있습니다.
위 예시처럼 여러 모델 간의 관계를 잘 정의하고, 필요에 따라 다단계 참조를 활용하면 효율적인 데이터 처리가 가능합니다.
'TIL(Today I Learned)' 카테고리의 다른 글
reduce의 다양한 쓰임새 (0) | 2024.12.06 |
---|---|
공통 테이블 표현식(CTE, Common Table Expression) (0) | 2024.12.05 |
데이터베이스 정규화 (0) | 2024.12.03 |
RESTful API (0) | 2024.12.02 |
DOM의 개념과 메서드들 (0) | 2024.11.29 |