SQL Graph のアーキテクチャ

適用対象: Sql Server 2017 (14.x) 以降のバージョン Azure SQL DatabaseAzure SQL Managed InstanceSQL データベース

SQL Graph のアーキテクチャについて説明します。 基本を理解すると、他の SQL Graph の記事を理解しやすくなります。

SQL Graph データベース

ユーザーは、データベースごとに 1 つのグラフを作成できます。 グラフは、ノード テーブルとエッジ テーブルのコレクションです。 ノード テーブルまたはエッジ テーブルは、データベース内の任意のスキーマの下に作成できますが、これらはすべて 1 つの論理グラフに属します。 ノード テーブルは、同様の種類のノードのコレクションです。 たとえば、 Person ノード テーブルには、グラフに属するすべての Person ノードが保持されます。 同様に、エッジ テーブルは、同様の種類のエッジのコレクションです。 たとえば、 Friends エッジ テーブルは、 Person を別の Personに接続するすべてのエッジを保持します。 ノードとエッジはテーブルに格納されるため、通常のテーブルでサポートされるほとんどの操作はノード テーブルまたはエッジ テーブルでサポートされます。

次の図は、SQL Graph データベースのアーキテクチャを示しています。

SQLグラフデータベースアーキテクチャを示す図。

ノードテーブル

ノード テーブルは、グラフ スキーマ内のエンティティを表します。 ノード テーブルがユーザー定義列と共に作成されるたびに、暗黙的な $node_id 列が作成され、データベース内の特定のノードが一意に識別されます。 $node_idの値は自動的に生成され、そのノード テーブルのグラフ テーブルのオブジェクト ID と内部で生成された bigint 値の組み合わせです。 ただし、 $node_id 列を選択すると、JSON 文字列の形式で計算された値が表示されます。 また、 $node_id は、一意のサフィックスを持つ内部名にマップされる擬似列です。 テーブルから $node_id 擬似列を選択すると、列名が $node_id_<unique suffix>として表示されます。

Note

クエリで擬似列を使用することは、内部 $node_id 列に対してクエリを実行する唯一のサポートされ、推奨される方法です。 クエリで $node_id_<hex_string> 列を直接使用しないでください。 また、擬似列に示されている計算された JSON 表現は、実装の詳細です。 その JSON 表現の形式に直接依存しないでください。 このJSON表現を扱う必要がある場合は、 NODE_ID_FROM_PARTS() や関連する システム機能の使用を検討してください。 述語でグラフの擬似列 ($node_id、 $from_id、 $to_id) を直接使用することはお勧めしません。 たとえば、 n.$node_id = e.$from_id のような述語は避ける必要があります。 このような比較は、JSON 表現への変換により非効率的になる傾向があります。 代わりに、可能な限り MATCH 関数に依存してください。

ユーザーは、ノード テーブルの作成時に $node_id 列に一意の制約またはインデックスを作成することをお勧めしますが、作成されていない場合は、既定の一意の非クラスター化インデックスが自動的に作成されます。 ただし、グラフの擬似列のインデックスは、基になる内部列に作成されます。 つまり、 $node_id 列に作成されたインデックスは、内部 graph_id_<hex_string> 列に表示されます。

エッジテーブル

エッジ テーブルは、グラフ内のリレーションシップを表します。 エッジは常に向きがあり、2 つのノードを接続します。 エッジ テーブルを使用すると、ユーザーはグラフ内の多対多リレーションシップをモデル化できます。 エッジ テーブルでは、ユーザー定義列 ("attributes") は省略可能です。 エッジ テーブルが作成されるたびに、ユーザー定義列と共に、エッジ テーブルに 3 つの暗黙的な列が作成されます。

列名 Description
$edge_id データベース内の特定のエッジを一意に識別します。 これは生成された列であり、値はエッジ テーブルのobject_idと内部で生成された bigint 値の組み合わせです。 ただし、 $edge_id 列を選択すると、JSON 文字列の形式で計算された値が表示されます。 $edge_id は、一意のサフィックスを持つ内部名にマップされる擬似列です。 テーブルから $edge_id を選択すると、列名が $edge_id_<unique suffix>として表示されます。 クエリで擬似列名を使用することは、内部 $edge_id 列に対してクエリを実行する場合に推奨される方法であり、16 進文字列で内部名を使用することは避ける必要があります。
$from_id エッジの起点となるノードの $node_id を格納します。
$to_id エッジが終了するノードの $node_id を格納します。

特定のエッジが接続できるノードは、 $from_id 列と $to_id 列に挿入されたデータによって制御されます。 最初のリリースでは、エッジ テーブルに制約を定義して、2 種類のノードの接続を制限することはできません。 つまり、エッジは、その種類に関係なく、グラフ内の任意の 2 つのノードを接続できます。

