SQL Server 2017 ile kullanılmaya başlayan karmaşık ve hiyerarşik ilişki yönetimini sağlayan Graph database özelliğini yazı içerisinde anlatmaya çalışacağım.
Graph database – Grafik veritabanı – İlişkisel veritabanı sistemleri ve NoSQL veritabanları ile çalışırken yaşadığımız karmaşık hiyerarşik verileri gösterme, ilişki düzeylerinin sayısı ve veritabanı boyutları gibi konularda yaşanan performans sorunlarını gidermesi için kritik önem arz ediyor diyebilirim.
Grafik veritabanı nerelerde kullanabiliriz?
- Sosyal ağ oluşturmada
- Dolandırıcılık tespitinde – fraud detection
- Ürün önerileri
- BT Ağ analizi
- Sosyal öneriler
vs şeklinde kullanım alanlarını detaylandırabiliriz.
Grafik veritabanı iki öğeden oluşur.
- Node: Grafik veritabanı içerisinde varlıkları temsil eder. Müşteri, çalışan vs
- Edge: Varlıklar arasında – Node – ilişkiyi temsil eder.
SQL Server Grafik veritabanı hakkında kısa bilgilendirme sonrasında kullanımı hakkında bir demo gerçekleştirelim ve bilgilerimizi pekiştirmiş olalım.
Örnek senaryo: Kişi, Şehir, Takım, Stat ve bunlar arasındaki ilişkileri anlatalım.
İlk adım olarak senaryoyu uygulamak adına aşağıdaki kod bloğu ile “DMCGraph” isimli bir veritabanı oluşturalım.
USE master; GO DROP DATABASE IF EXISTS DMCGraph; GO CREATE DATABASE DMCGraph; GO “Node” tablolarını oluşturmaya başlayalım. İlk olarak users için işlem yapalım. USE DMCGraph; GO DROP TABLE IF EXISTS Users; GO CREATE TABLE Users ( UserID INT IDENTITY PRIMARY KEY, UserName NVARCHAR(100) NOT NULL, ) AS NODE;
Yukarıdaki kod bloğuna baktığımızda klasik bir tablo oluşturma işlemi gibi olduğunu görebilirsiniz. Tek fark tablo söz diziliminin sonuna “AS NODE” ifadesi ile bir “Node” olduğunu belirtmeniz.
“Users” isimli Node, bir UserID ve ve Username bilgilerinden oluşuyor, node içerisinde Primary key olmasına özen göstermemiz gerekiyor. Bir tablonun node yada edge olup olmadığını kontrol etmek için sys.tables sistem tablosunda bulunan is_node ve is_edge kolonları kullanılır.
select name,is_node,is_edge from sys.tables
Resim-1
Yukarıdaki resimde users isimli tablonun bir node olduğunu görüyoruz. Zaten tanımlamasını yaparken “AS NODE” ile bir node olduğunu belirtmiştik.
Şimdi elimizde users isimli bir graph table var ve buna veri girişi yapalım.
insert into Users values
(‘Çağlar’),(‘Baki’),(‘Çağdaş’),(‘Musa’),(‘Sait’),(‘Burak’)
Şimdi ise users isimli node içeriğini görüntüleyelim.
select * from dbo.Users
Resim-2
Yukarıdaki resimi incelediğinizde tanımlama yaptığımız UserID ve UserName haricinde bir kolon olduğunu görürsünüz. Buradaki veri içeriği ise JSON verileri içerir ve varsayılan sıralama değeri 0’dan başlar.
Benzer şekilde Takım, Stat ve şehir node oluşturalım.
Takım için;
USE DMCGraph; GO DROP TABLE IF EXISTS Teams; GO CREATE TABLE Teams ( TeamID INT IDENTITY PRIMARY KEY, TeamName NVARCHAR(100) NOT NULL, ) AS NODE; INSERT INTO Teams (TeamName) VALUES ('Galatasaray'),('Fenerbahçe'),('Beşiktaş'),('Trabzonspor'),('Başakşehir') Stat için;
USE DMCGraph; GO DROP TABLE IF EXISTS Stat; GO CREATE TABLE Stat ( StatID INT IDENTITY PRIMARY KEY, StatName NVARCHAR(100) NOT NULL, ) AS NODE; INSERT INTO Stat (StatName) VALUES ('Türk Telekom Arena'),('Şükrüsaraçoğlu'),('Vodafone Arena'),('Avni Aker Stadı'),('Fatih Terim Stadı')
Şehir için;
USE DMCGraph; GO DROP TABLE IF EXISTS Cities; GO CREATE TABLE Cities ( CityID INT IDENTITY PRIMARY KEY, CityName NVARCHAR(100) NOT NULL, ) AS NODE; INSERT INTO Cities (CityName) VALUES ('İstanbul'),('Trabzon')
Grafik veritabanı için ihtiyaç duyacağımız node oluşturduk. Şimdi sırada edge oluşturmaya geldi. TutulanTakim, HangiSehirTakimi ve TakimlarinStad isimli edge oluşturalım.
DROP TABLE IF EXISTS TutulanTakim; GO CREATE TABLE TutulanTakim AS EDGE; DROP TABLE IF EXISTS HangiSehirTakimi; GO CREATE TABLE HangiSehirTakimi AS EDGE; DROP TABLE IF EXISTS TakimlarinStad; GO CREATE TABLE TakimlarinStad AS EDGE;
Yukarıdaki kod bloğunu çalıştırdıktan sonra sys.tables üzerinden is_node ve is_edge için gerekli kontrolleri yapalım.
Resim-3
Tanımlamaları Resim-3 de görüldüğü üzere gerçekleştirdik. Şimdi Edge üzerinde insert işlemi yapmaya geldi. Edge, iki veya daha fazla node arasındaki ilişkiyi tanımlamak için kullanılır.
Bir kullanıcının bir takımı tuttuğunu varsayarak TutulanTakim isimli edge üzerine insert işlemi yapalım. Fakat bu işlemi gerçekleştirmeden önce TutulanTakim edge bir görüntüleyelim.
select * from TutulanTakim
Resim-4
Yukarıdaki resimde görüldüğü üzere edge üzerinde 3 adet kolon oluşmuş. Kolon isimlendirmesine baktığımızda aslında node’lar arasındaki ilişkiyi bize anlatır bir yapıdadır.
1 numaralı users için işlem gerçekleştirelim. (1 numaralı kullanıcıyı 1 numaralı ekip ile ilişkilendirdim.)
insert into TutulanTakim($from_id, $to_id) values ((SELECT $node_id FROM Users WHERE UserID = 1), (SELECT $node_id FROM Teams WHERE TeamID = 1));
1 numaralı users için tekrar işlem gerçekleştirelim. (1 numaralı kullanıcıyı 4 numaralı ekip ile ilişkilendirdim.)
insert into TutulanTakim($from_id, $to_id) values ((SELECT $node_id FROM Users WHERE UserID = 1), (SELECT $node_id FROM Teams WHERE TeamID = 4));
2 numaralı users için tekrar işlem gerçekleştirelim. (2 numaralı kullanıcıyı 3 numaralı ekip ile ilişkilendirdim.)
insert into TutulanTakim($from_id, $to_id) values ((SELECT $node_id FROM Users WHERE UserID = 2), (SELECT $node_id FROM Teams WHERE TeamID = 3));
3 numaralı users için tekrar işlem gerçekleştirelim. (3 numaralı kullanıcıyı 1 numaralı ekip ile ilişkilendirdim.)
insert into TutulanTakim($from_id, $to_id) values ((SELECT $node_id FROM Users WHERE UserID = 3), (SELECT $node_id FROM Teams WHERE TeamID = 1)); HangiSehirinTakimi için de kayıt ekleme işlemi yapalım.
1 numaralı takımı,1 numaralı şehir için ekledim.
insert into HangiSehirTakimi($from_id, $to_id) values ((SELECT $node_id FROM Teams WHERE TeamId = 1), (SELECT $node_id FROM Cities WHERE CityId = 1))
4 numaralı takımı,2 numaralı şehir için ekledim.
insert into HangiSehirTakimi($from_id, $to_id) values ((SELECT $node_id FROM Teams WHERE TeamId = 4), (SELECT $node_id FROM Cities WHERE CityId = 2))
3 numaralı takımı,1 numaralı şehir için ekledim.
insert into HangiSehirTakimi($from_id, $to_id) values ((SELECT $node_id FROM Teams WHERE TeamId = 3), (SELECT $node_id FROM Cities WHERE CityId = 1))
TakimlarinStad için de kayıt ekleme işlemi yapalım.
1 numaralı takımı,1 numaralı stat ile eşleştirdim.
insert into TakimlarinStad($from_id, $to_id) values ((SELECT $node_id FROM Teams WHERE TeamId = 1), (SELECT $node_id FROM Stat WHERE StatId = 1))
2 numaralı takımı,2 numaralı stat ile eşleştirdim.
insert into TakimlarinStad($from_id, $to_id) values ((SELECT $node_id FROM Teams WHERE TeamId = 2), (SELECT $node_id FROM Stat WHERE StatId = 2))
3 numaralı takımı,3 numaralı stat ile eşleştirdim.
insert into TakimlarinStad($from_id, $to_id) values ((SELECT $node_id FROM Teams WHERE TeamId = 3), (SELECT $node_id FROM Stat WHERE StatId = 3))
Verilerin görüntülenmesi için;
Select deyiminde where koşulu içerisinde match deyimini belirtmeniz gerekmektedir. Örnek olarak Users’ların tuttuğu takımları görüntülemek için aşağıdaki sorguyu kullanmanız gerekiyor.
SELECT u.UserName, t.TeamName FROM Users u, TutulanTakim tt, Teams t WHERE MATCH(u-(tt)->t);
Yukarıdaki örnekte users node’u olarak, TutulanTakim edge’i tt olarak, teams node’u t olarak isimlendirdim. Çıktısı aşağıdaki gibidir.
Resim-5
Benzer şekilde farklı bir örnek olarak Hangi Şehir, hangi takıma ev sahipliği yapıyor sorusunun cevabını almak için aşağıdaki sorguyu kullanabiliriz.
select t.TeamName,c.CityName from Teams as t, HangiSehirTakimi as hst,Cities as c WHERE MATCH(t-(hst)->c);
Resim-6
Teams node için t, HangiSehirTakimi için hst, Cities için c isimlendirmelerini kullandım ve match ile eşleştirme yapmasını sağladım.
Kullanıcıların takımları ve takımların şehirlerinin yer aldığı sorguyu yazmak istersek eğer;
select u.UserName, t.TeamName,C.CityName from Users as u, Teams as t, Cities as c, TutulanTakim as tt, HangiSehirTakimi as hst where 1=1 and Match(u-(tt)->t) and Match(t-(hst)->c)
Resim-7
Verilerin Silinmesi için;
Edge üzerinden Delete işlemi gerçekleştirmek için $from_id ve $to_id değerlerini belirtmeniz gerekmektedir.
delete from TutulanTakim where 1=1 and $from_id = (select $node_id from users where UserId = 1 ) and $to_id = (select $node_id from Teams where TeamId =4 )
Sorguyu çalıştırdıktan sonra Resim-7 sorgusunu tekrar çalıştırdığınızda Trabzonspor bilgisini görmeyeceksiniz. Grafik veritabanları, karmaşık işlemlerden birçok işlemin uygulanma biçimini değiştiriyor.
Bu yazıda, grafik veritabanlarında node ve edgenasıl oluşturulacağını kısaca gözden geçirdik.Ayrıca farklı node arasındaki ilişkilerin nasıl uygulanacağını ve edge ekleme, okuma ve silme işlemlerinin nasıl gerçekleştirileceğini gördük.Bir sonraki yazımızda SQL Server üzerinde Grafik veritabanını kullanarak Twitter için veritabanı tasarımı gerçekleştiriyor olacağız.