これまでのシリーズ:

  1. SQL Serverグラフデータベース-パート1:はじめに
  2. SQL Serverグラフデータベース-パート2:グラフデータベース内のデータのクエリ
  3. SQL Serverグラフデータベース-パート3:グラフデータベース内のデータの変更
  4. SQL Serverグラフデータベース-パート4:グラフデータベース内の階層データの操作
  5. SQL Serverグラフデータベース-パート5: グラフデータベースへのリレーショナルデータのインポート

SQL Server2017のリリースで、Microsoftはグラフデータベースのサポートを追加し、ソーシャルメディアサイトで生成されたデータの種類など、複雑なエンティティ関係を含むデータセットをより適切に処理しました。 グラフデータベースは、従来のSQL Serverデータベースと同じテーブル構造を使用し、同じツールとT-SQLステートメントをサポートしますが、複雑なリレーションシップを格納

この記事は、SQL Serverグラフデータベースに関するシリーズの最初の記事です。 この記事では、グラフの基本概念を紹介し、SQL Server Management Studio(SSMS)とSQL Server2017のローカルインスタンスを使用して、グラフテーブルを作成および設定する方法を示します。 以下の記事では、グラフデータベースをクエリしてデータを変更する方法について詳しく説明しますが、この記事では基本から始めます。

SQL Serverグラフデータベース

SQL Serverのグラフデータベースは、複雑な多対多および階層関係を含むデータのモデリングプロセスを簡素化するのに役立ちます。 最も基本的には、グラフデータベースは、さまざまなタイプの関係を定義するために連携するノードとエッジのコレクションです。 ノードは、人や場所などのエンティティです。 エッジは、2つのエンティティ間の関係です。 たとえば、トレドなどの場所と、トレドに住んでいるChrisという名前の人との間に関係が存在する場合があります。 クリスとトレドは実体であり、”lives in”は両者の関係です。

SQL Serverのノードテーブルは類似したエンティティのコレクションであり、エッジテーブルは類似したリレーションシップのコレクションです。 これがどのように機能するかを理解するために、架空の魚愛好家のフォーラムに基づいている次の図に示すグラフモデルを考えてみましょう。 このモデルには、3つのノード(FishSpecies、FishLover、およびFishPost)と3つのエッジ(Likes、Posts、およびLinksTo)が含まれます。

長方形はノードを表し、ノードを接続する矢印はエッジを表し、矢印はリレーションシップの方向を指します。 たとえば、”いいね”エッジは、次のリレーションシップのいずれかを定義できます:

  • 魚の恋人は魚種が好きです。
  • 魚好きは魚についての投稿が好きです。
  • 魚好きは別の魚好きが好きです。

3つのリレーションシップすべてを、グラフデータベースの単一のエッジテーブル内のデータとして表すことができ、各リレーションシップはそれ自身の行に ノードテーブルは、各エンティティの行を含む点を除いて、ほぼ同じように機能します。 また、プロパティをノードとエッジの両方に関連付けることもできます。 プロパティは、ノードまたはエッジテーブルの列として定義されるキーと値の属性です。 たとえば、FishSpeciesノードには、それぞれの種の共通名と学名を格納するためのプロパティが含まれている場合があります。 プロパティは、FishSpeciesテーブルのユーザー定義列として作成されます。 ノードテーブルを作成するときは、少なくとも1つのプロパティを含める必要があります。

ほとんどの操作では、ノードテーブルとエッジテーブルは他のSQL Serverユーザー定義テーブルと同じように機能します。 一時テーブルやテーブル変数をノードテーブルやエッジテーブルとして宣言できないなど、いくつかの制限がありますが、ほとんどの場合、グラフテーブルを使

物事が少し不明瞭になるのは、グラフデータベース自体です。 この名前は、新しいタイプのデータベースオブジェクトを作成していることを示唆しているかもしれませんが、そうではありません。 グラフデータベースは、ユーザー定義データベース内で定義された論理構造にすぎず、複数のグラフデータベースをサポートできません。 グラフデータベースの存在は外部から比較的透明であり、ほとんどの場合、あなたが心配する必要があるものではありません。 グラフデータベースを使用する場合、主な焦点はグラフテーブルとそれに含まれるデータになります。