$node_id列と同様に、ユーザーはエッジ テーブルの作成時に$edge_id列に一意のインデックスまたは制約を作成することをお勧めしますが、作成されていない場合は、既定の一意の非クラスター化インデックスがこの列に自動的に作成されます。 ただし、グラフの擬似列のインデックスは、基になる内部列に作成されます。 つまり、 $edge_id 列に作成されたインデックスは、内部 graph_id_<unique suffix> 列に表示されます。 また、OLTP シナリオでは、エッジ方向の検索を高速化するために、ユーザーが ($from_id、 $to_id) 列にインデックスを作成することもお勧めします。

次の図は、ノード テーブルとエッジ テーブルをデータベースに格納する方法を示しています。

ノードと辺の表の表現を示す図。

Metadata

これらのメタデータ ビューを使用して、ノードまたはエッジ テーブルの属性を表示します。

sys.tables

sys.tables内の以下のビット列はグラフテーブルの識別に利用できます。 is_nodeが 1 に設定されている場合、テーブルはノード テーブルであり、is_edgeが 1 に設定されている場合、テーブルはエッジ テーブルになります。

列名 データ型 Description
is_node bit ノード テーブルの場合、 is_node は 1 に設定されます。
is_edge bit エッジ テーブルの場合、 is_edge は 1 に設定されます。

sys.columns

graph_type ビューのgraph_type_desc列とsys.columns列は、グラフ ノードとエッジ テーブルで使用されるさまざまな種類の列を理解するのに役立ちます。

列名 データ型 Description
graph_type int 値のセットを含む内部列。 値は、グラフ列は 1-8、その他は NULL です。
graph_type_desc nvarchar(60) 値のセットを含む内部列。

次の表に、 graph_type 列の有効な値を示します。

列の値 Description
1 GRAPH_ID
2 GRAPH_ID_COMPUTED
3 GRAPH_FROM_ID
4 GRAPH_FROM_OBJ_ID
5 GRAPH_FROM_ID_COMPUTED
6 GRAPH_TO_ID
7 GRAPH_TO_OBJ_ID
8 GRAPH_TO_ID_COMPUTED

sys.columns には、ノード テーブルまたはエッジ テーブルで作成された暗黙的な列に関する情報も格納されます。 以下の情報は sys.columnsから取得可能ですが、ユーザーはノードやエッジテーブルからこれらの列を選択することはできません。

ノード テーブル内の暗黙的な列は次のとおりです。

列名 データ型 is_hidden Comment
graph_id_\<hex_string> BIGINT 1 内部グラフ ID 値。
$node_id_\<hex_string> NVARCHAR 0 ノード ID の外部文字表現。

エッジ テーブルの暗黙的な列は次のとおりです。

列名 データ型 is_hidden Comment
graph_id_\<hex_string> BIGINT 1 内部グラフ ID 値。
$edge_id_\<hex_string> NVARCHAR 0 エッジ ID の文字表現。
from_obj_id_\<hex_string> INT 1 "from node" の内部 object_id 値。
from_id_\<hex_string> BIGINT 1 "from node" の内部グラフ ID 値。
$from_id_\<hex_string> NVARCHAR 0 "from node" の文字表現。
to_obj_id_\<hex_string> INT 1 "to node" の内部 object_id 。
to_id_\<hex_string> BIGINT 1 "to node" の内部グラフ ID 値。
$to_id_\<hex_string> NVARCHAR 0 "to node" の外部文字表現。

システム関数

次の組み込み関数を使用して、グラフ テーブル内の擬似列を操作できます。 これらの各関数の詳細な参照は、それぞれの T-SQL 関数参照で提供されます。

Built-in Description
OBJECT_ID_FROM_NODE_ID グラフ テーブルのオブジェクト ID を node_idから抽出します。
GRAPH_ID_FROM_NODE_ID node_idからグラフ ID 値を抽出します。
NODE_ID_FROM_PARTS グラフ テーブルのオブジェクト ID とグラフ ID 値からnode_idを作成します。
OBJECT_ID_FROM_EDGE_ID グラフ テーブルのオブジェクト ID を edge_idから抽出します。
GRAPH_ID_FROM_EDGE_ID 特定の edge_idのグラフ ID 値を抽出します。
EDGE_ID_FROM_PARTS グラフ テーブルとグラフ ID 値のオブジェクト ID から edge_id を構築します。

Transact-SQL 参考文献

グラフ オブジェクトの作成とクエリを有効にする SQL Server と Azure SQL Database で導入された Transact-SQL 拡張機能について説明します。 クエリ言語拡張機能は、ASCII アート構文を使用してグラフのクエリと走査を行うのに役立ちます。

データ定義言語 (DDL) ステートメント

