أعلنت شركة مايكروسوفت عن نظامها الجديد في ال SQL Azure والذي يسمح للمطورين بناء أنظمة موزعة عبر الكلاود وكذلك تطبيقات SaaS الخدماتية. يمكنك معرفة المزيد من المعلومات عبر الرابط التالي
ولسوء الحظ, لا يوجد الآن حل جاهز من المكتبات لتطبيقات التي تعمل على بيئة غير ال .NET, بالإضافة إلى ذلك فإن التطبيقات التي كانت تعمل على نظام ال federation الخاص بعملية تقسيم التطبيقات, هذه التطبيقات لن تعمل في تاريخ سبتمبر ٢٠١٥, حيث أن التطبيقات التي تعمل بنظام الآجراء بلغات مثل PHP لن يكون لها القابلية لإستخدام elastic scale بشكل مباشر.
هذا سبب كتابة التدوينة لتقديم حل يساعد على الرحيل إلى نظام ال SaaS بنظام مايكروسوفت الجديد SqlAzure Elastic Scale بدون إستخدام مكتبات ال .NET.
بداية كل ما عليك فعله هو متابعة الفيديو التعليمي من مايكروسوفت بالفكرة العامة للهجرة من نظام ال Fedration إلى ال Elastic Scale
من الناحية التقنية, لن نقوم بمناقشة كيفية إضافة شارد ومدير شارد بشكل عميق, وهذا يعني أنه لديك مدير للشاردز وشارد متوفر وموجود. هذه التدوينة تخبرك كيف تشغل وتحور التطبيق ليكون متعدد الآجراء, هناك تدوينة أخرى بشأن فتح أجراء جدد وإنشاء شارد جديد.
كيفية فلترة البيانات في كل من إستعلامات SELECT, Update, Delete على حسب آجير معين بإستخدام (Row Level Security )
خاصية Row Level Security والتي يمكن من خلالها فلترة إستعلامات قاعدة البيانات حسب رقم أجير محدد متوفرة فقط على خادم SQL SERVER V12 وهذا يعني أنه ينبغي عليك التأكد من تحديث خادم قاعدة البيانات الخاص بك على ال Azure إذا ما أردت إستخدام الخاصية.
لإضافة الخاصية تحتاج لإنشاء هيكلية خاصة وتفعيلها, مثل الكود في الأسفل
[box type=”shadow” ]CREATE SCHEMA rls — separate schema to organize RLS objects GO
CREATE FUNCTION rls.fn_tenantAccessPredicate(@TenantId int) RETURNS TABLE WITH SCHEMABINDING AS RETURN SELECT 1 AS fn_accessResult
WHERE DATABASE_PRINCIPAL_ID() = DATABASE_PRINCIPAL_ID(‘dbo’) — the user in your application’s connection string (dbo is only for demo purposes!)
AND CONVERT(int, CONVERT(varbinary(4), CONTEXT_INFO())) = @TenantId — @TenantId (int) is 4 bytes GO [/box]
بمجرد تنفيذ الكود بالأعلى نكون قد أنشأنا Security Level, نحتاج لفترة الجداول بحيث يمكننا تطبيق ال row level على كل جدول مثال في الأسفل
[box type=”shadow” ]
CREATE SECURITY POLICY rls.tenantAccessPolicy
ADD FILTER PREDICATE rls.fn_tenantAccessPredicate(TenantId) ON dbo.Blogs
ADD FILTER PREDICATE rls.fn_tenantAccessPredicate(TenantId) ON dbo.Posts GO [/box]
Further we need to set the Default value for the Tenant ID in order to be prompted in the query executions, the default value will be
[box type=”shadow” ]CONVERT(int, CONVERT(varbinary(4), CONTEXT_INFO()))[/box]
توجيه الآجير إلى الشارد المناسب
بعد فلترة البيانات على حسب الأجير, نحتاج لتوجيه الآجير إلى الشارد المناسب, حيث أن التطبيق يمكن أن يحوي مجموعة من الشاردز وكل شارد يحوي مجموعة آجراء. يمكن أن يعمل نظام الآجراء للتطبيق بمدى محدد مثال من 0 إلى 200 لشارد١ و 200 إلى 400 للشارد٢ وهكذا, في هذه الحالة كل ماعليك هو تعريف الآجير يقع في آي مدى, يمكن تطبيق الكود في الأسفل بإضافة دالة في قاعدة بيانات مدير الشارد للحصول على الأجير المناسب
[box type=”shadow” ]
[highlight]
CREATE FUNCTION [dbo].[getTenantConnectionInfoByTID] (@TenantId int) RETURNS TABLE AS RETURN
( SELECT sg.[DatabaseName] ,smsg.[Name] AS ‘shardMapManagerName’
FROM [__ShardManagement].[ShardMappingsGlobal] smg, [__ShardManagement].[ShardsGlobal] sg, [__ShardManagement].[ShardMapsGlobal] smsg
WHERE smg.[ShardMapId] = smsg.[ShardMapId] AND
smg.[ShardMapId] = sg.[ShardMapId] AND
sg.[ShardId] = smg.[ShardId] AND
@TenantId >= (CONVERT(int, CONVERT(VARBINARY(4), [MinValue])) +2147483648) AND
@TenantId < (CONVERT(int, CONVERT(VARBINARY(4), [MaxValue])) +2147483648)
)
[/highlight]
[/box]
في حال كان التطبيق لا يعمل بنظام المدى, بمعنى هناك آجراء مختلفين مسجلين في شارد مختلفة يمكن تطبيق الكود في الأسفل في مدير الشارد بدلا من الكود في الأعلى
[box type=”shadow” ]
[highlight]
CREATE FUNCTION [dbo].[getTenantConnectionInfoByTID] (@TenantId int) RETURNS TABLE AS RETURN
( SELECT sg.[DatabaseName] ,smsg.[Name] AS ‘shardMapManagerName’
FROM [__ShardManagement].[ShardMappingsGlobal] smg, [__ShardManagement].[ShardsGlobal] sg, [__ShardManagement].[ShardMapsGlobal] smsg
WHERE smg.[ShardMapId] = smsg.[ShardMapId] AND
smg.[ShardMapId] = sg.[ShardMapId] AND
sg.[ShardId] = smg.[ShardId] AND
@TenantId = (CONVERT(int, CONVERT(VARBINARY(4), [MinValue])) +2147483648) )
[/highlight]
[/box]
إضافة stored procedure بحيث يتم تمرير فيها رقم الأجير وتقوم بتثبيت رقم الأجير لجميع العمليات
[box type=”shadow” ]CREATE PROCEDURE sp_setContextInfoAsAppUserId(@TenantId int) AS SET CONTEXT_INFO @TenantId; GO[/box]
[divider]
الأن قمنا بتجهيز كل شيء, كل ما عليك هو فلترة التطبيق حسب آجير معين.
لنضع كل شيء معا, أولا عليك الإتصال بقاعدة بيانات مدير الشارد حيث ستقوم بدورها بتحديد أين يقع الأجير في أي شارد بإستخدام الدالة .getTenantConnectionInfoByTID(your tenant id here) التي قومنا بتعريفها
والأن بعد ما حددنا مكان الأجير نقوم بالإتصال بقاعدة البيانات للشارد ومن ثم نقوم بفلترة البيانات حسب رقم الأجير داخل الشارد من خلال إستخدام الدالة التالية
[box type=”shadow” ];’EXEC sp_setContextInfoAsAppUserId ‘your tenant id here[/box]
الأن تطبيقك مفلتر حسب التينتنت, حيث يمكن
select, insert, delete, update على حسب التينيت
أتمنى أن تكون التدوينة قدمت لكم الفائدة, وأنا مستعد لأي أسئلة
دمتم بود, إلى تدوينة أخرى