DB에서 구현하는 경우는 성능 관점에서 종종 이점이 있는데, 대량 데이터에 접근하고 처리해야되면서 네트워크 타고 오가기에는 느리거나 부담이 될때 유용하고, 컴파일된 프로시져를 쓰는게 어플리케이션 구현보다 빨라서 좋을 수도 있어요. (후자는 요즘 트렌드는 아니지만요 ㅋㅋㅋ)
그리고 C로 개발하시던 분들은 종종 C에서 디버깅하기에 불편함이 많다보니 DB에서 데이터 바로 조회하면서 하기 편해서 비즈니스 로직들까지 어플리케이션 레이어가 아니라 DB레이어에서 작업한 경우도 있으신것 같더라구요.
하지만 그러한 챌린지가 없는 경우에는 아무래도 소스코드 관리 및 역할의 분리, 확장성 등을 고려해서 서버에서 구현하는게 일반적이긴 합니다.
백갤러 1(14.52)2025-05-10 22:51
답글
되게 깔끔하게 잘 설명했노 ㄷㄷ
김대기(waitkim)2025-05-11 01:12
답글
궁금한 점 있어요예를 들어, 중복저장을 할 수 없다는 요구사항에서응용레벨에서 exists로 확인 후, insert vs 테이블에 unique 걸고 insert이게 전자는 쿼리 2번으로 인한 네트워크 오가는 시간 + db 디스크 스캔 및 I/O 거기다가 read에 따른 write 연산이 필요하니 동시성 처리도 해야할 것 같은데후자로 처리하면 쿼리 한 번이니깐 성능상 이점이 있을 것 같은데앞서 말해주신 소스코드 관리 및 역할의 분리, 확장성 등이 이 성능에서 얻는 이점보다 메리트가 큰 건가요?또 여기서 발생하는 성능이슈는 큰 트래픽에도 크게 문제되는 수준이 아닌가요 ?
백갤러 2(14.6)2025-05-11 03:56
답글
@백갤러2(14.6)
이거 왜 개행이 안되노 ㅅㅂ
백갤러 2(14.6)2025-05-11 03:57
답글
@백갤러2(14.6)
말씀하신 케이스가 적절한 문제 포인트입니다. 일반적인 OLTP 서비스에서는 큰 문제는 안되는데요. (어차피 대부분의 서비스에서 read는 일상이니까요)
몇몇 케이스에서는 DB구현에 의존해야될 때 가 있습니다.
하나는 짧은 시간내의 큰 트래픽 혹은 벌크 처리이면서 레이턴시 크리티컬한 요건이 주어졌을 때 read 후 insert가 느리다면 최적화를 위해 추상화 레벨을 낮추고 뚫어야하는게 맞다고 생각되구요.
또 다른건 DBMS 구현 자체가 썩 나이스하지 않아 타협을 보는 케이스도 있습니다.
백갤러 1(14.52)2025-05-11 09:32
답글
@백갤러2(14.6)
예를 들자면 MySQL에서 구현하려면 select 후 상위입찰 되면 안되니 select for update + repeatable read 를 사용하겠죠? 이 때, 조건에 맞는 행이 없다고 가정했을때 gap lock이 걸리면서 해당 구간 insert를 방지하는데, 문제는 gap lock을 이용한 특성상 논리적으로 상관없는 다른 insert 까지 방해하게 됩니다. 이건 좋지 않은 경우죠.
또한 오라클에서는 repeatable read가 없기때문에 select for update를 걸더라도 없는 행에는 아무런 영향이 없어 다른 세션이 상위입찰 할 수 있는데요. 이러면 결국 select 후 중복확인을 했으나 insert를 보장할 수 없게 되는거죠.
백갤러 1(14.52)2025-05-11 09:35
답글
@백갤러2(14.6)
그래서 오라클 커뮤니티쪽에서는 보통 그냥 insert 후 충돌을 발생시키도록 권장을 하는 모습인데요. (글쓴이님이 제시하신 후자의 방법)
이러한 MySQL, 오라클의 구현에 따라서 select에 대한 정보가 필요할때 종종(절대 많이 보지는 못했습니다.) select 후 insert 후 충돌 확인되면 다시 select 같은 패턴을 사용할 수 있는데 이게 참 ㅎㅎ.... 코드나 성능이 참 안타깝게 되죠.
그래서 위와 같이 할바에는 UK 잡아둔 상태에서 insert 먼저 때리는게 일반적이게 되는데요. 이러나 저러나 결국 코드 레벨에서는 DB 레벨에 대한 강한 가정을 두고 짜는 모양새가 됩니다.
백갤러 1(14.52)2025-05-11 09:45
답글
@백갤러2(14.6)
전자로 하면 select후 insert시 실패할 수 있다는 가정, 후자라면 insert시 중복이 안생기는 보장이 있다는 가정으로 말이죠.
하지만 보통 개념적으로 받아들이기 편하면서 성능도 낫고 보통 개발자라면 DB 테이블에 대한 제어 권한이 있기 때문에 후자를 선택하게 됩니다.(적어도 저는요~)
하지만 이제 DB니까 이런식으로 할 수 있는건데, 진짜 외부 API나 솔루션이라고 가정을 해보죠.
만약 정보 조회 후 insert 시 실패할 수 있으면서, insert시 중복 방지가 안되는건 어떻게 하실까요? 예를 들자면 전혀 UK가 아닐법한 조건이 비즈니스 규칙으로 있는거죠. 이름이 웅냐웅냐 라는 사람은 한번만 처리 할 수 있다.(유저 PK도 아니고 그냥 단순 정보의 일부같은 조건으로 생각해 주세요.)
백갤러 1(14.52)2025-05-11 09:54
답글
@백갤러2(14.6)
한번 생각해보시고, 구현도 직접 해보시는게 좋을 것 같습니다~ (여러 구현이 있을 수 있는데, 해답이 아예 불가능한 그런 질문은 아니예요)
백갤러 1(14.52)2025-05-11 09:55
답글
@백갤러1(14.52)
정리하자면, 소스코드 관리 및 역할의 분리, 확장성 등을 고려하여 일반적으로는 응용 레벨에서 구현한다.
1. 짧은 시간내의 큰 트래픽 혹은 벌크 처리이면서 레이턴시 크리티컬한 요건일 경우 발생할 수 있는 성능상의 문제
2. DBMS 구현으로 발생할 수 있는 성능상의 문제
가 크게 우려될 경우 DB레벨에서의 기능 구현을 고려해볼 수 있다.
백갤러 2(14.6)2025-05-11 13:58
답글
@백갤러2(14.6)
하지만 개발자가 컨트롤 할 수 없는 외부 api 등을 사용할 때는 응용 레벨에서 처리해야한다.
외부에 로직을 의존하는 건 성능상의 이슈가 있을 때 고려해볼만하다.
애초에 비즈니스 로직을 외부에 의존하는 것 부터, 변화에 유연하지 못하고 로직도 분산되서 좋지 않을 것 같네요.
덕분에 어느정도 정리가 됐습니다. 감사합니다.
백갤러 2(14.6)2025-05-11 14:01
답글
@백갤러2(14.6)
하나의 DB 스토리지에 의존하면 말씀하신 것처럼 확장성도 떨어지겠네요...
백갤러 2(14.6)2025-05-11 14:03
답글
@백갤러2(14.6)
음... 2. DBMS 구현으로 발생할 수 있는 성능상의 문제는 제가 의도한건 성능이라기 보다는 관리와 코드의 영향정도인데요.
저는 개발자가 제어할 수 있는 DB라면 보통 데이터 모델링을 하고 거기에 결국 비즈니스 규칙이 담기게 됩니다. 따라서 비즈니스의 모든 규칙을 코드에만 담는건 사실상 불가능하다고 생각하고 있어요. (어떤데이터든지 마음대로 받아주고 어떤 조건이든 원하는 속도대로 조회할 수 있는 만능 저장소 같은건 세상에 없잖아요?)
따라서 그러한 한계를 받아들이면서 DBMS를 잘 활용할 수 있을때는 활용하고, 아닐때는 아니라는 것에 가까웠습니다.
물론 이 기준점은 개발자마다 다른데요, 저는 주변 자원을 적극적으로 쓰는걸 선호하는 개발자라서 UK를 걸어서 해결되는 상황이면 그렇게 하고 끝낼것같아요.
DB에서 구현하는 경우는 성능 관점에서 종종 이점이 있는데, 대량 데이터에 접근하고 처리해야되면서 네트워크 타고 오가기에는 느리거나 부담이 될때 유용하고, 컴파일된 프로시져를 쓰는게 어플리케이션 구현보다 빨라서 좋을 수도 있어요. (후자는 요즘 트렌드는 아니지만요 ㅋㅋㅋ) 그리고 C로 개발하시던 분들은 종종 C에서 디버깅하기에 불편함이 많다보니 DB에서 데이터 바로 조회하면서 하기 편해서 비즈니스 로직들까지 어플리케이션 레이어가 아니라 DB레이어에서 작업한 경우도 있으신것 같더라구요. 하지만 그러한 챌린지가 없는 경우에는 아무래도 소스코드 관리 및 역할의 분리, 확장성 등을 고려해서 서버에서 구현하는게 일반적이긴 합니다.
되게 깔끔하게 잘 설명했노 ㄷㄷ
궁금한 점 있어요예를 들어, 중복저장을 할 수 없다는 요구사항에서응용레벨에서 exists로 확인 후, insert vs 테이블에 unique 걸고 insert이게 전자는 쿼리 2번으로 인한 네트워크 오가는 시간 + db 디스크 스캔 및 I/O 거기다가 read에 따른 write 연산이 필요하니 동시성 처리도 해야할 것 같은데후자로 처리하면 쿼리 한 번이니깐 성능상 이점이 있을 것 같은데앞서 말해주신 소스코드 관리 및 역할의 분리, 확장성 등이 이 성능에서 얻는 이점보다 메리트가 큰 건가요?또 여기서 발생하는 성능이슈는 큰 트래픽에도 크게 문제되는 수준이 아닌가요 ?
@백갤러2(14.6) 이거 왜 개행이 안되노 ㅅㅂ
@백갤러2(14.6) 말씀하신 케이스가 적절한 문제 포인트입니다. 일반적인 OLTP 서비스에서는 큰 문제는 안되는데요. (어차피 대부분의 서비스에서 read는 일상이니까요) 몇몇 케이스에서는 DB구현에 의존해야될 때 가 있습니다. 하나는 짧은 시간내의 큰 트래픽 혹은 벌크 처리이면서 레이턴시 크리티컬한 요건이 주어졌을 때 read 후 insert가 느리다면 최적화를 위해 추상화 레벨을 낮추고 뚫어야하는게 맞다고 생각되구요. 또 다른건 DBMS 구현 자체가 썩 나이스하지 않아 타협을 보는 케이스도 있습니다.
@백갤러2(14.6) 예를 들자면 MySQL에서 구현하려면 select 후 상위입찰 되면 안되니 select for update + repeatable read 를 사용하겠죠? 이 때, 조건에 맞는 행이 없다고 가정했을때 gap lock이 걸리면서 해당 구간 insert를 방지하는데, 문제는 gap lock을 이용한 특성상 논리적으로 상관없는 다른 insert 까지 방해하게 됩니다. 이건 좋지 않은 경우죠. 또한 오라클에서는 repeatable read가 없기때문에 select for update를 걸더라도 없는 행에는 아무런 영향이 없어 다른 세션이 상위입찰 할 수 있는데요. 이러면 결국 select 후 중복확인을 했으나 insert를 보장할 수 없게 되는거죠.
@백갤러2(14.6) 그래서 오라클 커뮤니티쪽에서는 보통 그냥 insert 후 충돌을 발생시키도록 권장을 하는 모습인데요. (글쓴이님이 제시하신 후자의 방법) 이러한 MySQL, 오라클의 구현에 따라서 select에 대한 정보가 필요할때 종종(절대 많이 보지는 못했습니다.) select 후 insert 후 충돌 확인되면 다시 select 같은 패턴을 사용할 수 있는데 이게 참 ㅎㅎ.... 코드나 성능이 참 안타깝게 되죠. 그래서 위와 같이 할바에는 UK 잡아둔 상태에서 insert 먼저 때리는게 일반적이게 되는데요. 이러나 저러나 결국 코드 레벨에서는 DB 레벨에 대한 강한 가정을 두고 짜는 모양새가 됩니다.
@백갤러2(14.6) 전자로 하면 select후 insert시 실패할 수 있다는 가정, 후자라면 insert시 중복이 안생기는 보장이 있다는 가정으로 말이죠. 하지만 보통 개념적으로 받아들이기 편하면서 성능도 낫고 보통 개발자라면 DB 테이블에 대한 제어 권한이 있기 때문에 후자를 선택하게 됩니다.(적어도 저는요~) 하지만 이제 DB니까 이런식으로 할 수 있는건데, 진짜 외부 API나 솔루션이라고 가정을 해보죠. 만약 정보 조회 후 insert 시 실패할 수 있으면서, insert시 중복 방지가 안되는건 어떻게 하실까요? 예를 들자면 전혀 UK가 아닐법한 조건이 비즈니스 규칙으로 있는거죠. 이름이 웅냐웅냐 라는 사람은 한번만 처리 할 수 있다.(유저 PK도 아니고 그냥 단순 정보의 일부같은 조건으로 생각해 주세요.)
@백갤러2(14.6) 한번 생각해보시고, 구현도 직접 해보시는게 좋을 것 같습니다~ (여러 구현이 있을 수 있는데, 해답이 아예 불가능한 그런 질문은 아니예요)
@백갤러1(14.52) 정리하자면, 소스코드 관리 및 역할의 분리, 확장성 등을 고려하여 일반적으로는 응용 레벨에서 구현한다. 1. 짧은 시간내의 큰 트래픽 혹은 벌크 처리이면서 레이턴시 크리티컬한 요건일 경우 발생할 수 있는 성능상의 문제 2. DBMS 구현으로 발생할 수 있는 성능상의 문제 가 크게 우려될 경우 DB레벨에서의 기능 구현을 고려해볼 수 있다.
@백갤러2(14.6) 하지만 개발자가 컨트롤 할 수 없는 외부 api 등을 사용할 때는 응용 레벨에서 처리해야한다. 외부에 로직을 의존하는 건 성능상의 이슈가 있을 때 고려해볼만하다. 애초에 비즈니스 로직을 외부에 의존하는 것 부터, 변화에 유연하지 못하고 로직도 분산되서 좋지 않을 것 같네요. 덕분에 어느정도 정리가 됐습니다. 감사합니다.
@백갤러2(14.6) 하나의 DB 스토리지에 의존하면 말씀하신 것처럼 확장성도 떨어지겠네요...
@백갤러2(14.6) 음... 2. DBMS 구현으로 발생할 수 있는 성능상의 문제는 제가 의도한건 성능이라기 보다는 관리와 코드의 영향정도인데요. 저는 개발자가 제어할 수 있는 DB라면 보통 데이터 모델링을 하고 거기에 결국 비즈니스 규칙이 담기게 됩니다. 따라서 비즈니스의 모든 규칙을 코드에만 담는건 사실상 불가능하다고 생각하고 있어요. (어떤데이터든지 마음대로 받아주고 어떤 조건이든 원하는 속도대로 조회할 수 있는 만능 저장소 같은건 세상에 없잖아요?) 따라서 그러한 한계를 받아들이면서 DBMS를 잘 활용할 수 있을때는 활용하고, 아닐때는 아니라는 것에 가까웠습니다. 물론 이 기준점은 개발자마다 다른데요, 저는 주변 자원을 적극적으로 쓰는걸 선호하는 개발자라서 UK를 걸어서 해결되는 상황이면 그렇게 하고 끝낼것같아요.
갈아치우기는 왜 좋은거냐? 쿼리 첨부터 다짜야되는데