اشتراک‌ها
9 ویژگی جدید SQL Server 2017

- SQL Server Runs on Windows, Linux and Docker Containers
- Graph Database Capabilities
- Python Support
- Resumable Online Index Rebuild
- New CLR Security Model
- Identity Cache
- Adaptive Query Processing
- Scaling Out Integration Services
- Simplify Your Code with New T-SQL Functions

9 ویژگی جدید SQL Server 2017
اشتراک‌ها
دوره کار با SQL Server توسط PowerShell

PowerShell For SQL Full Course
f you’re a SQL Data Pro, check out this demo-packed course to explore using PowerShell to manage SQL Server and Azure SQL Database. Hear about the background of PowerShell, and learn PowerShell basics, such as how to get help, use cmdlets, and load modules. Look at task automation and configuration, and learn how to provision, deploy, and manage SQL Server in Azure Virtual Machines and Azure SQL Database. Plus, see how to use the SQLPS module to administer SQL Server, both on-premises and in Azure Virtual Machines. Don’t miss this practical PowerShell training 

دوره کار با SQL Server توسط PowerShell
نظرات مطالب
LocalDB چیست؟
- خیر. نام کامل این محصول «SQL Server Express LocalDB » است + نسخه «Microsoft® SQL Server® 2012 Express» از اینجا قابل دریافت است. بنابراین جایگزین یا حذف نشده.
- هدف اصلی از LocalDb ارائه یک «embedded database» جدید از طرف مایکروسافت است.
بنابراین هدف آن استفاده تحت شبکه نیست. جاهایی استفاده می‌شود که تک کاربر نهایی دانش آنچنانی در نصب و نگهداری بانک‌های اطلاعاتی ندارد و برنامه و سیستم بانک اطلاعاتی او یکپارچه به نظر می‌رسند. از این نمونه بانک‌های اطلاعاتی embedded باز هم هستند. مانند Firebird Embedded ، SQLite، SQL CE و غیره.
- نسخه Express تحت شبکه قابل استفاده است؛ البته نیاز به تنظیم دارد.

مطالب
کاهش حجم لاگ‌ فایل‌های اس‌کیوال سرور 2005 و 2008
نمی‌دونم تابحال به صورت جدی با SharePoint مایکروسافت کار کردید یا نه؟ این برنامه که عمده کارهای خودش رو با SQL server انجام میده در طول یک روز ممکن است تا 80 گیگ log file اس‌کیوال سرور تولید کند و بعد از چند روز اگر به همین صورت به حال خود رها شود (که عموما هم به همین صورت است!) ممکن است دیگر قادر به استفاده از سرور به دلیل پر شدن درایوی که لاگ فایل‌ها در آن ذخیره می‌شوند نباشید.
همچنین رشد tempdb نیز توسط این برنامه بسیار چشم‌گیر است. بنابراین همیشه به‌خاطر داشته باشید محل قرارگیری tempdb و همچنین محل قرارگیری لاگ فایل‌ها (که هر دو قابل تنظیم هستند) را در درایوهایی قرار دهید که حداقل 100 گیگ فضای خالی در آنها موجود باشد.
با استفاده از اسکریپت زیر می‌شود حجم لاگ فایل‌های اس کیوال سرور را به حداقل رساند و نفس راحتی کشید! این مساله اگر جدی گرفته نشود واقعا تبدیل به یک کابوس می‌شود!
اسکریپت زیر کلیه دیتابیس‌های موجود را یافته و shrink می‌کند. قسمت offline و online کردن آن هم به این خاطر است که ارتباط تمام کاربران متصل را به صورت آنی قطع می‌کند (یکی از چندین روش موجود برای kill کردن کاربران است). (یک stored procedure از آن درست کنید و با تعریف یک job جدید در اس کیوال سرور ، این stored procedure را برای مثال هر روز ساعت 3 بامداد به صورت خودکار اجرا کنید)
Declare @database nvarchar(1000)
Declare @tsql nvarchar(4000)
Declare DatabaseCursor Cursor
Local
Static
For
select name from master.dbo.sysdatabases
open DatabaseCursor
fetch next from DatabaseCursor into @database

