[DB] UNIQUE INDEX 사용 이유

Profile-exe·2023년 7월 19일
0
post-thumbnail

온라인 강의를 들으며 회원가입을 위한 컨트롤러에서 email 필드의 유효성을 검사해 이미 가입한 이메일인지 확인하는 부분을 구현하고 있었다.

구현 방법에 대해서 인덱스라는 개념을 언급하지만 다른 방법을 사용하겠다고 했다. 언급한 내용은 자신의 mongodb 강의에 있다며 판촉(?) 행위를 하길래 그냥 혼자 공부해야겠다 생각하고 Github Copilot과 구글링을 통해 공부한 내용을 정리한다.

인덱스(INDEX), 고유 인덱스(UNIQUE INDEX), 고유 제약 조건(UNIQUE CONSTRAINT)에 대해 알아본다.


🧾 구현 방법 설명

when using mongodb you could create an index in the mongo database on your email field and give that index the unique property.

방법에 대한 설명은 해주고 실제 강의에서는 주어진 이메일을 대조하는 방법을 사용했는데, 위 설명을 보면 email 필드에 index를 생성하고 unique 속성을 부여하면 된다.

즉, email 필드를 UNIQUE INDEX로 설정하면 된다.

이를 적용하면 무엇이 달라질지, 어떤 이점이 있을지 알아보도록 하겠다.


🔍 INDEX ?

Database_index - Wikipedia

A database index is a data structure that improves the speed of data retrieval operations on a database table at the cost of additional writes and storage space to maintain the index data structure.

  • 데이터베이스의 인덱스(INDEX)검색 작업의 속도를 향상시키는 데이터 구조

  • 데이터 구조는 해시 테이블(Hash Table)B Tree로 구현 가능하며 주로 B Tree에서 파생된 구조로 구현됨 - B* Tree, B+ Tree

  • 인덱스 역시 데이터 구조이므로 추가적인 쓰기 작업저장 공간이 필요


⚖️ INDEX 장단점

📌 장점

  • 인덱스를 사용하면 데이터 조회(SELECT) 속도가 빨라진다.

  • WHERE, ORDER BY, MIN/MAX 속도가 빨라진다.

    데이터베이스에서 특정 데이터를 조회(WHERE)할 때 테이블 전체를 조회(full scan)해야 한다.

    하지만 인덱스를 사용하는 경우 인덱스를 기준으로 정렬된 상태로 저장되어 있어 더 빠르게 찾을 수 있다.

    정렬된 상태이므로 ORDER BY, MIN/MAX 또한 빨라진다

📌 단점

  • 인덱스라는 데이터 구조를 유지하기 위한 비용이 존재한다.

    테이블과는 별개로 추가적인 저장 공간이 필요하고 인덱스가 적용된 열(Column)에 INSERT, UPDATE, DELETE 작업 시 정렬, 인덱스 구조 갱신 등 추가적인 연산이 발생한다.

✨ 인덱스를 적용하기 적절한 경우

  • 조회(SELECT)를 자주 하는 경우

  • 삽입(INSERT), 수정(UPDATE), 삭제(DELETE)가 자주 발생하지 않는 경우

  • 데이터의 중복도가 낮은 경우

  • WHERE, ORDER BY, JOIN을 자주 하는 경우


✔️ 구현

앞 내용들로 INDEX에 대해서는 어느정도 알았으니 email 필드에 UNIQUE INDEX를 부여해 중복 방지(unique)빠른 조회(index)를 구현해보자.

  • models/user.js
const userSchema = new Schema({
  name: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    required: true,
    unique: true,	// unique 옵션 설정
  },
});
  • Github Copilot Chat 답변

email 필드에 unique 옵션을 추가하면 해당 필드에 대한 Unique Index가 생성되며, 이를 통해 해당 필드를 기준으로 조회하는 작업이 더욱 빠르게 수행될 수 있습니다. mongoose에서는 unique 옵션을 가진 필드에 대해 자동으로 인덱스를 생성해주는 기능이 있으므로, email 필드에 unique 옵션을 추가하면 mongoose가 자동으로 email 필드에 대한 Unique Index를 생성합니다

