Melintasi hubungan dengan kueri grafik

Selesai

Tip

Lihat tab Teks dan gambar untuk detail selengkapnya!

Beberapa hubungan data secara alami diwakili sebagai jaringan, termasuk koneksi sosial, hierarki organisasi, rekomendasi produk, dan pola deteksi penipuan. Meskipun Anda dapat memodelkan hubungan ini menggunakan kunci dan gabungan asing, kueri grafik menggunakan MATCH operator menyediakan cara yang lebih intuitif dan seringkali lebih efisien untuk melintasi data yang terhubung.

Memvisualisasikan struktur data grafik

Sebelum menulis kueri grafik, ini membantu memvisualisasikan bagaimana data grafik diatur. Pertimbangkan jejaring sosial sederhana di mana orang-orang saling mengenal dan membeli produk:

Diagram memperlihatkan model data grafik dengan simpul Orang dan Produk yang terhubung oleh tepi KNOWS dan PURCHASED.

Dalam model ini:

  • Simpul (kotak) mewakili entitas seperti orang dan produk
  • Tepi (panah) mewakili hubungan antar simpul. Arah panah menunjukkan arah hubungan (Alice tahu Bob, belum tentu Bob tahu Alice).

Nota

Diagram ini menggambarkan konsep grafik. Contoh kode di seluruh unit ini menggunakan data serupa tetapi disederhanakan untuk fokus pada fitur tertentu.

Memahami kemampuan grafik

Kemampuan grafik memperluas model relasional dengan simpul khusus dan tabel tepi. Simpul mewakili entitas seperti orang, produk, dan lokasi. Sisi mewakili hubungan di antara mereka, seperti hubungan "mengenal," "membeli," atau "berlokasi di."

Keuntungan utama kueri grafik adalah pencocokan pola. Alih-alih menulis gabungan multi-cara yang kompleks, Anda mengekspresikan pola yang Anda cari menggunakan sintaks gaya ASCII:

-- Traditional relational approach (multiple joins)
SELECT p1.Name, p2.Name
FROM Person AS p1
INNER JOIN Friendship AS f ON p1.PersonID = f.Person1ID
INNER JOIN Person AS p2 ON f.Person2ID = p2.PersonID;

-- Graph approach (pattern matching)
SELECT Person1.Name, Person2.Name
FROM Person AS Person1, Friendship, Person AS Person2
WHERE MATCH(Person1-(Friendship)->Person2);

Nota

Tabel grafik sepenuhnya kompatibel dengan fitur relasional yang ada. Anda dapat menggabungkan tabel grafik dengan tabel reguler, menggunakan indeks, dan menerapkan semua operasi T-SQL standar.

Membuat tabel simpul

Tabel node menyimpan entitas di grafik Anda. Buat menggunakan CREATE TABLE dengan AS NODE klausa:

-- Create a Person node table
CREATE TABLE dbo.Person (
    PersonID INT PRIMARY KEY,
    Name NVARCHAR(100) NOT NULL,
    Email NVARCHAR(200),
    Department NVARCHAR(50)
) AS NODE;

-- Create a Product node table
CREATE TABLE dbo.Product (
    ProductID INT PRIMARY KEY,
    Name NVARCHAR(200) NOT NULL,
    Category NVARCHAR(100),
    Price DECIMAL(10, 2)
) AS NODE;

-- Create a Location node table
CREATE TABLE dbo.Location (
    LocationID INT PRIMARY KEY,
    City NVARCHAR(100) NOT NULL,
    CountryRegion NVARCHAR(100) NOT NULL
) AS NODE;

SQL Server secara otomatis menambahkan $node_id kolom ke tabel simpul yang secara unik mengidentifikasi setiap simpul. Sistem menggunakan kolom ini secara internal untuk hubungan grafik.

Contoh berikut menyisipkan empat orang ke dalam tabel node Person, lalu mengkueri tabel untuk memperlihatkan kolom bisnis dan kolom yang dihasilkan sistem $node_id. Perhatikan bahwa pernyataan INSERT hanya menggunakan kolom yang ditentukan pengguna. SQL Server menghasilkan $node_id secara otomatis untuk setiap baris:

-- Insert person data using standard INSERT syntax
INSERT INTO dbo.Person (PersonID, Name, Email, Department)
VALUES 
    (1, 'Alice Johnson', 'alice@contoso.com', 'Engineering'),
    (2, 'Bob Smith', 'bob@contoso.com', 'Marketing'),
    (3, 'Carol Davis', 'carol@contoso.com', 'Engineering'),
    (4, 'David Lee', 'david@contoso.com', 'Sales');

-- Query shows the system-generated $node_id alongside user columns
SELECT $node_id, PersonID, Name FROM dbo.Person;

