Realm Blog

13,949번의 커밋과 6,148개의 이슈를 거쳐 Realm이 1.0이 되었습니다. 개발자분들의 성원에 감사드립니다

Realm 을 “최초의 모바일 데이터베이스”로 소개한 것이 2014년 7월 입니다. 오늘, 13,949개의 커밋과 6,148 개의 이슈를 통해 커뮤니티와 함께 만들어진 Realm 1.0을 자신있게 발표하게 되었습니다. 이는 Realm 회사로서, 제품으로서 커다란 의미를 가질 뿐 아니라 Realm과 함께한 iOS, Android 개발자 커뮤니티에 커다란 의미입니다.

우리가 처음 제품을 발표할 때, 우리는 iOS와 Mac 사용자를 위한 Objective-C 버전만을 발표했습니다. Swift 지원과 Android 버전은 그 후에 추가가 되었고, 최근에는 React Native와 Xamarin 지원을 발표하였습니다. 이제 Realm은 모든 모바일 개발 플랫폼과 개발 언어를 지원하고 있습니다. 이번 릴리즈는 2년 이상 온 힘을 다해 만들고 다듬은 결과물이며, 이는 커뮤니티의 수많은 지원이 있지 않았다면 불가능했을 것입니다. 감사합니다! 👏

1.0 이전 버전에서도 Realm은 이미 모바일 개발 커뮤니티에서 널리 사용되고 있었습니다. 개발자들은 Github에서 12,000 개 이상의 Star를 주셨고, 이는 계속 늘어나고 있습니다. Realm 은 현재 10만명이상의 개발자가 실제로 개발에 사용하고 있으며, 스타벅스, 트위터, 알리바바, 이베이, 네이버, 카카오, 배달의민족, CJ몰 과 같은 대형앱을 포함한 수많은 앱에서 널리 사용하고 있습니다. 이 앱들은 Realm이 그들의 앱을 더 낫게 만들 수 있다는 판단하에 사용합니다. Realm을 통해서 개발자들은 더 나은 사용자 경험을 가져올 수 있으며 앱의 개발은 더 쉽고 빨라집니다. 오늘 1.0 릴리즈를 통해서 이제 개발자들은 Realm이 충분한 수준으로 성숙했고 안정성을 확보하고 있다는 더 강한 확신을 가질 수 있습니다.

어떤 점이 바뀌었는지는 이 개발 changelogs를 통해 확인하실 수 있습니다: Java, Objective-C와 Swift

Realm이 무엇인가요?

Realm은 SQLite를 기반으로하는 여타 ORM들과는 다릅니다. 우리는 모바일 개발자가 필요로하는 기능을 모두 갖춘 데이터베이스이며 처음부터 새로 만들었습니다. 네이티브 객체는 우리가 직접 개발한 데이터베이스와 동적으로 맵핑 됩니다. 이 데이터베이스는 key-value 스토어가 아닌, 모든 데이터베이스에서 요구되는 기능을 갖춘 데이터베이스입니다. 이런 방법을 통해 우리는 간결한 API는 물론 최고의 성능을 보여줍니다. Realm을 사용하면 복잡한 데이터 모델을 구현하고, 객체를 그래프와 연결하고, 복잡한 질의를 날릴 수 있습니다.

// Define you model class by extending RealmObject
public class Dog extends RealmObject {
    private String name;
    private int age;

    // ... Generated getters and setters ...
}

public class Person extends RealmObject {
    @PrimaryKey
    private long id;
    private String name;
    private RealmList<Dog> dogs; // Declare one-to-many relationships

    public Person(long id, String name) {
        this.id = id;
        this.name = name;
    }

    // ... Generated getters and setters ...
}

// Use them like regular java objects
Dog dog = new Dog();
dog.setName("Rex");
dog.setAge(1);

// Create a RealmConfiguration that saves the Realm file in the app's "files" directory.
RealmConfiguration realmConfig = new RealmConfiguration.Builder(context).build();
Realm.setDefaultConfiguration(realmConfig);

// Get a Realm instance for this thread
Realm realm = Realm.getDefaultInstance();

// Query Realm for all dogs younger than 2 years old
final RealmResults<Dog> puppies = realm.where(Dog.class).lessThan("age", 2).findAll();
puppies.size(); // => 0 because no dogs have been added to the Realm yet

