- Postgres 19'daki property graph, mevcut tabloları düğüm ve kenar olarak tanımlayıp
MATCH ile sabit ilişki kalıplarını arayan bir SQL/PGQ özelliğidir; veriyi kopyalamaz veya ayrı bir graph yürütme motoru oluşturmaz
- Graph kalıpları ilişkisel join'lere derlenir ve mevcut optimizer, indeksler ve istatistikleri aynen kullanır; bu nedenle yavaş dolaşmalar da normal join'lerle aynı şekilde analiz edilip optimize edilebilir
- Boyut tabloları düğümlere, saf join tabloları kenarlara doğal biçimde karşılık gelir; ancak birden çok foreign key'e ve kendi özelliklerine sahip fact tabloları olayları temsil eden hub düğümler olarak modellenmeye daha uygundur
- Tek bir tablo, farklı takma adlarla aynı anda düğüm ve birden fazla kenar olarak tanımlanabilir; böylece
results içindeki mevcut foreign key'leri kullanan ayrı kenar tabloları oluşturup saklamaya gerek kalmaz
- Postgres 19 değişken uzunluklu path'leri desteklemediği için en kısa yol, N-hop erişilebilirlik veya PageRank için uygun değildir; ilişki yapısını önceden bildiğiniz sabit uzunluklu gezintiler için uygundur
İlişkisel şemayı graph olarak okuma biçimi
- Normalize edilmiş bir ilişkisel şemada
drivers, constructors, circuits gibi boyut tabloları varlıkları içerir, fact tabloları ise yarış sonuçları veya sıralama seansları gibi olayları kaydeder
- Her satır potansiyel bir düğüm, foreign key'ler ise başka satırlara işaret eden potansiyel kenarlardır
- ER diyagramı şema düzeyindeki bir graph'a karşılık gelir
- Gerçek satırlar ve foreign key ilişkileri ise örnek düzeyindeki bir graph'a karşılık gelir
- “Her sonuca karşılık gelen constructor'ı bul” isteği, ilişkisel SQL'de
results JOIN constructors ON ... şeklinde yazılan bir graph gezintisidir
- SQL/PGQ, graph'ın kendisini yeniden eklemek yerine, join'leri doğrudan sıralamak yerine soruyu graph biçiminde yazmanıza olanak tanır
- RelBench yaklaşımı tabloları pandas'a alıp bellekte bir PyTorch graph'ı kurarken, Postgres property graph veritabanı içindeki mevcut tablo ilişkilerini doğrudan kullanır
- PyG örnekleri de çoğunlukla düz dosyalar veya bellek içi graph'lar kullanır
- Formula 1 veri kümesiyle yapılan denemelerin koduna GitHub deposundan ulaşabilirsiniz
Property graph'ın yapısı
CREATE PROPERTY GRAPH, mevcut tablolar üzerinde oluşturulan adlandırılmış bildirimsel bir nesnedir
VERTEX TABLES, satırları düğüm olarak okunacak tabloları belirtir
EDGE TABLES, satırları bağlantı ilişkisi olarak okunacak tabloları belirtir
- Her düğüm tablosu için şu ögeler tanımlanır
KEY: düğümün kimliğidir, çoğu durumda primary key kullanılır
LABEL: MATCH içinde kullanılacak düğüm türü adıdır
PROPERTIES: graph sorgusunda erişilebilecek sütunların listesidir
- Her kenar tablosunda
SOURCE ve DESTINATION belirtilir; bu iki değer sırasıyla düğüm anahtarlarına referans verir
CREATE PROPERTY GRAPH veriyi taşımaz veya kopyalamaz
- Satırlar özgün tablolarında kalır
- Bildirim yalnızca mevcut foreign key yapısının graph olarak nasıl okunacağını tanımlar
- Property graph'ın yapısal ögeleri sadece iki türdür: düğüm ve kenar
- Label'lar ve property'ler düğüme veya kenara ait niteliklerdir
psql içinde her ögenin Element Kind değeri vertex veya edge olur
MATCH ile sabit kalıpları sorgulama
- Graph sorguları,
GRAPH_TABLE(...) içinde MATCH kalıbı yazılarak oluşturulur
- Aşağıdaki kalıp, driver'dan result üzerinden race'e giden ilişkiyi gösterir
MATCH (d IS driver)<-[IS of_driver]-(res IS result)-[IS in_race]->(ra IS race)
COLUMNS bölümü, graph sorgusunun dışarı döndüreceği sütunları belirtir
- Dıştaki
SELECT, GRAPH_TABLE(...) sonucunu normal bir tablo gibi sorgulayabilir
- Kalıpta yön ve label bulunduğu için ilişkiler cümle gibi okunabilir; bu da aynı çoklu join'e göre yapıyı anlamayı kolaylaştırır
Çalışma anında ilişkisel join'lere dönüşen yapı
MATCH, Postgres'e sonradan eklenmiş ayrı bir graph yürütme motoru değil, ilişkisel join'lere derlenen bir sözdizimidir
- driver–result–race kalıbında
EXPLAIN çalıştırıldığında, temel tablolar üzerinde 4 adet hash join görülür
- Doğrudan yazılmış join'lerde olduğu gibi şu bileşenler kullanılır
- mevcut Postgres optimizer'ı
- mevcut indeksler
- mevcut istatistikler
- Bir graph gezintisi yavaşsa, nedeni ve optimizasyon yöntemi de normal bir join'in yavaş olmasına benzer
psql içinde de graph'lar tablo benzeri komutlarla incelenebilir
\dG: property graph listesini gösterir
\d f1: her düğümü ve kenarı, temel tabloyu, öge türünü, kenarların başlangıç ve varış düğümlerini gösterir
\d+ f1: tam CREATE PROPERTY GRAPH ifadesini yeniden kurar ve kenar tablosunun primary key'inden türetilen kenar anahtarını da içerir
Anahtar ile property arasındaki fark
- Bir düğüm için
KEY olarak belirtilen sütun otomatik olarak property olmaz
driver_id yalnızca düğüm anahtarı olarak tanımlanıp sonra d.driver_id = 1 ile filtrelenirse, bu sütun sorgulanabilir bir property olmadığı için işlem başarısız olur
- Anahtar düğümü tanımlar, ancak onu sorguya açmaz
- ID sütunlarını filtrelemek veya döndürmek istiyorsanız, bunları
PROPERTIES listesine açıkça eklemelisiniz
Postgres 19'da değişken uzunluklu path kısıtı
- Postgres 19, bir kenarı 1 ila 3 kez izleme gibi öge kalıbı nicelikleyicilerini desteklemez
ERROR: element pattern quantifier is not supported
- İki hop gezmek için
MATCH içinde iki kenar kalıbını açıkça yazmanız gerekir
- Rastgele uzunlukta path'ler property graph sözdizimiyle ifade edilemez
- Derinliği açık uçlu gezintiler, temel tablolar üzerinde recursive CTE ile yapılmalıdır; bu durumda property graph sözdiziminin dışına çıkılır
Mevcut tabloları düğüm ve kenara eşleme
-
Boyut tabloları düğümdür
drivers, constructors, circuits gibi istikrarlı primary key'lere ve özelliklere sahip varlık tabloları doğrudan düğüme karşılık gelir
- Primary key'i düğüm anahtarı olarak kullanıp gerekli sütunları property olarak açmanız yeterlidir
-
Saf join tabloları kenardır
student_courses(student_id, course_id) gibi çoktan çoğa köprü tablolarının asıl görevi iki varlığı bağlamak olduğundan kenar olarak doğal biçimde karşılık gelirler
- Bir foreign key başlangıç düğümü, diğeri varış düğümü olarak tanımlanır
- Join tablosundaki her satır zaten tek bir ilişkiyi temsil ettiği için graph'a özel ek bir veri dönüşümüne gerek yoktur
- Bu yapıda
students ve courses düğüm, student_courses ise enrolled_in kenarı olur
-
Fact tabloları olay düğümleridir
results satırları driver, race ve constructor olmak üzere üç varlığa işaret ederken, grid, position, points, status gibi kendi verilerini de taşır
- SQL/PGQ kenarları, tek bir başlangıç ve tek bir varış noktası olan ikili ilişkilerdir; dolayısıyla üç foreign key içeren bir satırın tamamı tek bir kenara dönüştürülemez
- Fact satırının kendisi analiz konusuysa, o tabloyu düğüm olarak tanımlamak daha uygundur
results düğümü olayı ve onun özelliklerini taşır
results_driver, results_race, results_constructor gibi dar kenarlar dış varlıklara bağlanır
- Bu model
driver <- result -> race gibi bir hub yapısı kurar ve result düğümünde durup filtreleme yapmanıza veya özellik sorgulamanıza izin verir
- İlgi odağı ilişkinin kendisiyse kenar, benzersiz özellikleri olan belirli bir satır veya olaysa düğüm olarak modelleyin
- Join tabloları ilişkileri, fact tabloları ise olayları temsil eder
Tek bir tabloyu aynı anda düğüm ve kenar olarak kullanma
- “Düğüm veya kenar” ayrımı temel tabloya değil, graph içindeki her öge bildirimine uygulanır
- Tek bir tabloyu farklı takma adlarla hem
VERTEX TABLES hem EDGE TABLES içinde tanımlayabilirsiniz
results, result düğümü olarak kullanılırken aynı tablo şu kenar takma adlarıyla yeniden kullanılabilir
results AS res_driver: result'tan driver'a bağlanır
results AS res_race: result'tan race'e bağlanır
results AS res_constr: result'tan constructor'a bağlanır
- Her kenar takma adı,
results içinde zaten bulunan primary key ve foreign key sütunlarını kullanır
- Ayrı
results_driver, results_race, results_constructor tabloları oluşturmaya gerek yoktur ve takma adlar veri saklamaz
- Üç foreign key'e sahip fact tablosu, çok uçlu tek bir kenar olarak değil, her biri tek başlangıç ve tek varışa sahip üç ayrı kenar takma adı olarak tanımlanmalıdır
- Bu yaklaşım, üç fiziksel tablo veya view yerine tek bir temel tablo üzerinde üç bildirimsel takma ad kullanır
Property adları ve tür çakışmaları
PROPERTIES atlanırsa, SQL/PGQ tablodaki tüm sütunları property olarak açar
results ve qualifying tablolarında number sütunu bulunuyor ancak bunların türleri sırasıyla double precision ve bigint ise şu hata oluşur
ERROR: property "number" data type mismatch: double precision vs. bigint
- Graph genelinde aynı ada sahip bir property tek bir türe sahip olmalıdır; bu yüzden farklı türde aynı adlı sütunlar çakışır
- Yalnızca gereken sütunları
PROPERTIES içinde açıkça belirtirseniz, çakışan sütunları graph dışında bırakabilirsiniz
- Anahtarın otomatik olarak property olmaması sorunu da, tür çakışmaları da açık bir property izin listesi ile çözülebilir
Uygun ve uygun olmayan sorgular
-
Sabit ilişki kalıpları
- Property graph, “X ile bu belirli kalıpta bağlantılı olan hedefleri bul” türü sorular için uygundur
- Formula 1 graph'ında şu tür sorgular yazılabilir
- Belirli bir driver'ın hangi constructor için yarıştığını bulmak
- driver'dan result ve race üzerinden başka result ve driver'a giden kalıpla rakipleri bulmak
- Başlangıç sırası 10'un dışında olan ve driver'ı Italian olan sonuçlar gibi yapı ile property koşullarını birlikte filtrelemek
- İlişki biçimini önceden biliyor ve bu yapı sabit ve sonlu ise arama, filtreleme ve toplulaştırma sözdizimi daha okunaklı hale gelir
- Birden çok self-join gerektiren sorgular bile tek bir
MATCH kalıbıyla kolay okunur biçimde ifade edilebilir
-
Path'in kendisinin bilinmediği problemler
- Şu problemler Postgres 19 property graph için uygun değildir
- İki driver arasındaki en kısa yol
- N-hop içinde ulaşılabilen tüm hedefler
- Derinliği önceden bilinmeyen bağlantı gezintileri
- Bu sorgular değişken uzunluklu dolaşma gerektirdiği için temel tablolar üzerinde recursive CTE kullanılmalıdır
- PageRank, topluluk keşfi, merkezilik hesapları gibi graph algoritmaları da pattern matching'den farklı problemlerdir ve bu özelliğin kapsamına girmez
- Property graph, path yapısını bildiğinizde bağlantılı hedefleri bulur; ancak X ile Y'nin hangi path üzerinden bağlı olduğunu bilmiyorsanız yolu keşfedemez veya graph'ın yapısal önemini hesaplayamaz
Benimsemeden önce değerlendirilmesi gerekenler
- SQL/PGQ, mevcut foreign key yapısının üzerine kurulan bildirimsel bir katmandır ve özellikle seçilmediği sürece ek veri saklamaz
- Başlıca iki faydası vardır
- Sabit biçimli gezintileri ilişkisel join'lere göre daha okunaklı yazabilmek
- Şemayı graph olarak belgeleyen adlandırılmış bir nesne sunmak
- En büyük kısıt, değişken uzunluklu path olmaması ve bu nedenle derin ya da açık uçlu gezintilerin recursive SQL ile yapılmak zorunda olmasıdır
- Tabloların kendisi özünde düğüm veya kenar değildir; her graph için bu satırların düğüm, kenar veya ikisi birden olarak okunup okunmayacağına siz karar verirsiniz
- Postgres 19'da mevcut şema üzerinde sabit graph kalıpları sorgulamak istiyorsanız, veriyi ayrı bir graph veritabanına taşımadan önce
CREATE PROPERTY GRAPH ve MATCH yaklaşımını değerlendirebilirsiniz
- Bilinmeyen derinlikte arama yapmanız gerekiyorsa recursive CTE gerekir; ancak hangi yöntemi kullanırsanız kullanın, verinin Postgres dışına çıkması gerekmez
- Gerçek kullanıma almadan önce, ihtiyaç duyduğunuz performansı verip vermediğini doğrudan test etmelisiniz
Henüz yorum yok.