[CS] DB, DBMS

린다·2021년 11월 2일
0

Computer Science

목록 보기
3/3
post-thumbnail

학교에서 들었던 콘텐츠데이터베이스 수업 이후로 데이터베이스 관련 공부를 한건 정말 오랜만이었다! 그래도 나름 데이터베이스 수업을 재밌게 들었던터라(+ 가르쳐주신 교수님 강의력이 짱이었음 ,,) 오늘 수업이 되게 즐거웠다(?)
구구절절 tmi와 함께 정리해보는 DB, DBMS

✔️ DB, DBMS

  • 데이터베이스는 데이터의 집합을 의미한다. 데이터베이스 만으로는 할 수 있는 것이 없기 때문에 이를 관리하기 위하여 만들어진 소프트웨어를 DBMS(DataBase Management System)라고 부른다.
  • DBMS도 종류가 다양한데 관계형, 계층형, NosQL 등이 존재한다. 이 중 관계형 데이터베이스(RDBMS)가 가장 많이 사용된다.

✔️ RDBMS 구조

  • Schema: 데이터베이스의 구조와 각 열에 대한 제약 조건을 거는 것
  • Table: 전체 표, Row와 Column으로 이루어져있음
  • Column(= Attribute): 수직으로 묶인 데이터의 모음, 데이터베이스에서 내용을 검색할 때 Column을 기준으로 검색함
  • Row(= Record, Tuple): 수평으로 묶인 데이터의 모음, 한 객체에 대한 정보, PK로 구별 가능함

✔️ 테이블 조건

🔘 Primary Key

  • 객체를 유일하게 구별할 수 있는 키
  • Optional값이 절대 될 수 없음(빈 칸이 될 수 없음)
  • 절대 중복되면 안됨
  • PK는 인덱스의 특성을 가지고 있음 -> 데이터베이스 시스템에서 검색하는 속도를 높이기 위한 특성
  • 하지만 인덱스를 너무 많이 지정해주면 속도가 느려지기 때문에 반드시 필요한 부분에 있어서만 인덱스를 설정하는 것이 좋음

🔘 Foreign Key

  • PK를 외부 테이블에서 사용하면 foreign key라고 부름(다른 테이블의 PK)
  • 두 테이블 간의 종속이 필요한 경우 사용하기도 함

🔘 Unique Key

  • Pk는 아니지만 중복이 되지 않고 값을 비워두는 것은 가능한 경우

  • Realm은 다중 기본키를 허용하지 않음

✔️ Migration

🔘 Migration이란

  • 현재 운영환경으로부터 다른 운영환경으로 옮기는 작업을 뜻한다. 데이터베이스 환경에서만 사용되는 것이 아니라 소프트웨어, 하드웨어, 네트워크 등 폭넓게 사용되고 있는 용어
  • 데이터베이스에서의 마이그레이션은 데이터베이스 스키마 버전을 관리하기 위한 방법
  • 테이블을 수정 후 마이그레이션을 해줘야 테이블 간 충돌이 일어나지 않음
  • 개발 단계(출시 전)에서는 test app을 삭제 후 재설치하는 방식으로 해결할 수 있으나 그 추후에는 어떻게 해결해야할까?

🔘 Migration 방법

(해당 링크를 참고하여 정리해보았다.)

  • 스키마를 업데이트하는 경우, 스키마 버전을 올려주고 migration을 실행해야한다.
    만약에 그 업데이트가 옵셔널 프로퍼티를 추가하거나 프로퍼티를 삭제하는 부분을 포함하고 있다면 Realm Database가 migration을 자동으로 처리할 수 있다. 따라서 schema 버전만 올려주면 된다!
  • 더 복잡한 스키마 업데이트를 위해서 수동으로 migrationBlock에서 migration logic을 자세히 서술해야한다. 이때 다음과 같은 변화를 포함해야한다.

    ☑️ 기본값으로 채워야하는 필수 프로퍼티 추가
    ☑️ 필드 결합
    ☑️ 필드 이름 변경
    ☑️ 필드 타입 변경
    ☑️ 객체를 embedded object로 변환시키기