while @@fetch_status = 0
begin
print 'database:' + @database
if @database not in ('tempdb','master','model','msdb')
begin
SET @tsql = 'use master;
alter database ['+@database+'] set offline with rollback immediate;
alter database ['+@database+'] set online;
DECLARE @dbLogName nvarchar(500) ;
Use ['+@database+'] ;
select @dbLogName = rtrim(ltrim(name)) from sysfiles WHERE FILEID=2;
ALTER DATABASE ['+@database+'] SET SINGLE_USER ;
DBCC SHRINKFILE(@dbLogName , 2) ;
BACKUP LOG ['+@database+'] WITH TRUNCATE_ONLY ;
DBCC SHRINKFILE(@dbLogName , 2) ;
ALTER DATABASE ['+@database+'] SET MULTI_USER ;'
exec(@tsql)
end
fetch next from DatabaseCursor into @database
end

close DatabaseCursor

deallocate DatabaseCursor
اسکریپت فوق با SQL Server 2005 سازگار است اما در SQL Server 2008 منسوخ شده است! (قسمت truncate کردن)
نسخه سازگار با SQL server 2008 آن به صورت زیر است:

Declare @database nvarchar(1000)
Declare @tsql nvarchar(4000)
Declare DatabaseCursor Cursor
Local
Static
For
select name from master.dbo.sysdatabases
open DatabaseCursor
fetch next from DatabaseCursor into @database

while @@fetch_status = 0
begin
print 'database:' + @database
if @database not in ('tempdb','master','model','msdb')
begin
SET @tsql = 'use master;
alter database ['+@database+'] set offline with rollback immediate;
alter database ['+@database+'] set online;
DECLARE @dbLogName nvarchar(500) ;
Use ['+@database+'] ;
select @dbLogName = rtrim(ltrim(name)) from sysfiles WHERE FILEID=2;
ALTER DATABASE ['+@database+'] SET RECOVERY SIMPLE;
ALTER DATABASE ['+@database+'] SET SINGLE_USER ;
DBCC SHRINKFILE(@dbLogName , 2) ;
ALTER DATABASE ['+@database+'] SET MULTI_USER ;
ALTER DATABASE ['+@database+'] SET RECOVERY FULL;'
exec(@tsql)
end
fetch next from DatabaseCursor into @database
end

close DatabaseCursor

deallocate DatabaseCursor
ماخذ اصلی مورد استفاده:
http://go.microsoft.com/fwlink/?LinkId=111531&clcid=0x409


مطالب
تنظیم درجه سازگاری یک دیتابیس اس کیوال سرور

اس کیوال سرور خود را به 2008 ارتقاء داده‌اید؟ آیا می‌دانید که مجاز هستید از تمامی امکانات جدید آن در دیتابیس‌های موجود خود استفاده کنید یا خیر؟
به همین منظور ابتدا کوئری زیر را اجرا نمائید:
Use master;
SELECT name, compatibility_level FROM sys.databases
لیست دیتابیس‌های موجود به همراه درجه سازگاری آن‌ها نمایش داده می‌شود. هر کدام که درجه سازگاری مساوی با 100 نداشت یعنی مجاز به استفاده از تمامی امکانات سرور جدید نیست و با آن همانند یک دیتابیس قدیمی بر اساس درجه سازگاری آن رفتار می‌شود.
تفسیر این اعداد مطابق اطلاعات زیر است:
60 = SQL Server 6.0
65 = SQL Server 6.5
70 = SQL Server 7.0
80 = SQL Server 2000
90 = SQL Server 2005
100= SQL Server 2008
برای تغییر این درجه سازگاری می‌توان از یکی از دستورات T-SQL زیر استفاده کرد:

-- Old way:
EXEC sp_dbcmptlevel 'AdventureWorks', 100

-- New way:
ALTER DATABASE 'AdventureWorks' SET COMPATIBILITY_LEVEL = 100 ;
که روش اول منسوخ شده در نظر گرفته شده و روش دوم پیشنهاد می‌شود.
برای مثال کوئری زیر عبارات Alter مورد نظر را جهت ارتقاء دیتابیس‌های موجود که درجه سازگاری آن‌ها 100 نیست (هنوز به اس کیوال سرور 2008 ارتقاء پیدا نکرده‌اند)، تولید می‌کند:

SELECT 'ALTER DATABASE ' + NAME + ' SET COMPATIBILITY_LEVEL = 100;' TSQL
FROM sys.databases
WHERE compatibility_level <> 100


مطالب
آموزش مفاهیم Data Warehouse

مفاهیم مقدماتی Data Warehouse :