필드에 unique 옵션을 주면 mongoose에서 자동으로 Unique Index를 생성해준다. 이로서 email 필드에 대한 중복 방지 및 빠른 조회가 가능해졌다.

  • controllers/auth.js
postSignup: async (req, res, next) => {
  const { name, email, password } = req.body;

  try {
    // email만 넣으면 됌!!
    const existingUser = await User.findOne({ email });
    ...

  } catch (err) {
    ...
  }
},

email필드가 중복값이 없음이 보장되고 index가 적용되어있어 빠른 조회가 가능하다.


🤔 UNIQUE INDEX 적용 이유

그렇다면 왜 email 필드에 unique 인덱스를 적용해야 하는 것일까?

💬 INDEX 적용 이유

email필드에 대해 살펴보면 앞서 정리한 인덱스를 적용하기 적절한 경우에 대부분 해당한다.

  • 조회(SELECT)를 자주 하는 경우

    이메일은 사용자의 데이터로서 게시글 작성자 확인 시 정보 표시관리자 페이지에서 회원 조회 등 조회가 자주 일어날 수 있다.

  • 삽입(INSERT), 수정(UPDATE), 삭제(DELETE)가 자주 발생하지 않는 경우

    사람마다 다르겠지만 특정 사이트에 가입 및 탈퇴를 자주 하지 않으며 가입한 이메일 수정 또한 빈번하지는 않다.

  • 데이터의 중복도가 낮은 경우

    이메일 또한 타 사이트에서 중복되지 않은 아이디로 가입해 만들어진 것으로 다른 사용자와 이메일 주소가 같을 가능성이 매우 적다.

💬 "Unique" Index인 이유

email필드는 중복값을 허용하지 않는 필드로 설정하고 싶었기 때문이다. 사용자들이 각자의 고유한 이메일 주소를 가지고 회원가입 및 로그인이 가능하도록 구현하려 했다.


💡 Unique ConstraintUnique Index

Unique Constraint(고유 제약 조건)는 내부적으로 Unique Index(고유 인덱스)를 사용하여 구현된다. 고유 인덱스를 생성해 고유 제약 조건을 강제할 수 있기 때문이다.

두 기능을 지원하는 데이터베이스에서는 목적을 명시하는 목적으로 위 둘을 사용할 수 있다.

공통적으로 고유한 값을 가져 중복값을 허용하지 않는다는 조건이 적용된다고 간주한다.

🔗 인덱스 기능을 중점적으로 활용하여 고유성을 강조하고자 할 때

필드를 검색, 정렬, 필터링하는 데 빠른 속도가 필요한 경우, 고유 인덱스를 명시적으로 사용하고 주석을 추가하여 코드에 명확하게 표시하면 된다.

이렇게 함으로써 나중에 고유성이 불필요해진 경우 인덱스 기능만 유지하면 되니 일반적인 non-unique 인덱스로 대체해야 함을 알 수 있다.

🔗 비즈니스 규칙을 중점적으로 고유성을 강조하고자 할 때

필드의 고유성을 강제하기 위해 인덱스가 필요하지 않고, 단순히 비즈니스 규칙으로 고유성을 검증해야 하는 경우, 고유 제약 조건을 사용하는 것이 좋다.

🚨 주의

비즈니스 규칙에서 고유성을 강조할 때, 인덱스가 필요하지 않아도 내부적으로 UNIQUE INDEX를 이용해 구현하기 때문에 '인덱스가 필요하지 않지만 생긴다'는 사실을 인지해야 한다


참고

IBM 문서 - Unique and non-unique indexes
When should I use a unique constraint instead of a unique index
Difference between unique indexes and unique constraints
클러스터드 인덱스 (Clustered Index), 넌 클러스터드 인덱스 (Non Clustered Index)

profile
컴퓨터공학과 학부생

0개의 댓글