適用対象: Sql Server 2017 (14.x) 以降のバージョン
Azure SQL Database
Azure SQL Managed Instance
SQL データベース
SQL Graph のアーキテクチャについて説明します。 基本を理解すると、他の SQL Graph の記事を理解しやすくなります。
SQL Graph データベース
ユーザーは、データベースごとに 1 つのグラフを作成できます。 グラフは、ノード テーブルとエッジ テーブルのコレクションです。 ノード テーブルまたはエッジ テーブルは、データベース内の任意のスキーマの下に作成できますが、これらはすべて 1 つの論理グラフに属します。 ノード テーブルは、同様の種類のノードのコレクションです。 たとえば、 Person ノード テーブルには、グラフに属するすべての Person ノードが保持されます。 同様に、エッジ テーブルは、同様の種類のエッジのコレクションです。 たとえば、 Friends エッジ テーブルは、 Person を別の Personに接続するすべてのエッジを保持します。 ノードとエッジはテーブルに格納されるため、通常のテーブルでサポートされるほとんどの操作はノード テーブルまたはエッジ テーブルでサポートされます。
次の図は、SQL Graph データベースのアーキテクチャを示しています。
ノードテーブル
ノード テーブルは、グラフ スキーマ内のエンティティを表します。 ノード テーブルがユーザー定義列と共に作成されるたびに、暗黙的な $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() およびその他の関連する System Functions の使用を検討してください。
述語でグラフの擬似列 ($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
bit の次の列を使用して、グラフ テーブルを識別できます。
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 | テーブルを作成 (Transact-SQL) |
CREATE TABLE は、テーブル AS NODE または AS EDGE の作成をサポートするように拡張されました。 エッジ テーブルには、ユーザー定義属性は必要ありません。 |
| アルターテーブル | テーブル変更 (Transact-SQL) | ノード テーブルとエッジ テーブルは、リレーショナル テーブルと同じように、 ALTER TABLEを使用して変更できます。 ユーザーは、ユーザー定義の列、インデックス、または制約を追加または変更できます。 ただし、 $node_id や $edge_idなどの内部グラフ列を変更すると、エラーが発生します。 |
| インデックスを作成 | インデックス作成 (Transact-SQL) | ユーザーは、ノード テーブルとエッジ テーブルの擬似列とユーザー定義列にインデックスを作成できます。 クラスター化列ストア インデックスと非クラスター化列ストア インデックスを含め、すべてのインデックスの種類がサポートされています。 |
| エッジ制約の作成 | EDGE 制約 (Transact-SQL) | ユーザーはエッジ テーブルにエッジ制約を作成して、特定のセマンティクスを適用し、データの整合性を維持できるようになりました |
| ドロップテーブル | DROP TABLE (Transact-SQL) (テーブルを削除するSQLコマンド) | ノード テーブルとエッジ テーブルは、 DROP TABLEを使用してリレーショナル テーブルと同じように削除できます。 現時点では、エッジによって参照されるノードの削除を防ぐメカニズムはありません。 ノードを削除した場合 (またはノード テーブル全体を削除する) 場合、エッジの連鎖削除はサポートされません。 このような場合はすべて、グラフの一貫性を維持するために、削除されたノードに接続されているエッジを手動で削除する必要があります。 |
データ操作言語 (DML) ステートメント
| Task | 関連記事 | Notes |
|---|---|---|
| INSERT | 挿入(Transact-SQL) | ノード テーブルへの挿入は、リレーショナル テーブルへの挿入と同じ違いはありません。
$node_id列の値が自動的に生成されます。
$node_idまたは$edge_id列に値を挿入しようとすると、エラーが発生します。 ユーザーは、エッジ テーブルに挿入するときに、 $from_id 列と $to_id 列の値を指定する必要があります。
$from_id
$to_idは、特定のエッジが接続するノードの$node_id値です。 |
| DELETE | 削除(Transact-SQL) | ノード テーブルまたはエッジ テーブルのデータは、リレーショナル テーブルから削除するのと同じ方法で削除できます。 ただし、このリリースでは、削除されたノードを指すエッジがなく、ノードの削除時にエッジが連鎖的に削除されないようにする制約はサポートされていません。 ノードが削除されるたびに、そのノードへの接続エッジもすべて削除することをお勧めします。 |
| UPDATE | 更新(Transact-SQL) | ユーザー定義列の値は、UPDATE ステートメントを使用して更新できます。 内部グラフの列、 $node_id、 $edge_id、 $from_id 、 $to_idを更新することはできません。 |
| MERGE | マージ(Transact-SQL) |
MERGE ステートメントは、ノードまたはエッジ テーブルでサポートされています。 |
クエリ文
| Task | 関連記事 | Notes |
|---|---|---|
| SELECT | SELECT(Transact-SQL) | ノードとエッジはテーブルとして格納されるため、ほとんどのテーブル操作はノード テーブルとエッジ テーブルでもサポートされます。 |
| MATCH | マッチ(Transact-SQL) | MATCH 組み込みは、グラフを介したパターン マッチングとトラバーサルをサポートするために導入されています。 |
Limitations
ノード テーブルとエッジ テーブルには、特定の制限があります。
- ローカルまたはグローバルの一時テーブルをノード テーブルまたはエッジ テーブルにすることはできません。
- テーブルの型とテーブル変数は、ノード テーブルまたはエッジ テーブルとして宣言できません。
- ノード テーブルとエッジ テーブルは、システム バージョン管理されたテンポラル テーブルとして作成できません。
- ノード テーブルとエッジ テーブルをメモリ最適化テーブルにすることはできません。
- ユーザーは、UPDATE ステートメントを使用してエッジの
$from_id列と$to_id列を更新できません。 エッジによって参照されるノードを更新するには、ユーザーは新しいノードを指す新しいエッジを挿入し、前のノードを削除する必要があります。 - グラフ オブジェクトに対するデータベース間クエリはサポートされていません。
- グラフの擬似列 (
node_id、$from_id、$to_id、edge_id) は、 順序付けされたクラスター化列ストア インデックスの並べ替え列として使用できません。 順序付けされたクラスター化列ストアの並べ替え列としてグラフの擬似列を使用しようとすると、Msg 102: Incorrect syntaxエラーが発生します。 - Fabric SQL データベースでは、SQL Graph は許可されますが、Node テーブルと Edge テーブルは Fabric OneLake にミラーリングされません。
こちらも参照ください
次のステップ
- SQL Graph の使用を開始するには、「 SQL Graph データベース - サンプル」を参照してください。