OLTP   ( Online Transaction Processing ) : سیستم‌هایی می‌باشند که برای اهداف اصلی سازمان استفاده می‌شوند و این سیستم‌ها کار پردازش و ذخیره کردن داد‌ه‌ها را در OLTP Database انجام می‌دهند. مانند تمامی سیستم‌های ERP,MIS,…

OLTP Database  : پایگاه داده‌ی سیستم‌های OLTP می‌باشد. به طور معمول هر تراکنش کاربر در کمترین زمان ممکن برروی این سیستم‌ها ذخیره می‌گردد و در طول روز بار‌ها دستورات ( Insert/Update/Delete ) برروی آنها انجام می‌شود. این پایگاه‌های داده، همان Main Data ‌ها یا Source System ‌ها می‌باشند.

ETL  ( extract, transform, and load ) : مراحل انتقال داده از OLTP Database به پایگاه داده‌ی Stage می‌باشد. ETL سیستمی می‌باشد که توانایی اتصال به OLTP را دارد و اطلاعات را از OLTP واکشی می‌کند و به پایگاه داده‌ی Stage انتقال می‌دهد. سپس ETL داده‌ها را مجتمع ( integrates ) کرده و از Stage به DDS ( Dimensional Data Source ) انتقال می‌دهد .

Retrieves Data : عملیات واکشی داده‌ها طبق یک سری قوانین و قواعد می‌باشد .

برای انجام عملیات ETL دو روش وجود دارد

1. Data مجتمع ( Integrate ) و تمیز ( Data cleansing ) شود و در نهایت وارد Data Warehouse گردد.

2. Data وارد Data Warehouse گردد سپس مراحل مجتمع سازی و پاک سازی داده‌ها بر روی داده‌ها در خود Data Warehouse انجام گردد.

Consolidates Data : برخی شرکت‌ها داده‌های اصلی خودشان را در چندین پایگاه داده دارند. در این حالت برای انجام عملیات ETL باید داده‌ها تحکیم و مجتمع شوند و سپس در Data Warehouse  ذخیره شوند.

به طور کلی موارد زیر در فرایند   ETL در نظر گرفته می‌شود:

1. Data availability : برخی داده‌ها در یک سیستم وجود دارند ولی در سیستم دیگری وجود ندارند و یا تفاوت در نگهداری داده‌ها در سیستم‌های مختلف داریم. مثلا در یک سیستم آدرس در سه فیلد نگه داری می‌شود (کشور-شهر-آدرس) اما در سیستمی دیگر در دو فیلد(کشور-آدرس) نگه داری می‌شود. در این حالت باید ما در ETL راه کار هایی برای مجتمع کردن این موارد در نظر بگیریم.

2. Time ranges : در سیستم‌های مختلف امکان دارد بعد‌های زمانی مختلف باشد . مثلا در یک سیستم بررسی‌ها در بازه‌ی ساعتی و در سیستم دیگر بررسی‌ها در بازه‌ی روزانه یا ماهانه باشد . بنابر این در تجمیع داده‌ها باید این مورد مد نظر گرفته شود.

3. Definitions  : تعاریف در سیستم‌های مختلف می‌تواند متفاوت باشد. مثلا در یک سیستم، مبلغ کل فاکتور شامل مالیات می‌باشد ولی در سیستمی دیگر این مبلغ فاقد مالیات می‌باشد.

4. Conversion  : در فرآیند ETL باید باز از قواعد موجود در سیستم‌های مختلف آگاهی داشته باشیم. مثلا در یک سیستم ممکن است دما را به صورت سانتیگراد و در دیگری فارنهایت نگه داری کنند.

5. Matching : باید بررسی لازم را انجام دهیم که کدام داده مرتبط با کدام سیستم می‌باشد. به عبارت دیگر کدام سیستم مالک داده می‌باشد و دقیقا  داده‌ها در کدام سیستم معتبر‌تر می‌باشند. مثلا پرسنل، هم در سیستم حسابداری می‌باشند هم در سیستم پرسنلی؛ ولی معمولا داده‌های اصلی از سیستم پرسنلی می‌آیند.

