MR_COUNTERの使用
SQL文を使用して複数リージョン表でMR_COUNTERを作成および管理する方法について学習します。
MR_COUNTERデータ型は、競合のないレプリケートされたデータ型(CRDT)カウンタです。CRDTを使用すると、ユーザーの介入なしで、複数のリージョンにわたり同時変更をマージできます。
Oracle NoSQL Databaseの複数リージョン設定では、同じデータのコピーを複数のリージョンに格納する必要があり、様々なリージョンでデータが同時に変更される場合があります。MR_COUNTERデータ型を使用すると、様々なリージョンで同時にデータ変更が実行されても、データは常に、自動的マージされて一貫性のある状態になります。
現在、Oracle NoSQL Databaseでは、正/負(PN)のMR_COUNTERデータ型のみがサポートされています。PNカウンタは、増分操作と減分操作に適しています。たとえば、これらのカウンタを使用して、任意の時点でWebサイトからサッカーの試合をライブ・ストリーミングしている視聴者の数をカウントできます。視聴者がオフラインになったときに、そのカウンタを減分する必要があります。
MR_COUNTERを定義できるのは、表の作成中または表の変更中のみです。
MR_COUNTERデータ型を使用した表の作成
CREATE TABLE Users (
id integer,
firstname string,
lastname string,
age integer,
income integer,
count integer AS MR_COUNTER,
primary key (id)
) IN REGIONS FRA,LON; MR_COUNTERデータ型は、複数リージョン表の場合のみ使用できます。通常の表では使用できません。前述の文では、FRAリージョンとLONリージョンに複数リージョン表を作成して、countをINTEGER MR_COUNTERデータ型として含めています。複数リージョン表では、複数の列をMR_COUNTERデータ型として定義できます。
CREATE TABLE IF NOT EXISTS JSONPersons (
id integer,
person JSON (counter as INTEGER MR_COUNTER,
books.count as LONG MR_COUNTER),
primary key (id)
) IN REGIONS FRA,LON;前述の文では、JSONドキュメントperson内の2つのフィールドをMR_COUNTERとして指定しています。最初のフィールドcounterは、INTEGER MR_COUNTERデータ型です。2番目のフィールドcountは、ネストされたJSONドキュメントbooks内にあります。このcountフィールドはLONG MR_COUNTERデータ型です。
複数リージョン表への行の挿入
INSERT文を使用して、MR_COUNTER列を含む複数リージョン表にデータを挿入できます。次のオプションのどれかを使用して行を追加できます。どちらのオプションでも、MR_COUNTER列にデフォルト値0が挿入されます。
-
オプション1: MR_COUNTER列にキーワードDEFAULTを指定します。
INSERT INTO Users VALUES (10, "David", "Morrison", 25, 100000, DEFAULT);前述の文では、countMR_COUNTERに値DEFAULTを指定しています。SELECT * FROM Users;出力:{"id":10,"firstname":"David","lastname":"Morrison","age":25,"income":100000,"count":0} -
オプション2: 必要な列値のみをINSERT文に含めることで、MR_COUNTER列の値をスキップします。
INSERT INTO Users(id, firstname, lastname) VALUES (20, "John", "Anderson");前述の文では、特定の列に値を指定しています。SQLエンジンによって、対応する列にそれらの値が挿入され、MR_COUNTERにデフォルト値0が挿入され、他のすべての列にNULL値が挿入されます。SELECT * FROM Users WHERE id = 20;出力:{"id":20,"firstname":"John","lastname":"Anderson","age":null,"income":null,"count":0}
MR_COUNTERがJSONドキュメントの一部である場合は、MR_COUNTERに値0を明示的に指定する必要があります。
ノート:
- JSON MR_COUNTERの挿入時にキーワードDEFAULTを指定することはできません。
- 宣言されたJSON MR_COUNTERフィールドに値を指定せずに、またはキーワードDEFAULTを使用せずに、MR表にデータを挿入しようとすると、エラーが返されます。
次の例では、JSONPersons表に行を挿入しています。peopleドキュメントにJSON MR_COUNTER counterおよびcountが含まれているため、これらのMR_COUNTERに値0を明示的に指定しています。
INSERT INTO JSONPersons VALUES (
1,
{
"firstname":"David",
"lastname":"Morrison",
"age":25,
"income":100000,
"counter": 0,
"books" : {
"Title1" : "Gone with the wind",
"Title2" : "Oliver Twist",
"count" : 0
}
}
);{"id":1,"person":{"age":25,"books":{"Title1":"Gone with the wind","Title2":"Oliver Twist","count":0},"counter":0,"firstname":"David","income":100000,"lastname":"Morrison"}};MR_COUNTERの更新
UPDATE Users SET count = count + 10 WHERE id = 10 RETURNING *;Users表内のcountの値を10ずつ増やしています。RETURNING句では、次の出力がフェッチされます:{"id":10,"firstname":"David","lastname":"Morrison","age":25,"income":100000,"count":10}UPDATE JSONPersons p SET p.person.books.count = p.person.books.count + 1 WHERE id = 1 RETURNING *;countを1ずつ増分しています。{"id":1,"person":{"age":25,"books":{"Title1":"Gone with the wind","Title2":"Oliver Twist","count":1},"counter":0,"firstname":"David","income":100000,"lastname":"Morrison"}}MR_COUNTERを使用して同時変更を処理する方法
複数リージョン表を様々なリージョンに作成した場合、それには同じ定義があります。これは、MR_COUNTERデータ型を定義した場合はそれがリモート・リージョンとローカル・リージョンの両方に存在するということです。すべてのリージョンで、その最後にMR_COUNTERを同時に更新できます。参加リージョン内のすべての複数リージョン表が同期されると、これらの同時変更に関して自動的にマージが実行されて、ユーザーの介入なしでMR_COUNTERの最新の更新が反映されます。
MR_COUNTERを追加または削除するための表の変更
ALTER TABLE文を使用して、MR_COUNTERを追加または削除できます。
MR_COUNTERの追加
ALTER TABLE Users (ADD countTwo INTEGER AS MR_COUNTER);前述の文では、デフォルト値0でMR_COUNTERとしてcountTwoフィールドをUsers表に追加しています。
{"id":10,"firstname":"David","lastname":"Morrison","age":25,"income":100000,"count":10,"countTwo":0}
{"id":20,"firstname":"John","lastname":"Anderson","age":null,"income":null,"count":0,"countTwo":0}ALTER TABLE JSONPersons (ADD JsonTwo JSON(counterTwo AS NUMBER MR_COUNTER));JsonTwoがJSONPersons表に追加され、counterTwoフィールドが値0でMR_COUNTERとして含まれます。{
"id" : 1,
"person" : {
"age" : 25,
"books" : {
"Title1" : "Gone with the wind",
"Title2" : "Oliver Twist",
"count" : 1
},
"counter" : 0,
"firstname" : "David",
"income" : 100000,
"lastname" : "Morrison"
},
"JsonTwo" : {
"counterTwo" : 0
}
}MR_COUNTERの削除
ALTER TABLE Users (DROP countTwo);前述の文では、Users表からcountTwo MR_COUNTERが削除されます。
{"id":10,"firstname":"David","lastname":"Morrison","age":25,"income":100000,"count":10}
{"id":20,"firstname":"John","lastname":"Anderson","age":null,"income":null,"count":0}ALTER TABLE JSONPersons (DROP JsonTwo);JSONPersons表から、ネストされたJSONドキュメントJSONTwoが削除されます。{
"id" : 1,
"person" : {
"age" : 25,
"books" : {
"Title1" : "Gone with the wind",
"Title2" : "Oliver Twist",
"count" : 1
},
"counter" : 0,
"firstname" : "David",
"income" : 100000,
"lastname" : "Morrison"
}
}