一般に、グラフデータベースには、従来のリレーショナル機能を使用して達成できない機能はありません。 グラフデータベースの約束は、特定のタイプのデータをより効率的に整理して照会できることにあります。 次の状況では、グラフデータベースの実装を検討することをお勧めします:

  • 高度に相互接続されたデータとそのデータ間の関係を分析する必要があります。
  • あなたは、継続的に進化している複雑な多対多の関係を持つデータをサポートしています。
  • HierarchyIDデータ型の制限をナビゲートしようとしているときに、階層データを操作しています。

SQL Serverのグラフデータベース機能は、クエリプロセッサやストレージエンジンなどのコンポーネントを活用して、データベースエンジンに完全に統合されています。 この統合により、グラフデータベースは、列ストアインデックス、機械学習サービス、SSMS、その他のさまざまな機能やツールなど、さまざまなコンポーネントと組み合

グラフノードテーブルの定義

前の図に示すモデルに基づいてグラフデータベースを作成するには、三つのノードテーブルと三つのエッジテーブルを作成する必要 Microsoftは、SQL Server2017のCREATE TABLEステートメントを更新して、いずれかのテーブルタイプを定義するためのオプションを含めました。 すでに説明したように、任意のユーザー定義データベースにテーブルを作成できます。 この記事の例では、次のT-SQLコードに示すように、fishgraphという名前の基本的なデータベースを作成しました:

1
2
3
4
5
6

マスターを使用します;
移動
存在する場合はデータベースを削除しますFishGraph;
GO
データベースFishGraphを作成します。
GO

ご覧のように、ここでは特別なことは何もありません。 データベースは、他のユーザー定義データベースと同じように作成します。 グラフデータベースをサポートするように設定するために必要な特別なことは何もありません。

これらの例を自分で試してみる予定の場合は、FishGraphデータベースまたは自分で選択したいずれかを使用できます。 次のステップでは、次のCREATE TABLEステートメントを使用して、FishSpeciesノードテーブルを作成します:

1
2
3
4
5
6
7
8
9

使用FishGraph;
GO
DROP TABLE IF EXISTS FishSpecies;
GO
CREATE TABLE FishSpecies(
FISHID INT IDENTITY PRIMARY KEY,
CommonName NVARCHAR(100)NOT NULL,
scientificname nvarchar(100)not NULL
)ノードとして;

列の定義は非常に簡単でなければなりません。 ここで重要なのは、ノードテーブルを作成するために含める必要があるAS NODE句です。 この句を指定すると、データベースエンジンはテーブルに2つの列を追加し(これは後で説明します)、それらの列の1つに一意の非クラスター化インデックスを作成します。

sysを照会することで、テーブルがノードテーブルとして作成されているかどうかを確認できます。テーブルビュー。 SQL Server2017のリリースでは、Is_nodeおよびis_edgeビット列を含めるようにビューが更新されました。 テーブルがノードテーブルの場合、is_node列の値は1に設定され、is_edge列の値は0に設定されます。 エッジテーブルの場合、値は逆になります。 次の例では、このビューを使用して、FishSpeciesテーブルが正しく定義されていることを確認します:

1
2

sysからis_node、is_edgeを選択します。テーブル
where name=’FishSpecies’;

SELECTステートメントは、FishSpeciesがノードテーブルとして作成されたことを示す次の図に示す結果を返します。

マイクロソフトもsysを更新しました。列graph_type列とgraph_type_desc列を含めるためのビュー。 ビューと新しい列を使用して、FishSpeciesテーブルの詳細を知ることができます:

1
2
3

sysからname,graph_type,graph_type_desc
を選択します。列
ここで、object_id=OBJECT_ID(‘FishSpecies’);

次の図は、FishSpeciesテーブル用に作成された列を示しています。

ノードテーブルを作成すると、データベースエンジンはgraph_id_<hex_string>列と$node_id_<hex_string>列を追加し、unique node_id列に一意の非クラスタ化インデックスを作成します。 データベースエンジンは、最初の列を内部操作に使用し、2番目の列を外部アクセスに使用できるようにします。 Nod node_id列には、各エンティティの一意の識別子が格納され、データを照会するときに表示できます。 これは、あなたが気にする必要がある2つの唯一の列です。 実際、テーブルを直接照会すると、graph_id列ではなく$node_id列のみが表示されます。

