Realm基本知識

2021-08-06 06:18:59 字數 4756 閱讀 2943

realm是乙個類mvcc資料庫,每個連線的執行緒在特定的時刻都有乙個資料庫的快照。mvcc在設計上採用了和git一樣的原始檔管理演算法,也就是說你的每個連線線程就好比在乙個分支(也就是資料庫的快照)上工作,但是你並沒有得到乙個完整的資料庫拷貝。realm和一些真正的mvcc資料庫如mysql是不同的,real在某個時刻只能有乙個寫操作,且總是操作最新的資料版本,不能在老版本操作。

圖1 realm資料庫檔案管理圖示

realm資料庫使用了零拷貝技術,這是與coredata及其他資料庫完全不同的地方。

通常的資料庫操作是這樣的,資料儲存在磁碟的資料庫檔案中,我們的查詢請求會轉換為一系列的sql語句,建立乙個資料庫連線。資料庫伺服器收到請求,通過解析器對sql語句進行詞法和語法語義分析,然後通過查詢優化器對sql語句進行優化,優化完成執行對應的查詢,讀取磁碟的資料庫檔案(有索引則先讀索引),返回對應的資料內容並儲存到記憶體中,資料還需要序列化成記憶體可儲存的格式,最後資料還要轉換成語言層面的型別,比如objective-c的物件等。

零拷貝架構也使得realm可以自動更新物件和查詢。在乙個查詢中更新物件,在另外乙個查詢中可以馬上讀取到更新的內容。多執行緒同時更新資料也是一樣,可以即時更新物件的內容。正是因為物件的自動更新,所以realm中也是不允許多執行緒之間的物件共享,因為如果多執行緒共享realm物件,會導致資料的不一致性,雖然通過加鎖是可以保證資料一致性的,但是會增加開銷。

因此,在使用realm的時候,不要在多個執行緒之間共享物件。如果要在另外乙個執行緒獲取同樣的資料,請重新執行查詢。多執行緒更新資料的操作後面會有例子演示。

realm objective-c支援的資料型別有bool、bool、int、nsinteger、long、long long、float、double、nsstring、nsdate、nsdata 以及 被特殊型別標記的 nsnumber,注意:realm不支援auto_increment型別。realm中涉及的幾個類和概念如下:

這是realm資料庫框架的核心,它是乙個訪問底層資料庫的指標,有點類似coredata中的managedobjectcontext物件。在**中可以通過[rlmrealm defaultrealm]獲取。

這是realm的物件模型。自己定義的物件要繼承該類,然後可以定義自己的屬性。也可以定義主鍵(覆寫+ (nsstring *)primarykey方法)和索引(覆寫+ (nsarray*)indexedproperties方法)等。

realm中所有涉及資料更改的操作如insert,delete,update等,必須在乙個write事務中執行。

[[rlmrealm defaultrealm] transactionwithblock:^];
查詢操作很簡單,不需要在乙個write事務中執行。realm所有的查詢操作都是延遲載入的,只有當屬性被訪問的時候,才會讀取相應的資料。查詢結果並不是資料的拷貝,修改查詢結果(在寫入事務中)會直接修改硬碟上的資料。查詢物件的基本方法是rlmobjectallobjects方法,查詢的結果是乙個rlmresults物件。還可以條件查詢並對結果排序,**如下:

rlmresults*dogs = [dog allobjects]; // 從預設的 realm 資料庫中,檢索所有狗狗

// 使用斷言字串查詢

rlmresults*tandogs = [dog objectswhere:@"color = '白色' and name beginswith '小'"];

// 使用 nspredicate 查詢

nspredicate *pred = [nspredicate predicatewithformat:@"color = %@ and name beginswith %@", @"白色", @"小"];

tandogs = [dog objectswithpredicate:pred];

// 排序名字以「大」開頭的黑色狗狗

rlmresults*sorteddogs = [[dog objectswhere:@"color = '黑色' and name beginswith '大'"] sortedresultsusingproperty:@"name" ascending:yes];