Periodically : عملیات واکشی داده‌ها ( Retrieves Data ) و مجتمع سازی داده‌ها ( Consolidates Data ) در فرآیند   ETL فقط یکبار اتفاق نمی‌افتد و این مراحل در بازه‌های زمانی خاص تکرار می‌گردند. این واکشی و انتقال داده‌ها می‌تواند در روز چند بار تکرار شود یا می‌تواند چند روز یک بار اجرا گردد و این بستگی دارد به سیاست موجود در Data Warehouse .

DDS (Dimensional Data Source) (Data Warehouse) : یک پایگاه داده از نوع نرمال شده ( Normalized ) یا بعدی ( Dimensional ) می‌باشد. که داده‌های مجتمع شده و تمیز شده سیستم‌های OLTP را در خود جای داده است. این پایگاه داده برای واکشی‌های سیستم‌های آنالیز داده مورد استفاده قرار می‌گیرد. ورود اطلاعات در Data Warehouse به صورت Batch می‌باشد و به هیچ عنوان مانند پایگاه داده‌های OLTP ویرایش داده‌ها به صورت Online و هر زمان که داده‌ها تغییر می‌کنند، صورت نمی‌گیرد. اطلاعات در Data Warehouse معمولا به صورت تجمیع شده روزانه، ماهانه، فصلی یا سالانه می‌باشد. DDS ‌ها مجموعه ای از Dimensional Data Mart ‌ها هستند. و عمدتا به صورت denormalized می‌باشند.

Dimensional Data Mart : مجموعه ای از جداول Fact , Dimension می‌باشند که در یک بیزینس خاص باهم در ارتباط و مشترک می‌باشند.

dimensional data store schemas : طراحی‌های مختلفی از جداول Fact , Dimension در DDS وجود دارد که عبارتند از

1. Star schema : ساده‌ترین روش پیاده سازی Data Warehouse

2. Snowflake : در این روش جداول Dimension کمی نرمال سازی بیشتری دارند. سیستم‌های آنالیز داده با این روش بهتر کار می‌کنند.

3. Galaxy schemas : طراحی در این روش بسیار سخت و پیچیده می‌باشد. با این وجود فرایند ETL در این طراحی ساده‌تر انجام می‌شود.

نمونه‌ی طراحی Star به صورت زیر می‌باشد :

تفاوت‌های DDS و NDS :

1. در DDS ‌ها هیچ گونه نرمال سازی خاصی انجام نمی‌دهیم و عملا تمامی جداول را دینرمال کرده ایم، در حالی که در NDS تمامی جداول تا سطح سوم و گاهی تا سطح پنجم نرمال شده اند.

2. سرعت واکشی و پردازش کوئری‌ها روی DDS خیلی بیشتر از NDS ‌ها می‌باشد.

3. در صورتی که نیاز باشد Data Warehouse ‌های خیلی بزرگ طراحی کنیم با حجم بسیار زیاد توصیه می‌شود از NDS ‌ها استفاده شود در حالی که برای Data Warehouse ‌های کوچک و متوسط بهتر است از DDS ‌ها استفاده شود.

تصویر طراحی یک  (Enterprise Data Source = NDS) EDS در زیر آمده است :

History : جداول Data Warehouse میتوانند در طول زمان بسیار بزرگ شوند و دارای تعداد رکورد زیادی گردند. اینکه حداکثر داده‌های چند سال را در Data Warehouse نگه داری کنیم بستگی به سیاست‌های سازمانی دارد که سیستم OLAP برای آن تهیه می‌گردد. استفاده کردن از table partitioning می‌تواند در جبران افزایش تعداد رکورد کمک زیادی به ما بکند.

slowly changing dimension (SCD) : سه روش برای نگه داری سابقه‌ی تغییرات در جداول Dimension وجود دارد.

1. SCD type 1 : هیچ گونه سابقه‌ی تغییراتی را نگه داری نمی‌کنیم

2. SCD type 2 : سابقه‌ی تغییرات در ردیف‌ها نگه داری می‌شود. در این روش هر ردیف، شماره ردیف قبلی را دارد و تعداد نا محدودی از تغییرات را نگه داری می‌کنیم.

3. SCD type 3 : سابقه‌ی تغییرات در ستون‌ها نگه داری می‌شوند و فقط ردیف جاری و آخرین تغییرات را نگه داری می‌کنیم.

Query : فقط ETL حق تغییرات در Data Warehouse را دارد و کاربر نمی‌تواند Data Warehouse  را تغییر دهد. البته کاربران حق Query کردن از Data Warehouse را دارند.

