지금은 개나소나 모든 글을 삭제할 수 있습니다.
그건 싫고 글을 쓴 주인만 삭제가 가능하게 만들고 싶습니다.
하지만 그 전에 이 글을 누가 썼는지 지금 아무도 모르는데요?
그럼 어떡하지 하면서 손가락 빨고 있는게 아니라
그래서 글 발행시 작성자의 이름이나 _id 같은 것도 기록해두도록 합시다.
글 발행 기능을 업그레이드하자
글 발행할 때 지금은 title, content 이정도만 기록하고 있는데
여기다가 현재 로그인한 유저의 _id와 username을 기록해둡시다.
app.post('/add', upload.single('img1'), async (요청, 응답) => {
await db.collection('post').insertOne(
{
title : 요청.body.title,
content : 요청.body.content,
user : 현재 로그인된 유저의 _id,
username : 현재 로그인된 username 같은거
}
)
(생략)
})
그럼 /add API의 .insertOne에다가 정보를 추가해봅시다.
위의 2개 정보는 어디있습니까?
서버에 없으면 유저에게 보내라고 해도 됩니다.
하지만 유저가 보내는 모든 정보는 위조할 수 있기 때문에 유저정보같은 것은 요청.user 출력해보는게 가장 좋습니다.
user : 요청.user._id,
username : 요청.user.username
그래서 이렇게 저장하면 됩니다.
비정규화
여기서 질문이 하나 있을 수 있는데
username같은걸 여기 집어넣으면 나중에 문제가 될 수도 있는거 아닙니까?
나중에 유저가 심심해서 username을 변경해버리면 어쩌죠?
예를 들어 username이 kim인 유저가 글을 10000개 썼는데
유저가 갑자기 설정들어가서 username을 kim2로 바꾼겁니다.
그럼 글에 적혀있던 username : kim 부분도 kim2로 전부 수정해야하는거 아닙니까?
그래야 합니다.
▲ 그래서 SQL쓰는 관계형 DB들은 이런 문제를 어떤 식으로 해결하냐면
글을 발행할 때 유저이름을 넣지 않고 아니라 유저 document의 _id 같은 것만 적어둡니다.
그런건 바뀔 일이 아예 없으니까요.
그리고 나중에 글과 유저이름이 동시에 필요해지면 JOIN 문법같은걸 써서 유저이름이랑 글을 합쳐서 가져옵니다.
이런 식으로 서로 주제가 관련없는 데이터들은 철저하게 구분지어서 저장하는걸 멋있는 말로 정규화라고 합니다.
▲ 반면에 Mongodb같은 비관계형 데이터베이스들은 정규화 그런거 보통 안합니다.
그냥 유저 이름도 글 document에 대충 작성해버리는게 좋은 관습입니다.
이걸 비정규화라고 합니다.
장점은 그냥 글만 꺼내면 유저이름도 들어있어서 매우 빠르게 모든 정보를 꺼내올 수 있습니다.
정규화 장점 :
- 정보들이 정확함
- 입출력이 느림
비정규화 장점 :
- 정보들이 부정확함
- 입출력이 빠름
그래서 위 중에 택1 하면 되겠습니다. 언제나 장점이 있으면 단점도 있음
MongoDB는 비정규화를 권장하는 DB입니다.
지금 만드는 게시판도 잘 생각해보면 데이터 정확도가 크게 필요없죠?
이름 조금 틀려도 크게 상관없는 것 아닙니까
물론 비정규화해놔도 아주 정확하게 이름을 가져와야할 때는
- 글 document랑 유저 document 전부 가져오라고 코드 두 줄 짜거나
- document 2개를 이어붙이는 $lookup 연산자 쓰거나
느린거 감수하고 그런 식으로 써도 상관은 없습니다.
삭제기능 수정
이제 글발행할 때 마다 글쓴이의 _id랑 username도 함께 저장이 되는데
그럼 본인이 쓴 글만 삭제가능하게 하고 싶으면 어떻게 하죠?
app.delete('/delete', async (요청, 응답)=>{
await db.collection('post').deleteOne({
_id : new ObjectId(요청.query.docid),
user : 지금 로그인중인 유저의 _id
})
응답.send('삭제완료')
})
/delete 기능개발한 곳에다가 이렇게 적으면
1. _id : 유저가보낸 글 _id
2. user : 지금 로그인중인 유저의 _id
이거 2개가 일치하는 document만 삭제해줍니다.
지금 로그인중인 유저의 _id가 어딨냐고요?
그걸 저에게 물어보면 안됩니다.
잘 채워넣으시고 진짜 본인 글만 삭제되는지 테스트도 해봅시다.
그래서 오늘 배운거 :
1. Mongodb는 보통 입출력속도를 빠르게하려고 비정규화하는 DB임
2. 요청.user 안에 유저정보 들어있다는것만 잘 알고계시면 회원관련 기능들은 쉽게 알아서 만들 수 있음
그래서 의존 그만하고 알아서 대가리를 써서 회원기능이 들어간 게시판을 이거저거 만들어봅시다.
해보라고 하면 안하는 분들을 위해 제안을 드리자면
Q1. 본인이 쓴 글만 수정할 수 있게?
오늘 한거랑 비슷할 것 같군요.
Q2. 본인이 쓴 글에만 삭제버튼을 보여주려면?
그건 그냥 글에 적힌 작성자 _id가 내 _id랑 같으면 삭제버튼 보여달라고 html에다가 if문 쓰면 됩니다.
ejs 파일에 유저정보가 없다고요?
여러분들이 개발자인데 수동적으로 손가락 빨고있지 말고 서버에서 보내주면 되는 것 아닙니까.
심심하면 해보도록 합시다.
Q3. 삭제가 성공했을 때만 html을 안보이게 처리하려면?
지금은 삭제 ajax 요청시 성공/실패 상관없이 html을 숨겨주고 있습니다.
'Node.js' 카테고리의 다른 글
node>Node+Express 서버와 React 연동하려면 (1) | 2024.09.19 |
---|---|
node>댓글기능 만들기 (document간의 종속) (0) | 2024.09.19 |
node>검색기능 만들기 3 (search index) (0) | 2024.09.19 |
node>검색기능 만들기 2 (index 설명) (0) | 2024.09.19 |
node>검색기능 만들기 1 (0) | 2024.09.19 |