코어 데이터는 코코아 프레임워크에서 제공하는 데이터 관리 프레임 워크입니다. 일종의 DB라고 생각하면 편할 것 같아요.
인메모리 방식으로 구현되어서 읽고 쓰는 모든 데이터를 메모리에 로드한 다음에 처리합니다. 물론 데이터는 결국 영구 저장소에 저장되기 때문에 앱을 껐다가 켜도 같은 데이터를 볼 수 있습니다.
Core Data는 앱의 데이터를 영구히 저장하기 사용합니다. 또한 User Default와는 다르게 복잡한 구조를 가진 많은 데이터를 쉽게 저장할 수 있습니다.
Core Data를 마스터하기 위해서는 다양한 용어와 클래스명을 알아야 하지만 이번 포스팅에서는 간단하게 Entity에 관련된 핵심 용어만 정리해보도록 하겠습니다. 관계형 DB (SQL)과 비교해서 생각하면 쉽게 이해할 수 있습니다.
용어 | 의미 | 관계형 DB와 비교 |
---|---|---|
Entity | 데이터의 구조를 정의해 놓은 것 | Table |
Attribute | Entity의 하위 속성 | Column |
Relation | 다른 Entity와의 관계 정의 | JOIN |
Relation과 JOIN가 비슷한 개념이기는 하지만 원리적으로는 차이가 있습니다. JOIN이 두 테이블을 연결해서 새로운 제 3의 테이블을 만드는 방식이라면 Relation은 각각의 테이블 서로의 데이터를 온전히 다 가지고 있습니다. 그림으로 보면 아래와 같습니다.
위 그림에서는 1:1 Relation을 표시하고 있지만 사실 Relation은 1:N과 M:N의 두 가지 유형이 더 있습니다.
1 : 1은 위 그림에서 보듯이 두 Entity가 하나의 Relation만 가지는 경우입니다. 예를 들면 반과 담임 선생님의 관계라고 볼 수 있습니다. 담임선생님은 단 하나의 담당 반을 가지고 반도 마찬가지로 단 한 명의 담임 선생님만 가질 수 있습니다.
1 : N은 한 쪽 Entity는 하나의 Relation을 가지지만 다른 쪽 Entity는 여러 개의 Relation을 가지는 경우입니다. 예를 들면 반과 학생들의 관계라고 볼 수 있겠네요. 학생들은 한 개의 반만을 자신의 반으로 가지지만 반의 경우는 여러 명의 학생들을 구성원으로 가질 수 있습니다.
마지막으로 M : N은 두 Entity가 모두 여러 개의 Relation을 가지는 경우입니다. 학생과 동아리의 관계를 예로 들어보겠습니다. (동아리는 여러 개 가입할 수 있다고 가정 합니다.) 학생은 여러 개의 동아리를 가질 수 있습니다. 마찬가지로 동아리의 입장에서도 여러 명의 학생을 구성원으로 가질 수 있습니다.
Entity와 Attribute에 비해서 Relation은 상대적으로 SQL과 개념이 많이 다릅니다. JOIN의 예로 설명하기는 했지만 Table 두 개를 하나의 Table로 만드는 개념의 JOIN과 일종의 Column처럼 취급되는 Relation은 차이가 있지요.
한 마디로 설명하자면 Relation은 일종의 Column처럼 이해하는 것이 좋습니다. 다만 해당 Column에 들어있는 데이터가 다른 Table (Entity)의 데이터인 것입니다.
그림을 보고 설명을 들으면 언뜻 이해가 되는 것 같다가도 나중에 실제 코드를 쓸 때는 헷갈릴 때도 많습니다. 그것은 그 때가서 다시 보도록 합시다!
관계형 데이터베이스를 사용할 때 Table을 설계하듯이 Core Data를 사용하기 위해서는 Entity를 설계해야 합니다. Xcode를 켜고 Entity 설계를 한번 해봅시다.
Entity 설계를 위해서는 위에 Relation을 설명하면서 들었던 예시를 사용하겠습니다. (학생-반-선생님-동아리)
먼저 Data Model 파일을 만들어야 합니다. 새로운 파일에서 만들기에서 Data Model을 만들면 xcdatamodel 확장자를 가지는 Data Model 파일을 만들 수 있습니다.
다음은 Entity를 추가해봅시다. 좌하단에 있는 Add Entity를 클릭합니다.
아래 캡쳐처럼 4개의 Entity를 추가해봤습니다. 각각 반, 동아리, 학생, 교사의 데이터를 저장할 Entity입니다. Entity 이름은 대문자로 해야한다는 것 잊지 맙시다. (에러납니다...)
Relation은 나중에 하고 Attribute 먼저 추가해봅시다. Attribute 칸에 +를 눌러서 추가할 수 있습니다. Attribute는 다양한 Type을 할당할 수 있습니다. 여기까지는 관계형 DB
이제 Relation을 설정해봅시다. 먼저 1 : 1입니다.
Delete Rule | 의미 |
---|---|
No Action | 참조 대상이 삭제되도 아무 행동도 하지 않습니다. 결과적으로 사라진 Data를 참조하는 꼴이 됩니다. 참조 대상이 삭제되도 아무 행동도 하지 않습니다. 결과적으로 사라진 Data를 참조하는 꼴이 됩니다. (그때그때 경우에 맞게 수동으로 업데이트 하고자할 때 사용합니다.) |
Nullify | 참조 대상이 삭제되면 Relation이 nil이 됩니다. |
Cascade | 참조 대상이 삭제되면 참조하고 있던 모든 데이터를 삭제합니다. |
Deny | 해당 데이터를 참조하는 데이터가 있다면 해당 데이터를 삭제하지 못합니다. |
😅 Inverse 관계인 두 Relation을 오가면서 Delete Rule을 설정하다가 보면 엄청 헷갈립니다. 저는 이렇게 생각하니까 편하더라고요. 무조건 자기 자신이 기준입니다. 자기 자신이 삭제될 때 Relation 반대편에 있는 데이터를 어떻게 처리할 것인지 정해놓는 것입니다.
만약에 어떤 반 학생이 모두 전학을 가버렸다고(!) 가정해봅시다. 아마 반은 사라지겠지요? 하지만 반이 사라졌다고 해서 담임선생님이 중간에 퇴직하시지는 않습니다. 따라서 위 캡쳐처럼 homeRoomTeacher의 Delete Rule은 Nullify입니다.
마찬가지로 담임 선생님이 중간에 퇴직하셨다고 해서 반이 없어지지는 않습니다. 따라서 HomeRoom 역시 Nullify로 하면 되겠습니다.
위의 담임 선생님과 반의 관계는 둘 다 1:1 관계 였습니다. 이번에는 서로 Type이 다른 경우를 간단한 예시로 보여드리겠습니다.
Class와 Student 엔터티에 각각 students와 homeRoom이라는 Relation을 만들었습니다. 서로 Inverse 관계입니다.
반은 소속 학생을 여러 명 가질 수 있습니다. 따라서 Type은 To Many로 합니다. 또한 만약 반에 학생이 한 명이라도 남아있다면 반을 없애서는 안되겠지요? 따라서 Delete Rule은 Deny로 하겠습니다.
이번에는 학생의 입장입니다. 학생의 입장에서 소속 반은 단 1개 뿐입니다. 따라서 Type은 to One입니다. 또한 학생이 없어진다고 반이 없어지면 안되겠지요? Nullify로 합니다.