دقت داشته باشید که کوئری‌های پیچیده در NDS ‌ها بسیار کندتر از همان کوئری در DDS می‌باشد.

Business Intelligence : مجموعه ای از فعالیت‌ها که در یک سازمان برای شناخت بهتر وضعیت Business آن سازمان انجام می‌شود. نتایج BI کمک بسیاری برای تصمیم گیری‌های تکنیکی و استراتژیکی درون سازمان می‌کند. همچنین کمک به بهبود فرایند‌های Business جاری می‌کند.

فعالیت‌های Business Intelligence در سه دسته بندی قرار می‌گیرند :

1. Reporting : گزارشاتی که از Data Warehouse گرفته می‌شود و به کاربر نمایش داده می‌شود و عمدتا این گزارشات به صورت tabular form می‌باشند.

2. OLAP : فعالیت‌های انجام شده روی MDB برای گرفتن گزارشات Drill-Down و ... می‌باشد.

3. Data mining : فرآیند واکشی و داده کاوی داده‌های درون سیستم می‌باشد، که منجر به کشف الگوها و رفتار‌ها و ارتباطات داده‌ها در سیستم می‌شود. توسط داده کاوی ما متوجه می‌شویم چرا برخی داده‌ها در سیستم تولید شده اند.

a. descriptive analytics : زمانی که از داده کاوی برای شرح وقایع گذشته و حال استفاده می‌شود.

b. predictive analytics : زمانی که از داده کاوی برای پیش بینی وقایع گذشته استفاده می‌شود.

Real time data warehouse  : به DW هایی گفته می‌شود که در کمترین زمان، تغییرات OLTP را در خود خواهند داشت. امروزه این نوع DW ‌ها تغییرات 5 دقیقه تا حداکثر 1 ساعت قبل را در خود دارند. برای دسترسی به چنین DW هایی دو راه زیر وجود دارد :

1. بر روی هر جدول، Trigger هایی باشد تا تغییرات را به DW انتقال دهد. (البته برای این منظور باید Business مربوط به ETL را در این تریگر‌ها نوشت)

2. سورس برنامه‌های اصلی کاربر ( OLTP ) تغییر کند تا علاوه بر OLTP Database ‌ها Data Warehouse را هم تغییر دهند.

روش‌های فوق بسیار روی سرعت و کارایی برنامه‌های اصلی تاثیر خواهند گذاشت.

NDS ( Normalize Data Source ) : در صورتی که طراحی Data Warehouse به صورت Dimensional نباشد و به صورت Normalize باشد، نوع Data Warehouse از نوع NDS می‌باشد.

روش ساخت MDB  :

OLTP Database -> ETL -> Stage Database ->  DDS (Dimensional Data Source = Data Warehouse) -> SSAS -> MDB

روش ساده‌تر ساخت Data Warehouse :

 

منظور از Source System  همان OLTP Database ‌ها می‌باشد.

به خاطر داشته باشید که Source System ‌ها جزئی از Data Warehouse نمی‌باشند.

از کاربرد‌های Data Warehouse می‌توان به موارد زیر اشاره کرد

1. Data Mining

2. استفاده در گزارشات

3. تجمیع داده ها

Data Mining کمک به درک بهتر Business جاری در سازمان می‌کند. همچنین منجر به کشف دانش از درون داده‌ها می‌شود.

برای Data Mining می‌توانید از انواع پایگاه داده‌های موجود مانند رابطه ای ، سلسله مراتبی و چند بعدی استفاده کرد . حتا می‌توان از فایل‌های XML , Excel نیز استفاده کرد.

Customer Relationship Management (CRM) :

منظور از مشتری، مصرف کننده‌ی سرویسی است که سازمان شما ارایه می‌کند. یک سیستم CRM شامل تمامی برنامه ایی می‌باشد که تمام فعالیت‌های مشتری را پشتیبانی می‌کند.

Operational Data Store (ODS) :

این پایگاه داده به صورت رابطه ای و نرمال شده می‌باشد و شامل تمامی اطلاعات پایگاه داده ای OLTP می‌باشد که در این پایگاه داده مجتمع شده اند. تفاوت ODS با Data Warehouse در این می‌باشد که داده‌ها در ODS با هر Transaction به روز می‌شوند (سرعت بروز رسانی اطلاعات در ODS بالاتر از DW می‌باشد).

Master Data Management (MDM)  :