Task 関連記事 Notes
CREATE TABLE CREATE TABLE (Transact-SQL) CREATE TABLE 現在はテーブル AS NODE または AS EDGEの作成をサポートするために拡張されています。 エッジ テーブルには、ユーザー定義属性は必要ありません。
ALTER TABLE ALTER TABLE (Transact-SQL) ノード テーブルとエッジ テーブルは、リレーショナル テーブルと同じように、 ALTER TABLEを使用して変更できます。 ユーザーは、ユーザー定義の列、インデックス、または制約を追加または変更できます。 ただし、 $node_id や $edge_idなどの内部グラフ列を変更すると、エラーが発生します。
CREATE INDEX CREATE INDEX (Transact-SQL) ユーザーは、ノード テーブルとエッジ テーブルの擬似列とユーザー定義列にインデックスを作成できます。 クラスター化列ストア インデックスと非クラスター化列ストア インデックスを含め、すべてのインデックスの種類がサポートされています。
CREATE EDGE CONSTRAINTS EDGE 制約 (Transact-SQL) ユーザーはエッジ テーブルにエッジ制約を作成して、特定のセマンティクスを適用し、データの整合性を維持できるようになりました
DROP TABLE DROP TABLE (Transact-SQL) ノード テーブルとエッジ テーブルは、 DROP TABLEを使用してリレーショナル テーブルと同じように削除できます。 現時点では、エッジによって参照されるノードの削除を防ぐメカニズムはありません。 ノードを削除した場合 (またはノード テーブル全体を削除する) 場合、エッジの連鎖削除はサポートされません。 このような場合はすべて、グラフの一貫性を維持するために、削除されたノードに接続されているエッジを手動で削除する必要があります。

データ操作言語 (DML) ステートメント

Task 関連記事 Notes
INSERT INSERT (Transact-SQL) ノード テーブルへの挿入は、リレーショナル テーブルへの挿入と同じ違いはありません。 $node_id列の値が自動的に生成されます。 $node_idまたは$edge_id列に値を挿入しようとすると、エラーが発生します。 ユーザーは、エッジ テーブルに挿入するときに、 $from_id 列と $to_id 列の値を指定する必要があります。 $from_id $to_idは、特定のエッジが接続するノードの$node_id値です。
DELETE DELETE (Transact-SQL) ノード テーブルまたはエッジ テーブルのデータは、リレーショナル テーブルから削除するのと同じ方法で削除できます。 ただし、このリリースでは、削除されたノードを指すエッジがなく、ノードの削除時にエッジが連鎖的に削除されないようにする制約はサポートされていません。 ノードが削除されるたびに、そのノードへの接続エッジもすべて削除することをお勧めします。
UPDATE UPDATE (Transact-SQL) ユーザー定義の列の値は UPDATE 文を使って更新できます。 内部グラフの列、 $node_id、 $edge_id、 $from_id 、 $to_idを更新することはできません。
MERGE MERGE (Transact-SQL) MERGE ステートメントは、ノードまたはエッジ テーブルでサポートされています。

クエリ文

Task 関連記事 Notes
SELECT SELECT(Transact-SQL) ノードとエッジはテーブルとして格納されるため、ほとんどのテーブル操作はノード テーブルとエッジ テーブルでもサポートされます。
MATCH マッチ(Transact-SQL) MATCH 組み込みは、グラフを介したパターン マッチングとトラバーサルをサポートするために導入されています。

Limitations

グラフテーブルはSQL Server 2017で導入されました。 グラフの機能や機能SQL Server 2016年やFabric Data Warehouseでは利用できません。

ノード テーブルとエッジ テーブルには、特定の制限があります。

  • ローカルまたはグローバルの一時テーブルをノード テーブルまたはエッジ テーブルにすることはできません。
  • テーブルの型とテーブル変数は、ノード テーブルまたはエッジ テーブルとして宣言できません。
  • ノード テーブルとエッジ テーブルは、システム バージョン管理されたテンポラル テーブルとして作成できません。
  • ノード テーブルとエッジ テーブルをメモリ最適化テーブルにすることはできません。
  • ユーザーは$from_id文を使ってエッジの$to_idやUPDATE列を更新することはできません。 エッジによって参照されるノードを更新するには、ユーザーは新しいノードを指す新しいエッジを挿入し、前のノードを削除する必要があります。
  • グラフ オブジェクトに対するデータベース間クエリはサポートされていません。
  • グラフの擬似列 (node_id、 $from_id、 $to_id 、 edge_id) は、 順序付けされたクラスター化列ストア インデックスの並べ替え列として使用できません。 順序付けされたクラスター化列ストアの並べ替え列としてグラフの擬似列を使用しようとすると、 Msg 102: Incorrect syntax エラーが発生します。
  • Fabric SQL データベースでは、SQL Graph は許可されますが、Node テーブルと Edge テーブルは Fabric OneLake にミラーリングされません。