// Persist your data in a transaction
realm.beginTransaction();
final managedDog = realm.copyToRealm(dog); // Persist unmanaged objects
Person person = realm.createObject(Person); // Create managed objects directly
person.getDogs().add(managedDog);
realm.commitTransaction();

// Listeners will be notified when data changes
puppies.addChangeListener(new RealmChangeListener<RealmResults<Dog>>() {
    @Override
    public void onChange(RealmResults<Dog> results) {
        // Query results are updated in real time
        puppies.size(); // => 1
    }
});

// Asynchronously update objects on a background thread
realm.executeTransactionAsync(new Realm.Transaction() {
    @Override
    public void execute(Realm bgRealm) {
        Dog dog = bgRealm.where(Dog.class).equals("age", 1).findFirst();
        dog.setAge(3);
    }
}, new Realm.Transaction.OnSuccess() {
    @Override
    public void onSuccess() {
      // Original queries and Realm objects are automatically updated.
      puppies.size(); // => 0 because there are no more puppies younger than 2 years old
      managedDog.getAge();   // => 3 the dogs age is updated
    }
});
// Define your models like regular Objective‑C classes
@interface Dog : RLMObject
@property NSString *name;
@property NSData   *picture;
@property NSInteger age;
@end
@implementation Dog
@end
RLM_ARRAY_TYPE(Dog)
@interface Person : RLMObject
@property NSString             *name;
@property RLMArray<Dog *><Dog> *dogs;
@end
@implementation Person
@end

// Use them like regular Objective‑C objects
Dog *mydog = [[Dog alloc] init];
mydog.name = @"Rex";
mydog.age = 1;
mydog.picture = nil; // properties are nullable
NSLog(@"Name of dog: %@", mydog.name);

// Query Realm for all dogs less than 2 years old
RLMResults<Dog *> *puppies = [Dog objectsWhere:@"age < 2"];
puppies.count; // => 0 because no dogs have been added to the Realm yet

// Persist your data easily
RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
  [realm addObject:mydog];
}];

// Queries are updated in real-time
puppies.count; // => 1

// Query and update the result in another thread
dispatch_async(dispatch_queue_create("background", 0), ^{
  Dog *theDog = [[Dog objectsWhere:@"age == 1"] firstObject];
  RLMRealm *realm = [RLMRealm defaultRealm];
  [realm beginWriteTransaction];
  theDog.age = 3;
  [realm commitWriteTransaction];
});
// Define your models like regular Swift classes
class Dog: Object {
  dynamic var name = ""
  dynamic var age = 0
}
class Person: Object {
  dynamic var name = ""
  dynamic var picture: NSData? = nil // optionals supported
  let dogs = List<Dog>()
}

// Use them like regular Swift objects
let myDog = Dog()
myDog.name = "Rex"
myDog.age = 1
print("name of dog: \(myDog.name)")

// Get the default Realm
let realm = try! Realm()

// Query Realm for all dogs less than 2 years old
let puppies = realm.objects(Dog).filter("age < 2")
puppies.count // => 0 because no dogs have been added to the Realm yet

// Persist your data easily
try! realm.write {
  realm.add(myDog)
}

// Queries are updated in real-time
puppies.count // => 1

// Query and update from any thread
dispatch_async(dispatch_queue_create("background", nil)) {
  let realm = try! Realm()
  let theDog = realm.objects(Dog).filter("age == 1").first
  try! realm.write {
    theDog!.age = 3
  }
}
// Define your models and their properties
class Car {}
Car.schema = {
  name: 'Car',
  properties: {
    make:  'string',
    model: 'string',
    miles: 'int',
  }
};
class Person {}
Person.schema = {
  name: 'Person',
  properties: {
    name:    {type: 'string'},
    cars:    {type: 'list', objectType: 'Car'},
    picture: {type: 'data', optional: true}, // optional property
  }
};

// Get the default Realm with support for our objects
let realm = new Realm({schema: [Car, Person]});

// Create Realm objects and write to local storage
realm.write(() => {
  let myCar = realm.create('Car', {
    make: 'Honda',
    model: 'Civic',
    miles: 1000,
  });
  myCar.miles += 20; // Update a property value
});