در یک نگاه می‌توان داده‌ها را به دو دسته تقسیم کرد

1. transaction data

2. master data

transaction data : شامل داده ای transactional در سیستم‌های OLTP می‌باشد.

master data : توضیح دهنده‌ی Business جاری در سازمان می‌باشد.

برای تشخیص این دو نیاز است Business سازمان را به خوبی شناسایی نمایید. به عبارت دیگر رویداد‌های Business ی همان transaction data می‌باشند و master data شامل پاسخ‌های این سوال‌ها می‌باشد. چه کسی، چه چیزی و کجا در مورد Business transaction .

Customer data integration (CDI) : عبارت است از MDM در رابطه با مشتری داده ها. کار این قسمت عبارت است از واکشی، پاک سازی ، ذخیره سازی ، نگه داری و به اشتراک گذاشتن داده ای مشتری می‌باشد.

Unstructured Data : داده ای ذخیره شده در پایگاه داده ، structured Data می‌باشند و داده هایی مانند عکس و فیلم و صوت و ...

Service-Oriented Architecture (SOA) : یک متد ساخت برنامه می‌باشد که در این روش تمامی اجزا برنامه به صورت ماژول هایی دیده می‌شود که در آنها ارتباطات با دیگر سیستم‌ها به صورت سرویس می‌باشد و این زیر سیستم‌ها را می‌توان در پروژه‌های مختلف به کار برد.

Real-Time Data Warehouse : DW هایی که توسط ETL به روز می‌شوند در هنگامی که یک Transaction روی OLTP اتفاق می‌افتد.

مراحل انتقال داده از OLTP Database به MDB به صورت زیر می‌باشد.

Data quality : مکانیسم اطمینان بخشی از این که در DW دادهای مناسب و درست وارد می‌شوند. به عبارت دیگر DQ همان firewall برای DW در مقابل داده‌های نامناسب می‌باشد.

برای بهتر مشخص شدن مکان DQ شکل زیر را در نظر بگیرید

نحوه‌ی حرکت داده ای از OLTP به MDB اولین چیزی می‌باشد که شما باید به آن فکر کنید و برای آن روشی را انتخاب نمایید قبل از ساخت   Data Warehouse .

چهار روش برای معماری انتقال اطلاعات از OLTP به DW وجود دارد (البته به عنوان نمونه و شما می‌توانید از روش‌های دیگر و طراحی‌های مختلف و ترکیبی نیز بهره ببرید)

1. single DDS : در این روش فقط Stage , DDS وجود دارد.

2. NDS + DDS : در این روش علاوه بر Stage,DDS از NDS نیز استفاده می‌شود.

3. ODS + DDS : در این روش از Stage,ODS,DDS استفاده می‌گردد.

4. federated data warehouse (FDW ) : استفاده از چندین DW که با هم تجمیع شده اند.

تصویر Single DDS :

تصویر NDS + DDS :

تصویر ODS + DDS :

تصویر federated data warehouse (FDW ) :

منبع : Building a Data Warehouse With Examples in SQL Server  انتشارات Apress

مطالب
راهکار راه‌اندازی Infrastructure as a code
Infrastructure as code پروسه تعریف کردن ساختار Infrastructure در قالب یک سری فایل است؛ بجای اینکه با ابزارهایی Interactive مانند Portalها به مدیریت Infra بپردازیم.

مزیت این روش در آن است که در صورت داشتن Stageهای مختلفی مانند Development, QA, Sandbox, Production و ...، ابتدا در تعدادی فایل، ساختار Infra مورد نیاز را نوشته و به صورت اتوماتیک Development را از روی آن می‌سازیم و بعد در صورت جواب گرفتن، QA و ... را نیز از روی همان می‌سازیم و از اینجا به بعد هر تغییری در Infra ابتدا در Development تست شده و در صورت جواب گرفتن، به QA و سپس Production می‌رود.

این روش به علت خودکار بودن، باعث می‌شود امکان اشتباه پایین بیاید و بسته به روش پیاده سازی، می‌تواند خیلی شبیه به Migrationها در EntityFramework باشد؛ چرا که در آنجا نیز Migrationها ایجاد و بر روی دیتابیس Development اعمال می‌شوند و در صورت جواب گرفتن در تست‌ها، می‌توان تغییرات را به صورت خودکار روی QA و ... نیز ارسال نمود و امکان فراموش کردن چیزی در این میان وجود ندارد.