자동으로 스키마 업데이트 되는 경우

  • 프로퍼티를 추가하거나 삭제하는 경우: migration은 자동으로 진행되나 schema version은 직접 관리해줘야한다.
  • 다음과 같이 직접 스키마 버전을 언급해줌으로써 최신 스키마 버전을 사용하겠다고 선언해줘야한다.
// 새로운 버전을 사용하겠다고 config를 선언해준다.
let config = Realm.Configuration(
    schemaVersion: 2)
// 새로 선언해준 config를 realm을 열 때 사용한다고 선언해준다.
Realm.Configuration.defaultConfiguration = config
let realm = try! Realm()

수동으로 스키마를 migrate 해야하는 경우

  • 프로퍼티 이름을 수정하는 경우
    : Migration.renameProperty(onType:from:to:)를 사용해야한다.
  • ageyearsSinceBirth로 이름을 변경하고자 하는 경우
let config = Realm.Configuration(
    schemaVersion: 2,
    migrationBlock: { migration, oldSchemaVersion in
        if oldSchemaVersion < 2 {
            // 프로퍼티의 이름을 "name"에서 "yearsSinceBirth"로 변경해준다.
            // The renaming operation should be done outside of calls to `enumerateObjects(ofType: _:)`.
            migration.renameProperty(onType: Person.className(), from: "age", to: "yearsSinceBirth")
        }
    })
  • 프로퍼티 변경하는 경우
    : 커스텀 migration 로직을 구현하기 위해서는 realm을 열 때 Configuration의 migrationBlock 프로퍼티를 설정해주면 된다.
  • migrationBlock은 migration을 수행하기 위해 사용할 수 있는 Migration object를 매개변수로 받는다. Migration object의 enumerateObjects(ofType:_:) 메서드를 사용하여 인스턴스를 반복하여 업데이트할 수 있다.
  • 분리돼있던 fistName, lastName을 하나의 fullName으로 변경하고 싶은 경우 작성하는 코드
// In application(_:didFinishLaunchingWithOptions:)
let config = Realm.Configuration(
    schemaVersion: 2, // Set the new schema version.
    migrationBlock: { migration, oldSchemaVersion in
        if oldSchemaVersion < 2 {
            // The enumerateObjects(ofType:_:) method iterates over
            // every Person object stored in the Realm file to apply the migration
            migration.enumerateObjects(ofType: Person.className()) { oldObject, newObject in
                // combine name fields into a single field
                let firstName = oldObject!["firstName"] as? String
                let lastName = oldObject!["lastName"] as? String
                newObject!["fullName"] = "\(firstName!) \(lastName!)"
            }
        }
    }
)
// Tell Realm to use this new configuration object for the default Realm
Realm.Configuration.defaultConfiguration = config
// Now that we've told Realm how to handle the schema change, opening the file
// will automatically perform the migration
let realm = try! Realm()
  • Int 타입으로 선언돼있던 age를 String 타입으로 변환하고싶은 경우
// In application(_:didFinishLaunchingWithOptions:)
let config = Realm.Configuration(
    schemaVersion: 3, // Set the new schema version.
    migrationBlock: { migration, oldSchemaVersion in
        if oldSchemaVersion < 2 {
            // Previous Migration.
            migration.enumerateObjects(ofType: Person.className()) { oldObject, newObject in
                let firstName = oldObject!["firstName"] as? String
                let lastName = oldObject!["lastName"] as? String
                newObject!["fullName"] = "\(firstName!) \(lastName!)"
            }
        }
        if oldSchemaVersion < 3 {
            // New Migration.
            migration.enumerateObjects(ofType: Person.className()) { oldObject, newObject in
                // Make age a String instead of an Int
                newObject!["age"] = "\(oldObject!["age"] ?? 0)"
            }
        }
    }
)
// Tell Realm to use this new configuration object for the default Realm
Realm.Configuration.defaultConfiguration = config
// Now that we've told Realm how to handle the schema change, opening the file
// will automatically perform the migration
let realm = try! Realm()

0개의 댓글