與其他資料庫不同的是,realm並沒有提供limit之類的關鍵字來限制一次載入的資料量。因為realm中的查詢是延遲載入的,只有在查詢結果被使用到的時候,才會讀取資料庫檔案去載入物件,所以並不用limit來實現分頁。

當我們需要修改資料模型時,比如增減屬性,屬性重新命名等,都進行資料遷移。後面的一節會有例項介紹。

#podfile

platform :ios, 『9.0』

use_frameworks!

target 『realmstart』 do

pod 'realm', '~> 0.98'

end

我這裡新建了三個類,分布是dog,person以及company。其中dog和person是多對多的關係,即乙隻狗可以屬於多個人,而乙個人可以有多隻狗。person和company為多對一的關係,即乙個人只能屬於乙個公司,乙個公司可以有很多人。

**如下:

#import @inte***ce dog : rlmobject @property (nonatomic, strong) nsstring *name; @property (nonatomic, strong) nsstring *color; @property (nonatomic, readonly) rlmlinkingobjects *owners; @end rlm_array_type(dog) //必須加這個巨集定義 #import "dog.h" #import "person.h" @implementation dog //反向鏈結 + (nsdictionary *)linkingobjectsproperties ; } @end #import #import "company.h" #import "dog.h" @inte***ce person : rlmobject @property (nonatomic, strong) nsstring *name; @property (nonatomic) nsinteger age; @property (nonatomic, strong) company *company; @property (nonatomic, strong) rlmarray*dogs; //一對多 @end #import "person.h" @implementation person //為屬性name加索引 + (nsarray*)indexedproperties @end #import @inte***ce company : rlmobject @property (nonatomic, strong) nsstring *name; @end #import "company.h" @implementation company @end
/**

清理資料庫檔案,為測試環境做準備。

*/- (void)cleanrealm

}}/**

新增測試資料

*/- (void)addinitdatatorealm ];

}/**

查詢測試

*/- (void)queryrealm

}/**

更新測試

*/- (void)updaterealm

}];}/**

多執行緒測試

*/- (void)multithreadrealm

[[rlmrealm defaultrealm] transactionwithblock:^

}];if (results.count > 0)

});nsarray *names = @[@"張三", @"李四"];

[[rlmrealm defaultrealm] transactionwithblock:^ else

sleep(3);

}i++;

}}];

}/**

多執行緒輸出:

2016-07-16 20:34:31.103 realmstart[32013:1565410] change name to lisi

2016-07-16 20:34:32.104 realmstart[32013:1565455] start async

2016-07-16 20:34:32.108 realmstart[32013:1565455] outer block, name:張三

2016-07-16 20:34:34.172 realmstart[32013:1565410] change name to wangwu

2016-07-16 20:34:37.248 realmstart[32013:1565455] in async block

*/

- (void)migraterealm 

};[rlmrealmconfiguration setdefaultconfiguration:config];

[rlmrealm defaultrealm];

}

Oracle 基本知識

乙個表空間只能屬於乙個資料庫 每個資料庫最少有乙個控制檔案 建議3個,分別放在不同的磁碟上 每個資料庫最少有乙個表空間 system表空間 建立system表空間的目的是盡量將目的相同的表存放在一起,以提高使用效率,只應存放資料字典 每個資料庫最少有兩個聯機日誌組,每組最少乙個聯機日誌檔案 乙個資料...

Oracle 基本知識

乙個表空間只能屬於乙個資料庫 每個資料庫最少有乙個控制檔案 建議3個,分別放在不同的磁碟上 每個資料庫最少有乙個表空間 system表空間 建立system表空間的目的是盡量將目的相同的表存放在一起,以提高使用效率 每個資料庫最少有兩個聯機日誌檔案 乙個資料檔案只能屬於乙個表空間 乙個資料檔案一旦被...

Oracle 基本知識

oracle 文章摘要 oracle 基本知識。正文 oracle 基本知識 乙個表空間只能屬於乙個資料庫 每個資料庫最少有乙個控制檔案 建議3個,分別放在不同的磁碟上 每個資料庫最少有乙個表空間 system表空間 建立system表空間的目的是盡量將目的相同的表存放在一起,以提高使用效率 每個資...