یکی از بهترین ابزارهای Infra as a code، ابزاری به نام Pulumi است که هم با kubernetes و هم با Azure و AWS و Google Cloud سازگار است. البته برای مثال Kubernetes خود روش‌هایی را برای نگهداری ساختار Infra در قالب فایل‌های کانفیگ‌اش دارد، ولی Pulumi هم سادگی و آسانی را ارائه می‌دهد و هم در Cloud که شما عموما از Database Serviceها و App Service و Logging Systemهای مختص خود Cloud استفاده می‌کنید که زیر مجموعه kubernetes نیستند، می‌توانید کنترل کل Cloud و Kubernetes را همزمان با یک ابزار انجام دهید.

برای مثال، افراد در Cloud به جای ساختن دیتابیس در Kubernetes، از Database as a service استفاده می‌کنند که به معنای رسیدن به کیفیت بالاتر و کاهش هزینه‌هاست. یا درخواست سرویس DDos protection و CDN یا Media Services و ... نیز مثال‌هایی دیگر از این نوع هستند.

برای کار با Pulumi هم می‌توانید از سایت آن، اکانت بگیرید که در این صورت Snapshotهای تغییرات Infra در کد، داخل سایت Pulumi نگهداری می‌شوند و هم می‌توانید Snapshotها را مشابه Snapshotهای Entity Framework داخل خود سورس کنترلر نگه دارید که در این صورت وابستگی به سرورهای Pulumi نیز نخواهید داشت.

بعد از نصب Pulumi CLI می‌توانید یک پروژه را با یکی از زبان‌های برنامه نویسی Go - C# - JavaScript - Python ایجاد نموده و سپس داخل آن Resourceهای خود را بسازید و تنظیمات Firewall را ایجاد کنید و ...

سپس با دستور Pulumi up تغییرات شما روی Development یا هر Stage دیگری که انتخاب کرده‌اید، اعمال می‌شوند. در نهایت اگر باز Infra احتیاج به تغییری داشته باشد، ابتدا فایل پروژه را تغییر می‌دهید و بعد سایر روال‌های لازم درون تیمی، اعم از Code Review و ... را می‌گذرانید و سپس مجدد Pulumi up را اجرا می‌کنید.

در ادامه یک نمونه کد را می‌بینیم، از راه اندازی App Service - Sql Server - Blob Storage - Application Insights

App Service ساخته شده که Backend ما را اجرا می‌کند، هم Connection String اتصال به دیتابیس را خواهد داشت و هم Connection String مربوط به Blob Storage را تا فایل‌هایش را درون آن ذخیره کند و در نهایت Application Insights هم وظیفه Monitoring را به عهده خواهد داشت.
var sqlDatabasePassword = pulumiConfig.RequireSecret("sql-server-nikola-dev-password");
var sqlDatabaseUserId = pulumiConfig.RequireSecret("sql-server-nikola-dev-user-id");

var resourceGroup = new ResourceGroup("rg-dds-nikola-dev", new ResourceGroupArgs
{
    Name = "rg-dds-nikola-dev",
    Location = "WestUS"
});

var storageAccount = new Account("storagenikoladev", new AccountArgs
{
    Name = "storagenikoladev",
    ResourceGroupName = resourceGroup.Name,
    Location = resourceGroup.Location,
    AccountKind = "StorageV2",
    AccountReplicationType = "LRS",
    AccountTier = "Standard",
});

var container = new Container("container-nikola-dev", new ContainerArgs
{
    Name = "container-nikola-dev",
    ContainerAccessType = "blob",
    StorageAccountName = storageAccount.Name
});

var blobStorage = new Blob("blob-nikola-dev", new BlobArgs
{
    Name = "blob-nikola-dev",
    StorageAccountName = storageAccount.Name,
    StorageContainerName = container.Name,
    Type = "Block"
});

var appInsights = new Insights("app-insights-nikola-dev", new InsightsArgs
{
    Name = "app-insights-nikola-dev",
    ResourceGroupName = resourceGroup.Name,
    Location = resourceGroup.Location,
    ApplicationType = "web" // also general for mobile apps
});