Membuat tabel sisi

Tabel Edge mewakili hubungan antara simpul. Buat menggunakan CREATE TABLE dengan AS EDGE klausa:

-- Create a "reports to" relationship edge
CREATE TABLE dbo.ReportsTo (
    StartDate DATE,
    ReportType NVARCHAR(50)
) AS EDGE;

-- Create a "purchased" relationship edge
CREATE TABLE dbo.Purchased (
    PurchaseDate DATE NOT NULL,
    Quantity INT NOT NULL,
    TotalAmount DECIMAL(10, 2)
) AS EDGE;

-- Create a "knows" relationship edge (social connection)
CREATE TABLE dbo.Knows (
    ConnectionDate DATE,
    ConnectionStrength INT  -- 1-10 scale
) AS EDGE;

SQL Server secara otomatis menambahkan kolom $edge_id, $from_id, dan $to_id ke tabel edge. Anda dapat menyisipkan sisi dengan menentukan nilai $from_id dan nilai $to_id dari node yang terhubung, seperti ini:

-- Alice reports to Bob
INSERT INTO dbo.ReportsTo ($from_id, $to_id, StartDate, ReportType)
SELECT 
    (SELECT $node_id FROM dbo.Person WHERE Name = 'Alice Johnson'),
    (SELECT $node_id FROM dbo.Person WHERE Name = 'Bob Smith'),
    '2023-01-15',
    'Direct';

-- Create social connections
INSERT INTO dbo.Knows ($from_id, $to_id, ConnectionDate, ConnectionStrength)
SELECT 
    (SELECT $node_id FROM dbo.Person WHERE Name = 'Alice Johnson'),
    (SELECT $node_id FROM dbo.Person WHERE Name = 'Carol Davis'),
    '2022-06-01',
    8;

Tip

Tabel Edge dapat menyimpan properti tentang hubungan itu sendiri, seperti tanggal, bobot, atau jenis. Ini berguna untuk analisis temporal atau algoritma grafik tertimbang.

Grafik kueri dengan pernyataan MATCH

Klausa MATCH menggunakan sintaks pola untuk menentukan hubungan yang ingin Anda temukan. Pola dasar menggunakan panah untuk memperlihatkan arah hubungan:

-- Find who reports to whom
SELECT 
    Employee.Name AS Employee,
    Manager.Name AS Manager,
    r.StartDate
FROM dbo.Person AS Employee, 
     dbo.ReportsTo AS r, 
     dbo.Person AS Manager
WHERE MATCH(Employee-(r)->Manager);

Arah panah penting:

  • (Node1)-(Edge)->(Node2): Edge beralih dari Node1 ke Node2
  • (Node1)<-(Edge)-(Node2): Edge beralih dari Node2 ke Node1

Contoh berikut menemukan semua orang yang mengenal Alice:

SELECT 
    Connector.Name AS PersonWhoKnowsAlice,
    k.ConnectionStrength
FROM dbo.Person AS Connector, 
     dbo.Knows AS k, 
     dbo.Person AS Target
WHERE MATCH(Connector-(k)->Target)
  AND Target.Name = 'Alice Johnson';

Melintasi beberapa hubungan

Kueri lompatan tunggal menemukan koneksi langsung, namun database graf unggul dalam penelusuran multi-hop. Anda dapat merantai beberapa pola tepi dalam satu MATCH klausul untuk mengikuti jalur melalui beberapa hubungan. Kemampuan ini memungkinkan Anda menjawab pertanyaan seperti "siapa teman saya?" atau "produk apa yang dibeli kolega saya?" tanpa menulis subkueri berlapis yang kompleks.

Contoh berikut menemukan teman-teman dengan menautkan dua hubungan KNOWS . Pola Person1-(k1)->Person2-(k2)->Person3 dimulai di Person1, mengikuti satu tepi KNOWS ke Person2, lalu mengikuti tepi KNOWS lain untuk mencapai Person3:

-- Find friends of friends (2-hop connections)
SELECT DISTINCT
    Person1.Name AS Person,
    Person3.Name AS FriendOfFriend
FROM dbo.Person AS Person1,
     dbo.Knows AS k1,
     dbo.Person AS Person2,
     dbo.Knows AS k2,
     dbo.Person AS Person3
WHERE MATCH(Person1-(k1)->Person2-(k2)->Person3)
  AND Person1.Name = 'Alice Johnson'
  AND Person3.Name <> Person1.Name;  -- Exclude self

Anda juga dapat menggabungkan berbagai jenis hubungan dalam satu traversal. Contoh berikut menelusuri dari KNOWS ke PURCHASED untuk mencari produk apa yang dibeli oleh orang-orang yang dikenal oleh seseorang tertentu:

-- Find products purchased by people in the same department
SELECT DISTINCT
    p1.Name AS Person,
    p1.Department,
    prod.Name AS Product
FROM dbo.Person AS p1,
     dbo.Knows AS k,
     dbo.Person AS p2,
     dbo.Purchased AS pu,
     dbo.Product AS prod
WHERE MATCH(p1-(k)->p2-(pu)->prod)
  AND p1.Department = p2.Department;

Penting

Setiap alias tabel tepi hanya dapat muncul sekali dalam satu MATCH pola. Untuk melintasi jenis tepi yang sama beberapa kali, gunakan alias terpisah.

Gunakan SHORTEST_PATH untuk traversal panjang variabel

Anda dapat menggunakan SHORTEST_PATH untuk menemukan koneksi terpendek di sejumlah variabel hubungan. Kata kunci FOR PATH menandai tabel yang berpartisipasi dalam pencocokan panjang variabel, dan kuantor seperti + (satu atau lebih) atau {1,3} (satu hingga tiga) mengontrol kedalaman traversal.

Contoh berikut menemukan semua orang yang dapat dijangkau dari Alice dalam tiga langkah dan menghitung jarak ke masing-masing orang tersebut:

SELECT 
    StartPerson.Name,
    LAST_VALUE(ReachablePerson.Name) WITHIN GROUP (GRAPH PATH) AS ReachablePerson,
    COUNT(ReachablePerson.Name) WITHIN GROUP (GRAPH PATH) AS Distance
FROM dbo.Person AS StartPerson,
     dbo.Knows FOR PATH AS k,
     dbo.Person FOR PATH AS ReachablePerson
WHERE MATCH(SHORTEST_PATH(StartPerson(-(k)->ReachablePerson){1,3}))
  AND StartPerson.Name = 'Alice Johnson';

Pilih antara grafik dan pendekatan relasional

Kueri grafik tidak selalu menjadi pilihan terbaik. Pertimbangkan panduan ini saat memutuskan antara grafik dan pendekatan relasional tradisional:

Gunakan kueri grafik saat:

  • Hubungan adalah fokus utama kueri Anda
  • Anda perlu melintasi variabel atau kedalaman yang tidak diketahui (teman-teman teman)
  • Data secara alami membentuk jaringan (grafik sosial, hierarki, rute)
  • Pola kueri akan memerlukan banyak gabungan mandiri dalam SQL relasional
  • Anda melakukan analisis temuan jalur atau konektivitas

Gunakan kueri relasional saat:

  • Hubungan tersebut sederhana dan memiliki kedalaman tetap (induk-anak dengan satu tingkat)
  • Anda terutama memfilter dan menggabungkan atribut entitas
  • Model data sebagian besar bersifat tabular dengan beberapa hubungan
  • Kinerja sangat penting, dan indeks pada kunci asing sudah memadai.
  • Tim Anda lebih terbiasa dengan pola SQL tradisional

Mengatasi tantangan kueri grafik umum

Kueri grafik memiliki persyaratan sintaksis unik yang dapat menyebabkan kesalahan. Tabel berikut ini menjelaskan tantangan umum dan cara mengatasinya.

Tantangan Penyebab Solusi
Kueri tidak mengembalikan hasil Arah panah dalam MATCH pola tidak cocok dengan bagaimana tepi disisipkan Verifikasi bagaimana tepi disisipkan. Jika $from_id adalah Karyawan dan $to_id manajer, panah harus menunjuk dari Karyawan ke Manajer.
Kesalahan sintaks dengan tepi berulang Alias tepi yang sama digunakan beberapa kali dalam satu MATCH pola Buat alias terpisah untuk setiap traversal dengan jenis tepi yang sama.
SHORTEST_PATH kueri gagal Tabel tepi dan simpul tidak ditandai dengan FOR PATH Tambahkan FOR PATH kata kunci ke semua tabel yang berpartisipasi dalam pencocokan panjang variabel.
Edge mereferensikan simpul yang tidak ada Kolom kunci bisnis digunakan alih-alih nilai $node_id Gunakan subkueri untuk memilih $node_id dari tabel simpul saat menyisipkan tepi.

Nota

Tabel grafik dan MATCH operator tersedia di SQL Server 2017 dan yang lebih baru, dan Azure SQL Database. Fungsi ini SHORTEST_PATH memerlukan SQL Server 2019 atau yang lebih baru. Periksa dokumentasi platform Anda untuk ketersediaan fitur tertentu.

Untuk informasi selengkapnya tentang fitur grafik, lihat Pemrosesan grafik dengan SQL Server dan MATCH (Transact-SQL).