서버캣
101
2019-06-01 13:57:12 작성 2019-06-03 19:45:41 수정됨
2
431

대용량 디비에서는 외래키를 안쓰나요?


안녕하세요

몇개월 안된 신입 개발자입니다

주변 유명 아이티기업 백엔드로 일하고 계시는 분들 말씀을 들어보면, 데이터가 많으면 속도때문에 외래키를 아예 안쓰고 조인을 많이 쓴다는데 원래 이렇게 하는게 맞나요?

외래키 무결성은 없어도 되는건가요? 그리고 이게 속도에 큰영향을 미치나요?

인덱스 걸어도 외래키 설정을 안하는게 훨씬 빠른가요?

실제 많은 기업들이 외래키를 안쓴다길래 왜 그런지 궁금합니다

0
0
  • 답변 2

  • zepinos
    19k
    2019-06-01 15:12:20

    데이터 정합성 맞출 때 좀 거슬리고 테이블 구조 변경 시 고려할게 더 많아서 프로덕션 데이터베이스에서는 제거를 해버리는 경우도 많습니다. 대신 프로그램에서 무결성을 잘 지키도록 프로그래밍 되어야하죠.

    1
  • 르매
    560
    2019-06-03 12:56:13 작성 2019-06-03 13:01:40 수정됨

    1. 외래키 무결성은 없어도 되는건가요?
    외래키를 쓰지 않는다면 무결성은 거의 깨진다고 보셔도 되겠죠. 아무리 프로그램에서 노력한다해도 한계가 있습니다.

    2. 이게 속도에 큰영향을 미치나요?
    무결성을 아무도 체크하지 않는 경우와 비교한다면 당연히 속도에 영향이 있습니다. 그렇다고해도 일반적인 OLTP 환경에서는 큰 차이로 보기 어렵습니다. 그보다는 자식이 많은 부모테이블에서 대량 DELETE가 발생하는 특수한 작업에 한해서 영향이 있다는 정도?

    하지만 실제로 무결성을 체크 안할리는 없고, 아마 프로그램에서 무결성을 대신 체크할텐데.
    그것과 비교했을 때도 외래키가 느릴까요?

    외래키가 체크하는 무결성은 이렇습니다.

    a. 자식테이블에 INSERT 할 때 참조키가 부모테이블에 있는지
    b. 자식테이블에서 참조키를 UPDATE할 때 변경 후 값이 부모테이블에 있는지
    c. 부모테이블에서 DELETE할 때 자식테이블에서 참조하고 있는지

    이걸 외래키 없이 프로그램에서는 어떻게 확인할까요?
    당연히 사전에 SELECT 해보는 거겠죠?

    결론을 말씀드리면 그냥 외래키를 걸어 놓고 프로그램에서 불필요한 SELECT 안하는게 가장 빠릅니다.
    필요한 DML을 바로 실행하고 DBMS가 반환하는 에러를 핸들링하는것이 성능과 무결성 모두를 잡는 방법이죠. (프로그램에서 SELECT 하면 동시성 문제도 생기는데.. 이거 체크하겠다고 잠금까지 건다면?? 정말 암울하죠. 그냥 외래키 하나 거는게 훨씬 가볍고 빠릅니다.)

    3. 인덱스 걸어도 외래키 설정을 안하는게 훨씬 빠른가요?
    FK에 인덱스 거는 것은 필수 작업입니다.
    외래키를 쓰던 쓰지 않던 무결성을 빠르게 확인하려면 꼭 인덱스가 필요합니다.

    4. 실제 많은 기업들이 외래키를 안쓴다길래 왜 그런지 궁금합니다.
    지푸라기라도 잡는 심정이라 할까요? 많은 프로젝트에서 DB 병목으로 장애가 발생하는데, 어떻게든 부하가 될만한 건 최대한 빼고 싶은거죠.

    하지만 정말 병목이 되는 부분은 늘 따로 있는데 대부분은 설계 자체의 문제, 최적화 되지 않은 쿼리, 인덱스 missing 같은 것이 원인입니다.

    다른 원인이라고하면.. 외래키가 걸려있을 때 테스트 데이터 만드는게 불편합니다. 개발할 때 번거로운건 사실이죠.

    또는 프로젝트에 DB 개발자가 없거나요. 때로는 공용 DB 조직이 있음에도 저런 일을 묵인하는 경우가 있는것 같은데.. 같은 업을 가진 사람으로서 왜 그러는지는 잘 모르겠습니다.

    1
  • 로그인을 하시면 답변을 등록할 수 있습니다.