var sqlServer = new SqlServer("sql-server-nikola-dev", new SqlServerArgs
{
    Name = "sql-server-nikola-dev",
    ResourceGroupName = resourceGroup.Name,
    Location = resourceGroup.Location,
    AdministratorLogin = sqlDatabaseUserId,
    AdministratorLoginPassword = sqlDatabasePassword,
    Version = "12.0"
});

var sqlDatabase = new Database("sql-database-nikola-dev", new DatabaseArgs
{
    Name = "sql-database-nikola-dev",
    ResourceGroupName = resourceGroup.Name,
    Location = resourceGroup.Location,
    ServerName = sqlServer.Name,
    RequestedServiceObjectiveName = "Basic"
});

var appServicePlan = new Plan("app-plan-nikola-dev", new PlanArgs
{
    Name = "app-plan-nikola-dev",
    ResourceGroupName = resourceGroup.Name,
    Location = resourceGroup.Location,
    Sku = new PlanSkuArgs
    {
        Tier = "Shared",
        Size = "D1"
    }
});

var appService = new AppService("app-service-nikola-dev", new AppServiceArgs
{
    Name = "app-service-nikola-dev",
    ResourceGroupName = resourceGroup.Name,
    Location = resourceGroup.Location,
    AppServicePlanId = appServicePlan.Id,
    SiteConfig = new AppServiceSiteConfigArgs
    {
        Use32BitWorkerProcess = true, // X64 not allowed in shared plan!
        AlwaysOn = false, // not allowed in shared plan!
        Http2Enabled = true
    },
    AppSettings =
    {
        { "ApplicationInsights:InstrumentationKey", appInsights.InstrumentationKey },
        { "APPINSIGHTS_INSTRUMENTATIONKEY", appInsights.InstrumentationKey }
    },
    ConnectionStrings = new InputList<AppServiceConnectionStringArgs>()
    {
        new AppServiceConnectionStringArgs
        {
            Name = "AppDbConnectionString",
            Type = "SQLAzure",
            Value = Output.Tuple(sqlServer.Name, sqlDatabase.Name, sqlDatabaseUserId, sqlDatabasePassword).Apply(t =>
            {
                (string _sqlServer, string _sqlDatabase, string _sqlDatabaseUserId, string _sqlDatabasePassword) = t;
                return $"Data Source=tcp:{_sqlServer}.database.windows.net;Initial Catalog={_sqlDatabase};User ID={_sqlDatabaseUserId};Password={_sqlDatabasePassword};Max Pool Size=1024;Persist Security Info=true;Application Name=Nikola";
            })
        },
        new AppServiceConnectionStringArgs
        {
            Name = "AzureBlobStorageConnectionString",
            Type = "Custom",
            Value = Output.Tuple(storageAccount.PrimaryAccessKey, storageAccount.Name).Apply(t =>
            {
                (string _primaryAccess, string _storageAccountName) = t;
                return $"DefaultEndpointsProtocol=https;AccountName={_storageAccountName};AccountKey={_primaryAccess};EndpointSuffix=core.windows.net";
            })
        }
    }
});

appService.OutboundIpAddresses.Apply(ips =>
{
    foreach (string ip in ips.Split(','))
    {
        new FirewallRule($"app-srv-{ip}", new FirewallRuleArgs
        {
            Name = $"app-srv-{ip}",
            EndIpAddress = ip,
            ResourceGroupName = resourceGroup.Name,
            ServerName = sqlServer.Name,
            StartIpAddress = ip
        });
    }

    return (string?)null;
});
حال فرض کنید در Sprint جدید، شروع به استفاده از Redis می‌کنیم. به این ترتیب فایل بالا تغییر می‌کند و یک Redis نیز به آن اضافه می‌شود. فایل بالا Single source of truth است و در واقع با نگاه به آن می‌فهمیم که Infra مان چه ساختاری دارد (دقیقا مشابه مدل در Entity Framework Core).

سپس زمانیکه تغییرات قرار است روی QA برود، روال CI/CD می‌تواند به صورت خودکار ابتدا Infra مربوط به خودش را (یعنی QA) را تغییر دهد تا Redis دار شود و سپس پروژه را پابلیش کند و Migrationهای مربوط به Database را هم اجرا کند و اگر کل این فرآیند با موفقیت طی شود، مجدد در هنگام پابلیش به Production نیز بدون هر گونه کار دستی، تمامی این موارد به شکل خودکار اعمال می‌شوند و این خود یک بهبود اساسی را در روال DevOps پروژه ایجاد می‌کند.