sysによって返されるgraph_type列とgraph_type_desc列。列ビューは、グラフテーブル内の自動生成された列に固有のものです。 列は、データベースエンジンが生成した列のタイプを示します。 型は、事前定義された数値とそれに関連する説明によって示されます。 Microsoftでは、これらのコードと説明について多くの詳細を提供していませんが、Microsoft document SQL Graph Architectureでいくつかの詳細を見つけることができます。 繰り返しますが、主な関心事は$node_id列とそれに含まれるデータです。

テーブルを作成したら、データの追加を開始できます。 ノードテーブルに対してINSERTステートメントを実行すると、他のテーブルと同じように動作します。 次の例に示すように、ターゲット列とその値を指定します:

1
2
3
4
5
6
7
8
9
10
11

INSERT INTO FishSpecies (CommonName, ScientificName) VALUES
(‘Atlantic halibut’, ‘Hippoglossus hippoglossus’),
(‘Chinook salmon’, ‘Oncorhynchus tshawytscha’),
(‘European seabass’, ‘Morone (Decentrarchus) labrax’),
(‘Gizzard shad’, ‘Dorosoma cepedianum’),
(‘Japanese striped knife jaw’, ‘Oplegnathus faciatus’),
(‘ノーザンパイク’,’エソックス-ルキウス’),
(‘太平洋のニシン’、’Clupea pallasi’),
(‘ニジマス’,’Oncorhynchus mykiss’),
(‘Sole(ドーバー)”、”ソレアソレアソレアソレアソレアソレ’),
(‘ホワイトベース”、”モローネ-クリソプス”‘);

もちろん、あなたはあなたが特定の愛情を持っているどんな魚種を追加することができます。 ここでの私の選択は完全に恣意的でした。 しかし、私のデータに固執してからFishSpeciesテーブルを照会すると、結果は次の図のようになります。

上記のように、graph_id列は結果に表示されませんが、auto node_id列は自動生成された値で完了します。 データベースエンジンは、各値をJSON文字列として作成し、型(ノードまたはエッジ)、スキーマ、テーブル、および各行に固有のBIGINT値を提供します。 予想どおり、データベースエンジンは、典型的なリレーショナルテーブルと同様に、ユーザー定義列の値も返します。

次のステップは、次のT-SQLコードを使用して、FishLoverノードテーブルを作成して移入することです:

1
2
3
4
5
6
7
8
9
10
11
12

DROP TABLE IF EXISTS FishLover;
GO
CREATE TABLE FishLover(
FishLoverID INT IDENTITY PRIMARY KEY,
Username NVARCHAR(50)NOT NULL,
)AS NODE;
Insert INTO FishLover(Username)VALUES
(‘powerangler’),
(‘ジェシー98’),
(‘引っ掛けられた’),
(‘ディープダイブ’),
(‘アンダーウォーターケーシーイ’);

この表には、FishLoverIDとUserNameの2つのユーザー定義列のみが含まれますが、必要な数の列を定義できます。 たとえば、アプリケーションの性質に応じて、姓と名、連絡先情報、およびその他の詳細を含めることができます。 テーブルを作成したら、クエリを実行してデータを検証できます。 結果は、次の図に示すようになります。

その後、同じ手順を実行してFishPostテーブルを作成し、必要なメッセージテキストを渡すことができます:

1
2
3
4
5
6
7
8
9
10
11
12
13

ドロップテーブルが存在する場合は、魚ポストを削除します。;
GO
CREATE TABLE FishPost(
PostID INT IDENTITY PRIMARY KEY,
Title NVARCHAR(50)NOT NULL,
MessageText NVARCHAR(800)NOT NULL
)AS NODE;
PostID INT IDENTITY PRIMARY KEY,
Postid Int IDENTITY PRIMARY KEY,
Title NVARCHAR(50)NOT NULL,
MessageText NVARCHAR(800)NOT NULL
)AS NODE;
insert into fishpost(title,messagetext)VALUES
(‘逃げたもの’,’私たちのチームは利用可能です。 Aeneasの利点は必要性を予約した。’),
(‘魚に関する研究’,’penatibus venenatis,nascetur ridiculus mus.’),
(‘フック、ラインとシンカー’、’Donec pede justo、fringilla vel、aliquet nec、vulputate eget、arcu。’),
(‘非常に多くの魚、そう少しの時間’、’Nullam dictum felis eu pede mollis pretium。 整数値の整数値。’),
(‘私の好きな魚’,’Aeneanレオligula,porttitor eu,consequat vitae,eleifend ac,enim.’);