// Query Realm for all cars with a high mileage
let cars = realm.objects('Car').filtered('miles > 1000');

// Will return a Results object with our 1 car
cars.length // => 1

// Add another car
realm.write(() => {
  let myCar = realm.create('Car', {
    make: 'Ford',
    model: 'Focus',
    miles: 2000,
  });

// Query results are updated in real-time
cars.length // => 2
// Define your models like regular C# classes
public class Dog : RealmObject 
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Person Owner { get; set; }
}

public class Person : RealmObject 
{
    public string Name { get; set; }
    public RealmList<Dog> Dogs { get; } 
}

var realm = Realm.GetInstance();

// Use LINQ to query
var puppies = realm.All<Dog>().Where(d => d.Age < 2);

puppies.Count(); // => 0 because no dogs have been added yet

// Update and persist objects with a thread-safe transaction
realm.Write(() => 
{
    var mydog = realm.CreateObject<Dog>();
    mydog.Name = "Rex";
    mydog.Age = 1;
});

// Queries are updated in real-time
puppies.Count(); // => 1

// LINQ query syntax works as well
var oldDogs = from d in realm.All<Dog>() where d.Age > 8 select d;

// Query and update from any thread
new Thread(() =>
{
    var realm2 = Realm.GetInstance();

    var theDog = realm2.All<Dog>().Where(d => d.Age == 1).First();
    realm2.Write(() => theDog.Age = 3);
}).Start();

왜 Realm을 써야 할까요?

쉬운 사용성

Realm은 언제나 쉬운 사용성을 매우 중요한 요소로 생각합니다. 개발자들은 커다란 앱도 Realm으로 바꾸는데 많은 시간이 걸리지 않았다고 이야기 합니다. 보통 개발, 최적화, 디버깅에 걸리는 시간을 획기적으로 단축해 줍니다.

빠른 속도

Realm의 쉬움이 성능상의 비용을 발생하지는 않습니다. 메모리 매핑, 지연된 불러오기, 커스텀 스토리지 엔진 덕분에 Realm은 풍부한 객체 기반의 API를 제공하면서도 SQLite에 비해 일반적으로 빠릅니다. 우리는 항상 자신의 사용 예에 맞추어 모든 사람이 테스트해보길 권합니다만 코드를 Realm으로 옮길 때 막대한 성능향상을 보아왔습니다.

크로스 플랫폼

Realm은 iOS와 안드로이드 모두를 대상으로 실행할 수 있습니다. Realm 파일 포맷이 완전히 크로스 플랫폼이고 iOS와 안드로이드에서 손쉽게 접근할 수 있습니다. 디버깅을 위해 Realm Browser에서 .realm 파일들을 열수 있습니다.

Realm 은 Java, Objective-C, React Native, Swift 그리고 Xamarin을 지원합니다. Realm 파일 포맷은 완전히 크로스 플랫폼이고 같은 데이터모델을 사용할 수 있어 비슷한 비지니스 로직을 모든 플랫폼에서 사용할 수 있습니다. 디버깅을 위해 Realm 브라우져에서 .realm 파일들을 열수 있습니다.

고급 기능들

Realm 객체는 항상 하부 데이터에 맞추어 최신 판으로 갱신됩니다. 반응형 패턴이나 단일 데이터 흐름을 따르기 매우 쉽습니다. Realm 객체를 그래프로 연결할 수 있고, 복잡한 쿼리를 통해 어떤 복잡한 질의를 할 수 있으며 내장된 AES256 암호화 기능을 사용할 수 있습니다. 또한 Realm 커뮤니티를 통해 개발된 수많은 플러그인에서 개발된 수많은 애드온을 사용해 UI 등 다른 요소들과 매우 쉽게 통합할 수 있습니다.

신뢰성

커다란 앱을 개발하고 계신가요? Realm은 당신을 위한 데이터베이스 입니다. Realm은 전 세계 수십억대의 스마트폰에서 사용되고 있으며 e-커머스 애플리케이션, 은행, 핼스 케어 제공자, 심지어 정부기관 등이 사용하고 있습니다. 또한 수많은 탑순위 앱들이 사용 중 입니다.

커뮤니티 주도

Realm은 GitHub에서 공개되어 개발이 진행되고 있습니다. 기능들의 우선순위는 사용자 요청에 의해서 정하며 오픈소스의 기여를 언제나 환영합니다. 우리는 12,000개 이상의 Star를 받았으며 우리 제품을 기반으로 수많은 플러그인과 컴포넌트가 개발되고 있습니다.

기술 지원

Realm은 다른 모든 것보다 지원과 버그 수정을 우선하고 있습니다. 데이타베이스에 관한 답을 그것을 개발하고 지원하는 사람들에게 직접 들을 수 있습니다. Stack Overflow, GitHub, 또는 Twitter로 질문해주세요.

누가 Realm을 쓰고 있나요?

Realm 은 수십억의 인구가 이미 사용하고 있습니다. 한국에서는 네이버, 카카오의 다양한 앱들과, 배달의민족, 요기요, CJ오쇼핑, 피키캐스트, 리디북스, 캐시슬라이드, 싸이메라, 리멤버, 비트윈 등 다양한 분야에서 사용하고 있습니다.

트위터

앱스토어 최상위의 앱들도 Realm을 신뢰합니다. 트위터의 비디오 앱인 Vine과 그앱을 사용하는 2억명의 실 사용자들은 2016년 부터 Realm을 사용하고 있습니다.

스타벅스

포춘 500 회사도 Realm을 그들의 대표앱에 사용하고 있습니다. 사이렌오더와 같은 선주문 기능이나 리워드 관리들에 사용합니다.

알리바바

뉴욕증권 거래소에 상장되어있는 중국의 거대한 회사인 알리바바는 Realm을 그들의 대표 상거래 앱에 사용하고 있습니다. 이 앱을 통해서 공급자와 구매자가 물건을 팔거나 구매하고 작년에느 30억달러 이상의 매매가 이루어졌습니다.

버드와이저

글로벌 500에 랭크되어있는 이 거대한 회사는 Realm으로 TapWiser라는 앱을 만들었습니다. 이 앱을 통해서 컴퓨터가 없는 수많은 바나 상점에서도 바로 맥주 주문을 할 수 있습니다.

SAP

Concur 를 사용하고 계시다면, 당신은 이미 Realm을 사용하고 있습니다: 2만명의 고객사의 3천만명 이상의 고객들이 비용 처리나 여행 계획등을 이 앱을 처리하고 있습니다.

Rite Aid (거대 약국체인)

포춘 500에 포함된 이 거대한 상거래 회사는 Realm으로 사용해 사용자의 데이터를 안전하게 저장하고 있습니다.

이 뿐만 아니라 아마존, 구글, 고프로, 월마트, 아디다스, 시스코, NBC, 나이키, NFL 등등 수많은 회사가 사용하고 있습니다.

다음 단계

우리는 계속 발전할 수 있도록 여러분들의 피드백을 듣고자 합니다. 스택오버플로우트위터등 다양한 곳을 통해서 저희에게 의견을 주실 수 있습니다.

Realm Java 시작하기 - GitHub에서 코드를 확인하세요
Realm Objective-C 시작하기 - GitHub에서 코드를 확인하세요
Realm Swift 시작하기 - GitHub에서 코드를 확인하세요
Realm React Native 시작하기 - GitHub에서 코드를 확인하세요
Realm Xamarin 시작하기 - GitHub에서 코드를 확인하세요

Realm으로 더 나은 앱을 개발 하실 수 있기를 기대합니다!


Realm Team

Realm의 미션은 더 나은 앱을 빠르게 개발할 수 있도록 돕는 것입니다. 이를 위해 저희는 개발자들이 실시간 협업, 가상 현실, 라이브 데이터 동기화, 오프라인 경험, 메시징 등 정교하고 강력한 기능을 쉽게 개발할 수 있도록 하는 개발 도구와 플랫폼을 제공하고 있습니다.

저희는 모바일 인터넷이 수많은 사용자와 보다 많은 디바이스가 속한 개방형 네트워크와 이들 간의 실시간 상호 작용으로 진화할 것이라고 믿으며, 개발자가 이같은 방향으로 발전할 수 있도록 돕기 위해 저희 제품들을 개발하고 있습니다.

이런 개발 뉴스를 더 만나보세요