مقدمه Edge در Graph Tables
همانطور که در بخش قبلی اشاره کردیم، برای ارتباط بین دو node در یک گراف از Edge استفاده می کنیم. هر Edge که ارتباط بین دو جدول node را برقرار می کند می تواند دارای خصوصیت (Property) باشد و یا نباشد. این نوع طراحی برای پیاده سازی روابط چند به چند پیچیده بسیار خوب خواهد بود.
برای اینکه بهتر مسئله را درک کنید یک مثال را بررسی خواهیم کرد:
در بخش قبل یک node به نام Person تعریف کرده بودیم که اطلاعات افراد را نگهداری می کرد. حال می خواهیم با ایجاد یک Edge بین افراد ارتباط برقرار کنیم، فرض کنید قصد داریم در یک شبکه ی اجتماعی اطلاعات دوستی افراد را در این مدلسازی پیاده کنیم. برای اینکه از ابتدا مثال را بررسی کنیم، جدول Person را ایجاد کرده و اطلاعات تستی را در آن ثبت می کنیم:
1 2 3 4 5 6 7 8 9 10 11 12 |
--------------- Create Person Table --------------- CREATE TABLE Person ( ID INT identity PRIMARY KEY, FirstName NVARCHAR(30), LastName NVARCHAR(30), City NVARCHAR(30) ) AS NODE; --------------- Fill Data in Person Table --------------- Insert into Person values ('Hamed','Naeemaei','Tehran') Insert into Person values ('Reza','Jenabi','Tehran') Insert into Person values ('Amin','Golmahalle','Tehran') Insert into Person values ('Saeed','Rezvani','Chalus') |
نحوه ساخت Edge Table
حال باید جدولی از نوع Edge یا یال برای ارتباط بین افراد بسازیم، به همین علت ابتدا نحوه ایجاد جدول Edge را توضیح خواهیم داد:
1 2 3 4 5 |
CREATE TABLE [ database_name . [ schema_name ] . | schema_name . ] table_name ( { } [ ,...n ] ) AS [Edge] [ ; ] |
ساختار کلی برای ایجاد جدول Edge مانند جداول متداول است با این تفاوت که در انتهای کوئری از عبارت As Edge استفاده می کنیم
جدول Edge می تواند دارای خصوصیت نباشد:
1 |
CREATE TABLE Friendship AS EDGE; |
و جدول Edge می تواند دارای خصوصیت باشد:
1 |
CREATE TABLE Friendship (DateOfEvent DateTime,Status bit) AS EDGE; |
پس از اینکه با نحوه ایجاد این نوع جداول آشنا شدیم، جدول ارتباط دوستی بین افراد را ایجاد خواهیم کرد، که همانند کد خط بالا می باشد. برای این جدول Edge دو فیلد تاریخ رویداد و وضعیت رویداد ( به معنای دوستی یا قطع دوستی ) ایجاد کرده ایم.
همانطور که مشاهده می کنید جدول Edge ایجاد شد و در لیست جداول دیتابیس نمایش داده شده است.
نحوه درج اطلاعات در Edge Table
برای درج اطلاعات در Edge Table ها باید مشخص کنیم این یال چه نود هایی را به یکدیگر متصل می کند. مانند تصویر زیر
یال Friends بین دو موجودیت Person ارتباط برقرار می کند بنابراین در یک جدول Edge اطلاعات نود مبدا و نود مقصد علاوه بر اطلاعات دیگر ذخیره خواهد شد.
برای شروع کار من سعی می کنم Person شماره یک و Person شماره دو، ارتباط دوستی برقرار کنم که کد آن اینگونه خواهد بود:
1 2 3 4 5 6 7 |
INSERT INTO Friendship VALUES ( (SELECT $node_id FROM Person WHERE ID = 1), -- کد نود مبدا (SELECT $node_id FROM Person WHERE id = 2), -- کد نود مقصد getdate() -- تاریخ ,1 -- ارتباط دوستی/قطع دوستی ); |
بعد از آن یک کوئری روی جدول می زنیم تا ببینیم چه دیتایی در جدول ثبت شده است:
دیتایی که در نتیجه میبینیم آن چیزی نیست که ما می خواهیم. در جداول معمولی Sql Server با استفاده از عملگر Join می توانستیم بین دو جدول ارتباط برقرار کنیم و نتیجه را ببینیم اما برای نمایش اطلاعات دو جدول که با یکدیگر ارتباط دارند در گراف دیتابیس اینگونه نیست. برای ارتباط دو موجودیت در Graph Database باید از یالی که بین نود ها ارتباط برقرار می کند استفاده نماییم. در ادامه Syntax این کوئری را باهم خواهیم دید:
1 2 3 4 5 6 7 |
SELECT p1.id,p1.FirstName, p1.LastName ,p2.id,p2.FirstName, p2.LastName,f.DateOfFriendShip,Status FROM Person p1,Person p2, Friendship f WHERE MATCH(p1-(f)->p2) |
نتیجه ی کوئری بالا اینگونه خواهد بود:
این جدولها آیا بیشتر برای ارتباط یه جدول با خودش استفاده میشه؟
با سلام، خیر در بخش بعدی ارتباط بین دو جدول متفاوت را نیز توضیح خواهم داد
سلام
ممنون از مطلب خوبتون. در این خصوص یکی دو تا سئوال از خدمتتون داشتم:
1)در طول زمان با بالا رفتن حجم دیتاهای این نوع جداول به مشکلی از قبیل کُندی عملیات CRUD برنمیخوریم؟
2) آیا امکان پارتیشن بندی در اینگونه جداول قلبل پیاده سازی هستش؟
3) این جداول از Temporal Tables هم پشتیبانی میکنند؟
سلام، با تشکر از سوالات خوبتون
برخی مسائل هستند که پیاده سازی آنها در مدل رابطه ای پیچیدگی های خاصی دارد برای نمونه سیستم نظردهی سایتها را در نظر بگیرید که ممکن است یک نظر در چند سطح و بصورت تو در تو پاسخ داده شود نوشتن یک کوئری بازگشتی یا با Join های تو در تو باعث پیچیدگی کد میشود.
در حالت مسائل معمولی سرعت دیتابیس های رابطه ای بهتر است ولی در مسائلی مانند مسئله فوق کوئری هایی که روی جداول Relational زده می شوند حافظه ی زیادی مصرف می کنند.
در مورد 2 که فرمودید تست نکردم ولی فکر میکنم امکان Partitioning روی این جداول وجود دارد
در حال حاضر که این ویژگی به SQL Server 2017 اضافه شده بسیاری از قابلیت های مفیدی که برای جداول معمول وجود دارد برای این نوع جداول وجود ندارد برای نمونه:
در EF از این نوع جداول در Mapping فعلا پشتیبانی نمی شود.
امکان تعریف temporal table از نوع Node و Edge وجود ندارد که پاسخ مورد 3 می باشد