次の図は、Lorem Ipsumデータで立ち往生した場合に表示される結果を示しています。

ノードテーブルを作成して移入するのはこれですべてです。 CREATE TABLE文のAS NODE句を除いて、他のほとんどのものは通常どおりビジネスです。

グラフエッジテーブルの定義

エッジテーブルの作成は、AS NODE句ではなくAS EDGE句を指定する必要がある点を除いて、ノードテーブルの作成に似ています。 たとえば、Postsテーブルを作成するには、次のCREATE TABLEステートメントを使用します:

1
2
3
4
5

ポストが存在する場合は、テーブルを削除します;
移動します
テーブルポストを作成します(
ImportantFlagビットNULLでないデフォルト0
)エッジとして;

テーブル定義はノードテーブルに似ていますが、主キー列が含まれていない点が異なります(もちろん、AS EDGE句を使用します)。 この場合、主キーは必要ありませんが、ある時点で主キーが必要であると判断した場合は、確実に追加できます。 (主キーがノードテーブルに役立つ理由はすぐにわかります。)

テーブル定義にはImportantFlag列も含まれていることに注意してください。 これは主に、ノードテーブルと同様に、ユーザー定義の列をエッジテーブルに追加できることを示すために含まれています。 つまり、少なくとも1つのユーザー定義列を含める必要があるノードテーブルとは異なり、ユーザー定義列なしでエッジテーブルを作成することは珍しくありませ

エッジテーブルを作成した後、sysを照会することで、エッジテーブルが正しく定義されていることを確認できます。前に見たように、テーブルビュー:

1
2

sysからis_node、is_edgeを選択します。テーブル
where name=’Posts’;

すべてのことを正しく実行した場合、結果は次の図のようになります。

sysを照会することもできます。以前と同じように、列の詳細を確認するためのテーブルビュー:

1
2
3

sysからname,graph_type,graph_type_desc
を選択します。列
ここで、object_id=OBJECT_ID(‘Posts’);

次の図は、私のシステムで返された結果を示しています。

ご覧のとおり、データベースエンジンは、ノードテーブルで見た2つの列ではなく、1つのエッジテーブルに8つの列を追加します。 ここでも、各列タイプの説明については、SQL Graph Architectureのドキュメントを参照してください。 これらの列の大部分は、内部操作のためにデータベースエンジンによって使用されます。 主に次の3つの列に注意する必要があります:

  • ed edge_id_<hex_string>列は、各リレーションシップを一意に識別します。
  • The from_id_<hex_string>列には、リレーションシップが発生したテーブルのエンティティに関連付けられた$node_id値が格納されます。
  • The to_id_<hex_string>列は、リレーションシップが終了するテーブル内のエンティティに関連付けられた$node_id値を格納します。

ノードテーブルの$node_id列と同様に、データベースエンジンは$edge_id列の値を自動的に生成します。 ただし、リレーションシップを定義するには、values from_id列とcolumns to_id列に具体的に値を追加する必要があります。 これがどのように機能するかを実証するために、単一のレコードから始めます:

1
2
3

INSERT INTO Posts(from from_id,to to_id)VALUES(
(FISHLOVERからSELECT node_idを選択します)FishLoverID= 1),
(PostIDのFishPostからSELECT node_idを選択します= 3));

INSERTステートメントは、Fishloverid値が1のFishLoverエンティティとPostID値が3のFishPostエンティティとの間のpostsテーブル内のリレーションシップを定義しています。 Hex node_id、from from_id、およびto to_idエイリアスを使用して、16進数の文字列を指定することなく、ターゲット列を参照できることに注意してください。

data from_id列にデータを追加するには、FishLoverエンティティに関連付けられた$node_id値を指定する必要があります。 この値を取得する1つの方法は、主キー値を使用してエンティティを対象とするサブクエリを含めることです。 あなたはcolumn from_id列に対して同じアプローチを取ることができます。

この方法でデータを挿入すると、主キーをノードテーブルに追加するのが便利ですが、エッジテーブルには必要ない理由がわかります。 ノードテーブルの主キーを使用すると、INSERT文にnod node_id値を提供するのがはるかに簡単になります。

ここでPostsテーブルを照会すると、結果は次の図に示すようになります。

テーブルには、ImportantFlagがデフォルトの0に設定された新しい関係が含まれている必要があります。 次のINSERTステートメントを使用して、さらにいくつかの行を追加できるようになりました:

1
2
3
4
5
6
7
8
9
10
11
12

INSERT INTO Posts(from from_id,to to_id)VALUES(
(FISHLOVERからSELECT node_idを選択します)FishLoverID= 3),
(FishpostからPos node_idを選択します。PostID=2));
ポストに挿入(from from_id,to to_id)値(
(選択Fish node_id From FishLover WHERE FishLoverID= 2),
(PostIDのFishPostからSELECT node_idを選択します= 5));
INSERT INTO Posts(from from_id,to to_id,ImportantFlag)VALUES(
(SELECT Fish node_id FROM FishLover WHERE FishLoverID= 5),
(FishpostからSELECT node_idを選択します。PostID=4)、1);
INSERT INTO Posts(from from_id,$to_id,ImportantFlag)VALUES(
(SELECT Fish node_id FROM FishLover WHERE FishLoverID= 4),
(PostIDのFishPostからSELECT node_idを選択します= 1), 1);

最後の2つのINSERT文では、ImportantFlag列の値も提供されていることに注意してください。 Postsテーブルを照会すると、結果に5つの行すべてが含まれるようになります。

次の手順では、次のT-SQLコードを使用して、Likesテーブルを作成して移入します:

1
2
3
4
5
6
7
8
9
10
11
12

DROP TABLE IF EXISTS Likes;
GO
CREATE TABLE LIKES AS EDGE;
INSERT INTO Likes(from from_id,to to_id)VALUES(
(SELECT Fish node_id FISHLOVER WHERE FishLoverIDからnod node_idを選択します= 3),
(FISHSPECIESからSELECT node_idを選択します。FishID=8));
Likes(from from_id,to to_id)値に挿入(
(FISHLOVERからFish node_idを選択します)FishLoverID= 5),
(PostIDのFishPostからSELECT node_idを選択します= 4));
Likes(from from_id,to to_id)値に挿入します(
(FishLoverからSELECT node_idを選択します)FishLoverID= 1),
(FishLoverからFish node_idを選択し、FishLoverIDを選択します= 4));

もちろん、必要な関係を定義することができます。 ここで注意すべき重要な点は、ノードのいずれかのセットに限定されないということです。 たとえば、最初のINSERTステートメントはFishLoverとFishSpeciesの関係を作成し、2番目のステートメントはFishLoverとFishPostの関係を作成し、3番目のステートメントはfishloverとfishloverの関係を作成 これにより、次の図に示すクエリ結果が得られます。

LinksToテーブルを作成および移入するときも、同じ方法を取ることができます:

1
2
3
4
5
6
7
8
9
10
11
12

ドロップテーブルIf EXISTS LinksTo;
GO
CREATE TABLE LinksTo AS EDGE;
INSERT INTO LinksTo(from from_id,to to_id)VALUES(
(SELECT Fish node_id FROM FishPost WHERE PostID= 2),
(FISHSPECIESからSELECT node_idを選択します。FishID=6));
LINKSTOに挿入(from from_id,to to_id)値(
(選択Fish node_idからFishpostどこPostID= 4),
(FishLoverからFish node_idを選択し、FishLoverIDを選択します= 1));
INSERT INTO LinksTo(from from_id,to to_id)VALUES(
(Select Fish node_id FROM Fishpost WHERE PostID= 3),
(PostIDのFishPostからSELECT node_idを選択します= 5));

次の図は、この例に従ったと仮定して、テーブルに追加した後のデータの外観を示しています。

グラフデータベースを使用すると、発生ノードと終了ノードの間に幅広いリレーションシップを追加できます。 また、グラフモデルへの変更を簡単に組み込むこともできます。 たとえば、ユーザーがフォーラムに投稿する魚のレシピを格納するためのFishRecipesノードテーブルを追加すると、既存のPosts、Likes、およびLinksToエッジテーブルを活用できます。

グラフデータベースの今後

Microsoftにはsql Serverデータベースエンジンの一部としてグラフデータベース機能が含まれているため、コンポーネントをインストールしたり再構成したりすることなく簡単に試すことができます。 何よりも、これまで使用してきたのと同じツールと手順を使用して、ノードテーブルとエッジテーブルを作成および移入できます。 以下の記事では、グラフデータのクエリと変更の方法について説明し、階層データの操作について詳しく説明しますので、必ずお楽しみにしてください。

コメントを残す

メールアドレスが公開されることはありません。