اشتراک‌ها
نگاهی به مشخصات SQL Server 2019

SQL Server 2019 is designed to solve challenges of the modern data professional including:

  • Store enterprise data in a data lake and offer SQL and Spark query capability overall data
  • Reduce the need for Extract, Transform, and Load (ETL) applications by eliminating data movement
  • Integrate and secure machine learning applications with scalable performance
  • Reduce the need for application and query changes to gain a boost in performance
  • Increase confidential computing of data through hardware enclaves
  • Increase application and database uptime and availability through features like ADR (Advanced Database Recovery)
  • Extend the power of the T-SQL language in a secure and robust fashion
  • Run applications and deploy databases across multiple operating systems and platforms with compatibility
  • Reduce the risk of upgrades while using new SQL capabilities when you are ready though inbuilt database compatibility levels 
نگاهی به مشخصات SQL Server 2019
مطالب
Base64 و کاربرد جالب آن
Base64 یک مبنای عددی است که یکی از کاربرد‌های آن در نرم افزار‌ها انتقال اطلاعات فایل باینری است. به عنوان مثال با تبدیل محتوای باینری یک تصویر به مبنای 64 میتونید اون تصویر رو در دل فایل هایی نظیر HTML و CSS و SVG قرار بدید؛ یا به اصطلاح اون تصویر رو Embeded (توکار) کنید.

نکته: در Base64 برای هر 6 بیت یک کاراکتر معادل در مبنای 64 در نظر گرفته میشه، به همین دلیل در هنگام تبدیل برای جلوگیری از Lost (گم) شدن داده‌ها عملیات مورد نظر رو بر روی سه بایت داده انجام میدیم. که با این کار برای هر 3 بایت (24 بیت) 4 کاراکتر معادل خواهیم داشت؛ به این ترتیب حجم نهایی فایل تبدیل شده در واحد بایت، برابر است با:

(حجم نهایی) = (3 / حجم کل فایل) + (حجم کل فایل)


و حالا نحوه تبدیل فایل تصویر به Base64:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Image2Base64Converter
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Multiselect = false;
            ofd.Filter = "Pictures |*.bmp;*.jpg;*.jpeg;*.png";

            if (ofd.ShowDialog(this) == DialogResult.OK)
            {
                txtImagePath.Text = ofd.FileName;
            }
        }

        private void btnConvert_Click(object sender, EventArgs e)
        {
            if (!File.Exists(txtImagePath.Text))
            {
                MessageBox.Show("File not found!");
                return;
            }

            btnCopy.Enabled = false;
            btnConvert.Enabled = false;
            txtOutput.Enabled = false;

            BackgroundWorker bworker = new BackgroundWorker();
            bworker.DoWork += (o, a) =>
            {
                string header = "data:image/{0};base64,";
                header = string.Format(header, txtImagePath.Text.GetExtension());

                StringBuilder data = new StringBuilder();

                byte[] buffer;
                BinaryReader head = new BinaryReader(
                    new FileStream(txtImagePath.Text, FileMode.Open));

                buffer = head.ReadBytes(6561);
                while (buffer.Length > 0)
                {
                    data.Append(Convert.ToBase64String(buffer));
                    buffer = head.ReadBytes(6561);
                }

                head.Close();
                head.Dispose();

                this.Invoke(new Action(() =>
                {
                    txtOutput.ResetText();
                    txtOutput.AppendText(header);
                    txtOutput.AppendText(data.ToString());

                    btnCopy.Enabled = true;
                    btnConvert.Enabled = true;
                    txtOutput.Enabled = true;
                }));
            };

            bworker.RunWorkerAsync();
        }

        private void btnCopy_Click(object sender, EventArgs e)
        {
            Clipboard.SetText(txtOutput.Text);
        }
    }

    public static class ExtensionMethods
    {
        public static string GetExtension(this string str)
        {
            string ext = string.Empty;
            for (int i = str.Length - 1; i >= 0; i--)
            {
                if (str[i] == '.')
                {
                    break;
                }

                ext = str[i] + ext;
            }

            return ext;
        }
    }
}
توضیح کد:
در خط 44 یک BackgroundWorker تعریف شده است تا عملیات تبدیل در یک ترد جداگانه انجام شود، که در عملیات‌های سنگین ترد اصلی برنامه آزاد باشد.
در خطوط 47 تا 64 کدهای مربوط به تبدیل قرار گرفته است:
در خط 47 و 48 ابتدا یک سرآیند برای معرفی داده‌های تبدیل شده ایجاد میکنیم؛ ",data:image/{0};base64" که در ان نوع فایل و پسوند آن را مشخص کرده و سپس الگوریتم به کار گرفته شده برای تبدیل آن را نیز ذکر میکنیم: ":data" + نوع فایل (image) + "/" + پسوند فایل + ";" + الگوریتم تبدیل + ",".
در انتهای کار این سرآیند تولید شده در ابتدای داده‌های تبدیل شده فایل، قرار خواهد گرفت.
در خط 50 یک StringBuilder برای نگهداری اطلاعات تبدیل شده ایجاد کرده ایم.
در خط 52 یک بافر برای خواندن اطلاعات باینری فایل ایجاد کرده ایم.
در خط 53 فایل مورد نظر را برای خواندن باز کرده ایم.
و در خطوط 56 تا 61 فایل مورد نظر را خوانده و پس از تبدیل در متغیر data ذخیره کرده ایم.
در نظر داشته باشید که برای عملکرد صحیح لازم است که عملیات تبدیل بر روی 3 بایت داده انجام شود؛ پس در هر بار  خواندن داده‌های فایل، باید مقدار داده ای که خوانده میشود ضریبی از 3 باشد.
در خطوط 63 و 64 نیز منابع اشغال شده سیستم را آزاد کرده ایم.
در انتها داده‌های مورد استفاده برای Embeded کردن تصویر برابر است با:
()header + data.ToString

embeded-images.htm : فایل نمونه برای نحوه استفاده از تصویر توکار.
Image2Base64-Converter.zip : سورس کامل برنامه ارائه شده.
مطالب
توسعه یک Web API با استفاده از ASP.NET Core و MongoDb (قسمت اول)

در این مقاله قصد داریم یک Api تحت وب را با استفاده از فریم‌ورک ASP.NET Core توسعه دهیم تا عملیات CRUD را بر روی دیتابیس MongoDb که یکی از محبوب‌ترین دیتابیس‌های NoSql است، انجام دهد. قبل از شروع کار باید ویژوال استودیو نسخه‌ی 2019 را نصب داشته باشید؛ به‌طوریکه ورک لود ASP.NET and web development را  هم حتما همراه آن نصب کرده باشید. علاوه بر آن باید .Net Core SDK 3.0+ و دیتابیس MongoDb را هم نصب کنید که می‌توانید آنها را از آدرس‌های زیر دانلود کنید. نگران نصب MongoDb هم نباشید چون نکته خاصی ندارد. 

https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/

https://dotnet.microsoft.com/download/dotnet-core

نسخه‌ی جاری MongoDb، 4.4 است که پس از نصب، به صورت پیشفرض در آدرس C:\Program Files\MongoDB قرار می‌گیرد. در مسیر C:\Program Files\MongoDB\Server\4.4\bin فایل‌های اصلی MongoDb قرار دارند و برای تعامل با MongoDb، به این فایل‌ها نیاز خواهیم داشت. پس برای اینکه به راحتی بتوان در هر جای سیستم از طریق پاورشل به این فایل‌ها دسترسی داشته باشید، این مسیر را به Path environment variable ویندوز اضافه کنید.

MongoDb دارای یک بخش اصلی یا اصطلاحا یکdaemon  است که وظیفه‌ی آن، پردازش درخواست‌هایی است که برای کار با داده‌ها صادر می‌شود. در حقیقت همه کارهایی که ما با داده‌ها انجام می‌دهیم مثلا دسترسی به داده‌ها و دستکاری آن‌ها، از طریق این daemon انجام می‌گیرد و پشت صحنه‌ی این daemon، با Storage Engine کار خواهد کرد.  برای اجرای daemon، پاور شل را باز کنید و دستور mongod را وارد کنید. اگر با تنظیمات پیشفرض اجرا کنید، بر روی پورت 27017 بالا آمده و فایل‌های دیتابیس را هم در مسیر C:\data\db قرار می‌دهد. اگر این مسیر را نداشته باشید، با خطا مواجه می‌شوید. یا باید این مسیر را تعریف کنید و یا از سوئیچ dbpath -- استفاده کنید تا مسیر فایل دیتابیس را تغییر دهید. پس پاور شل را باز کنید و دستور زیر را وارد کنید.

>> mongod --dbpath C:\BooksData
پس از اجرا شدن daemon ، باید از طریق شل mongo که یک شل جاوااسکریپتی است، به آن متصل شویم. از طریق این شل می‌توان کوئری‌ها و دستورات دستکاری داده‌ها را بر روی دیتابیس MongoDb اجرا کنیم. پس یک کنسول پاورشل جدید را باز کرده و دستور زیر را در آن وارد کنید.
>> mongo
پس از متصل شدن به شل، از طریق دستورuse ، یک دیتابیس را به نام BookstoreDb بسازید. بنابراین دستور زیر را وارد کنید.

>> use BookstoreDb
توجه کنید اگر از قبل این دیتابیس وجود داشته باشد، از آن استفاده می‌کند و گرنه آن را خواهد ساخت. بعد از اینکه پیغام switched to db BookstoreDb را مشاهده کردید، می‌توانید هر جا که به این دیتابیس نیاز داشته باشید، از دستور db استفاده نمایید که اشاره به دیتابیسی دارد که آن را use کرده‌ایم.

بعد از ساختن دیتابیس، باید یک کالکشن بسازید. کالکشن‌ها را می‌توان معادل جداول، در دیتابیس‌های رابطه‌ای تصور کرد. با دستور createCollection می توان اینکار را انجام داد. برای اینکار دستور زیر را وارد کنید.

>> db.createCollection('Books')
با این دستور، یک کالکشن با نام Books ساخته می‌شود. اگر پیغام { ok" : 1" } را دیدید، مطمئن باشید که کالکشن Books به درستی ساخته شده‌است. در واقع بعد از ساختن اولین کالکشن، دیتابیس ساخته می‌شود. با دستور show dbs می‌توانید دیتابیس‌های ساخته شده را ببینید.

بعد از ساختن کالکشن، می‌خواهیم مقداری دیتا را در آن قرار دهیم. معادل رکورد در دیتابیس‌های رابطه‌ای، در دیتابیس مونگو دی‌بی، Document نام دارد که مانند رکوردهای دیتابیس‌های رابطه‌ای نیست و ساختار و اسکیمای خاصی ندارد؛ یعنی می‌توان هر دیتایی را با هر ساختاری در آن ذخیره کرد. می‌خواهیم دو Document را به کالکشن Books اضافه کنیم. پس دستور زیر را وارد می‌کنیم. توجه کنید داده‌ها با ساختار json وارد می‌شوند.

>> db.Books.insertMany([{'Name':'Design Patterns','Price':54.93,'Category':'Computers','Author':'Ralph Johnson'}, {'Name':'Clean Code','Price':43.15,'Category':'Computers','Author':'Robert C. Martin'}])
بعد از اجرای دستور بالا، نتایج زیر را در خروجی می‌بینید که گویای این مطلب است که دو Document جدید اضافه شده‌است و خود سرور، به هر یک از داکیومنت‌ها، یک شناسه یا آی دی اختصاص داده‌است و Ack درست هم برگشت داده شده‌است که به معنای انجام درست کار است. اگر می‌خواهید خودتان به داکیومنت‌هایی که می‌سازید آی دی بدهید، باید از پراپرتی id_ استفاده نمایید.
 {
      "acknowledged" : true,
      "insertedIds" : [
         ObjectId("5bfd996f7b8e48dc15ff215d"),
         ObjectId("5bfd996f7b8e48dc15ff215e")
      ]
}
برای اینکه محتویات کالکشنی را مشاهده کنید، دستور زیر را وارد کنید. همانطور که اشاره شد، db، به دیتابیس ساخته شده اشاره دارد؛ Books همان کالکشن‌مان است و با استفاده از متد find می‌توان داده‌های کالکشن را جستجو کرد که در این مثال ما، هیچ فیلتری به آن نداده‌ایم. پس در نتیجه تمام دیتاها را بر می‌گرداند. متد pretty هم داده‌های برگشتی را در یک ساختار مرتب نمایش می‌دهد.
>> db.Books.find().pretty()
و خروجی زیر را مشاهده خواهید کرد
 {
      "_id" : ObjectId("5bfd996f7b8e48dc15ff215d"),
      "Name" : "Design Patterns",
      "Price" : 54.93,
      "Category" : "Computers",
      "Author" : "Ralph Johnson"
},
{
      "_id" : ObjectId("5bfd996f7b8e48dc15ff215e"),
      "Name" : "Clean Code",
      "Price" : 43.15,
      "Category" : "Computers",
      "Author" : "Robert C. Martin"
}
حالا دیتابیس ما آماده شده‌است. در بخش‌های بعدی با استفاده از فریم ورک   ASP.NET Core Web Api  ، Api هایی خواهیم نوشت که داده‌های این دیتابیس را به بیرون ارائه خواهد داد. 

مطالب
آشنایی با SQL Server Data Tools
مقدمه
یکی از امکانات اضافه شده در Sql Server 2012 ابزار Sql Server Data Tools یا به اختصار SSDT می‌باشد. این ابزار در واقع جایگزین ابزار Business Intelligence Development Studio می باشد که همه امکانات قبلی را داشته و همچنین قابلیت‌های جدیدی نیز به آن اضافه شد است. اما کاربرد این ابزار ایجاد محیطی یکپارچه برای طراحی و توسعه تمامی نسخه‌های پایگاه داده Sql Server با استفاده از Visual Studio می‌باشد. در این مقاله من به بیشتر بر روی امکانات زیر تمرکز دارم:
  • Installation
  • Creating a SQL Server Database Project
  • Modify Database Schema
  • Schema Compare and Update
  • Snapshot Project
  • Publish
  1. نصب Sql Server Data Tools
    آخرین نسخه این ابزار را از این آدرس دانلود کنید یا زمان نصب Sql Server 2012 گزینه آن را انتخاب کنید


  2. ایجاد یک پروژه جدید از نوع  SQL Server Database Project
    پس از نصب SSDT شما از طریق Visual Studio 2012 Shell که همراه SqlServer 2012 نصب می‌شود یا با Visual Stadio 2012 یک پروژه جدید از نوع SQL Server Database Project ایجاد کنید.

     Server Database Project Project به شما امکان توسعه پایگاه داده Sql Server را با استفاده  از محیط یکپارچه Visual Studio با در اختیار گذاشتن ابزار‌های همچون navigation, intellisense, validation, debugging, declarative editing و غیره را می‌دهد. شی پایگاه داده شما در پروژه و فایل‌های مجزا ذخیره می‌شود مثل آن که شما در حال توسعه برنامه #C یا VB.NET هستید.
  3. ورود پایگاه داده موجود به پروژه SQL Server Database
    شما می‌توانید شمای پایگاه داده موجود یا SQL Server DAC Package File (.dacpac) یا هر T-SQL دیگری را با راست کلیک بر روی پروژه و انتخاب گزینه Import به پروژه خود اضافه و تغییرات لازم را اعمال نماید شکل زیر پنجره Import Database  را نشان می‌دهد:
     

      پنجره 
    Solution Explorer امکانات زیر را در اختیار شما قرارمی دهد:

    - اضافه کردن اشیای همچون Table، View  و غیره با راست کیلک کردن بر روی پروژه و انتخاب گزینه Add
    - ویرایش اشیا موجود با دبل کیلک کردن بر روی اشیا
    - مقایسه شمای پایگاه داده با پایگاه داده دیگر و یا Microsoft SQL Server DAC Package File کافیست بر روی پروژه راست کیلک و گزینه Schema Compare را         انتخاب نمایید.
    - ایجاد یک Snapshot از شمای پایگاه داده در یک Microsoft SQL Server DAC Package File . یک snapshot برای ایجاد یک پایگاه داده یا ورود در پروژه ای دیگر یا در مقایسه دو پایگاه داده کاربرد دارد.
    - انتشار پایگاه داده که امکان ایجاد پایگاه داده یر روی یک سرور SQL Server را فراهم می‌نماید.  

  4. مقایسه شمای دو پایگاه داده با هم
    SSDT ابزاری برای مقایسه دو پایگاه داده و بروز رسانی پایگاه داده مقصد از روی شمای منبع از طریق ایجاد یک Script یا به صورت مستقیم را می‌دهد.



  5. انتشار پروژه با استفاده از SQL Server Data Tools
    این ابزار امکان گسترش پروژه شما بر روی SQL Server 2005, 2008, 2008 R2, 2012, یا SQL Azure instance را می‌دهد. برای انتشار کافیت از پنجره Solution Explorer  بر روی پروژه راست کیلک و گزینه Publish را انتخاب کنید.

  6. پنجره SQL Server Object Explorer
    این پنجره با اتصال به سرور SQL Server  امکان دسترسی و مدیریت پایگاه داده را به ما می‌دهد. علاوه بر دسترسی به اجزای یک پایگاه داده امکان مدیریت پوشه‌های Security , Server Objects نیز فراهم می‌باشد. همچنین امکان اتصال به Sql Server Express , localdb نیز وجود دارد. 


  7.   
مطالب
سیستم‌های توزیع شده در NET. - بخش دوم - چرا یک سخت افزار به تنهایی پاسخگوی نیازمندی‌های ما نیست؟
 قبل از شروع به بحث در مورد سیستم‌های توزیع شده، بهتر است ابتدا به سوالی اساسی که اساس بوجود آمدن سیستم‌های توزیع شده است، پاسخ دهیم:

چرا یک سخت افزار به تنهایی پاسخگوی همه نیاز‌های ما نیست؟

همه می‌دانیم که در یک هسته‌ی از پردازنده، چیزی بعنوان پردازش موازی وجود ندارد. هر هسته در هر لحظه می‌تواند یک پردازش را انجام دهد و این سرعت بالای در پردازش عملیات جاری و سوئیچ کردن بین دیگر عملیات است که حس موازی اجرا شدن آنها را به ما می‌دهد. یعنی در صورتیکه بخواهیم در یک سخت افزار با پردازنده‌ی تک هسته‌ای، برنامه نویسی موازی انجام بدهیم، در واقع هیچیک از عملیات ما بصورت موازی انجام نمی‌شوند. زمان پردازشی پردازنده، بر اساس تعداد عملیات و اولویت آنها، بین آنها تقسیم می‌شود. هر لحظه یکی از آنها اجرا می‌شود و با اتمام زمان اجرایش، نوبت به بعدی می‌رسد تا جاییکه تمام آنها به اتمام برسند. در این حالت پردازنده تک هسته‌ای، برای 2 کار زمان صرف می‌کند؛ اول اجرای عملیات جاری و دوم سوئیچ کردن به عملیات بعدی.

حال در صورتیکه تعداد عملیاتی که باید در سیستم بصورت همزمان انجام شوند بیشتر شود، زمانیکه پردازنده باید برای سوئیچ صرف کند نیز بیشتر شده و در نتیجه زمان اجرای عملیات بیشتر می‌شود و آنها دیر‌تر به اتمام میرسند. با بیشتر شدن تعداد این عملیات، کار به جایی می‌رسد که دیگر پردازنده هیچ زمانی را برای پردازش یک عملیات ندارد و باید تمام وقت خود را با سوئیچ کردن بین آنها صرف کند. بله؛ ما سیستمی را طراحی کرد‌ه‌ایم که شامل مجموعه‌ای از عملیات است که هیچ یک اجرا نمی‌شوند!

راه حل چیست؟

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


اینجا بود که نیازمندی‌های ما باعث شدند سخت افزارها پیچیده‌تر شوند. البته پیچیدگی بود که باعث تکامل آنها شد. تا اینجا برای انجام تعداد عملیات بیشتر می‌توانیم سخت افزار را ارتقاء دهیم. همچنین در اینجا بود که مفهوم Parallel Systems تکامل پیدا کرد؛ سیستمهایی که توانایی اجرای همزمان چند عملیات را داشتند که همه آنها از یک حافظه، بصورت مشترک استفاده می‌کردند.

مشکل سیستمهای Parallel مشخص است. کارآیی این نوع سیستم، کاملا به سخت افزار و نوع پیاده سازی آنها وابسته است. یعنی در صورت نیاز به کارآیی بیشتر، تنها راه ارتقاء سخت افزار و بهینه کردن کدهاست. اما این روال را تا کجا می‌توانیم انجام دهیم؟

برای روشن شدن مشکل بالا بیایید یک Web Application را بر روی یک سخت افزار اجرا کنیم. در یک Web Application یک Thread Pool شامل مجموعه‌ای از Threadها می‌باشد که هر Thread وظیفه اجرای یک درخواست را بر عهده دارد. یعنی با دریافت یک درخواست، یک Thread از این مجموعه کم می‌شود و وظیفه پاسخ دهی به آن در خواست را بر عهده می‌گیرد. تعداد Thread هایی که در یک Thread Pool می‌باشند نیز وابسته به تعداد هسته‌های پردازنده می‌باشد. برای این تعداد بصورت پیشفرض مقداری در نظر گرفته می‌شود که بیشترین کارآیی را در یک هسته داشته باشد؛ مثلا در ASP.NET بصورت پیشفرض به ازای هر هسته‌ی از CPU، تعداد 20 Thread به این مجموعه اضافه می‌شود. یعنی ما در یک پردازنده 2 هسته‌ای تنها می‌توانیم تعداد 40 درخواست را بصورت همزمان دریافت کنیم. در صورتیکه تعداد در خواستها در یک لحظه بیشتر از این تعداد باشد، تمام درخواست‌های اضافی در صف دریافت قرار می‌گیرند تا یکی از این Thread‌ها به درخواست خودش پاسخ دهد و به Thread Pool بازگردد و آماده اجرای درخواست بعدی باشد.

حال با فرض اینکه بصورت میانگین به هر درخواست در مدت 2 ثانیه پاسخ داده شود و در طول هر 2 ثانیه ما تعداد 200 درخواست جدید دریافت کنیم، یعنی در هر 2 ثانیه تعداد 160 درخواست در صف پردازش درخواست باقی می‌مانند. یعنی در مدت 10 ثانیه تعداد 800 درخواست پردازش نشده در این صف وجود دارند. در صورتیکه این روال ادامه پیدا کند، صف پردازش بزرگتر و بزرگتر می‌شود؛ تا جایی که دیگر حافظه‌ای برای دریافت درخواستهای جدید نباشد. اینجاست که سیستم ما از دسترس خارج می‌شود. پس تصمیم می‌گیریم سخت افزار خود را ارتقاء دهیم و کدهای خود را نیز بهینه کنیم. مثلا جاییکه عملیات I/O را انجام می‌دهیم، برای استفاده‌ی بهینه از Thread‌های موجود، کدهای خود را بصورت Async اجرا کنیم.

تا حدودی مشکل ما فعلا حل شده‌است. بعد از مدتی بدلیل اضافه شدن نیازمندی‌های جدید، تعدادکاربران فعال سیستم زیاد می‌شود و دوباره مشکل پوشش دادن تعداد بیشتر درخواست بوجود می‌آید. مجبوریم دوباره عملیات Scale-up یا Vertical scaling را انجام دهیم. بله؛ عملیاتی که ما در این سیستم‌ها برای مقیاس‌پذیری انجام می‌دهیم، اصطلاحا  Vertical scaling یا Scale-up نام دارد. یعنی با افزایش تعداد کاربران یا تعداد درخواست، کدها بهینه‌تر و سخت افزار ارتقاء پیدا می‌کند.

البته مثالی که ذکر شد به هیچ وجه با دنیای واقعی قابل مقایسه نیست. ممکن است شما سرویسی بسیار حیاتی را پیاده سازی کرده باشید که در شرایط خاص، هزاران یا میلیون‌ها کاربر بصورت همزمان بخواهند درخواستهای خود را برای شما ارسال کنند. در این حالت شما دو راه دارید؛ اول اینکه مرتبا سرویس بسیار حیاتی خود را از دسترس خارج کنید و منتظر بمانید تا حجم تعداد درخواست‌های کاربران کاهش یابد و یا مجبورید سخت افزار سرور خود را آنقدر ارتقاء دهید، تا این تعداد درخواست را بصورت همزمان پوشش دهد. واقعا هزینه تهیه کردن این سرور چقدر است؟

فرض کنید از سمت پایگاه داده نیز با مشکل روبرو شده‌ایم. حجم داده‌های ما روبه افزایش است. فضای حافظه‌ی آزاد تنها Server ی که داده‌های ما را ذخیره می‌کند، رو به اتمام است. چاره چیست؟ آن را ارتقا دهیم؟ بله برای مدتی سرور را از دسترس خارج کرده و فضای آزاد را افزایش می‌دهیم. در این بین تمام سرویس‌های ما که وابسته به این سرور هستند، از دسترس خارج می‌شوند. این کار برای داده‌هایی که ذاتا همیشه رو به افزایش هستند، چقدر باید تکرار شوند؟ چقدر باید هزینه کنیم تا این داده‌ها که تمام سرویس‌های ما به آنها وابسته هستند، با مشکل مواجه نشوند، یا کارآیی بازیابی آنها پایین نیاید؟

حال بیاید از زاویه دیگری به ماجرا نگاه کنیم ما یک سرویس بسیار حساس با تعداد کاربران زیادی را داریم. از دسترس خارج شدن این سرویس برای ما بسیار هزینه بر است. اما تنها سرور بسیار قوی ما که برای آن هزینه‌ی بسیار زیادی را پرداخت کرده‌ایم، با مشکلی مواجه شده که ممکن است زمان زیادی برای رفع مشکل آن صرف شود. بله باز سرویس از دسترس خارج شده و ما با مشکل بسیار جدی مواجه شده‌ایم که ممکن است آینده‌ی سرویس بسیار مهم را به خطر بیاندازد. چاره چیست؟ مثلا تعدادی سرور مشابه سرور اصلی را خریداری کنیم و در صورتیکه سرور اصلی با مشکل جدی مواجه شد از آنها استفاده کنیم. بله هزینه چند برابر شد. فرض کنید به هر دلیل، برق قسمتی که شما این سرورها را نگهداری می‌کنید، قطع شد! چه راهکاری را دارید؟ واقعیتی که باید بپذیریم این است که چون ما یک سرور را برای اجرای Application خودمان داریم، در هرصورت اگر این سرور با مشکلی مواجه شود، تمام سرویس‌های ما با خطری جدی مواجه می‌شوند و ما نیز در صورتیکه بخواهیم این چرخه‌ی معیوب را ادامه دهیم، تنها هر بار صورت مسئله را پاک می‌کنیم. بهتر است روش جدیدی را برای این مشکل بیابیم.

اینجاست که مفهوم سیستمهای توزیع شده به کمک سیستمهای Parallel می‌آید و مفهوم Scale-up یا Vertical scaling  با مفهموم Horizontal Scaling یا Scale-out ادغام می‌شود. در قسمت بعدی، با مفاهیم، خصوصیات و اصطلاحات موجود در این سیستم‌ها آشنا می‌شویم.
اشتراک‌ها
تعریف محرمانگی اطلاعات

The need to maintain information privacy is applicable to collected personal information, such as medical records, financial data, criminal records, political records, business related information or website data 

تعریف محرمانگی اطلاعات
نظرات مطالب
مدل EAV چیست؟
آن طور که بنده اطلاع دارم، در دیتا بیس‌های NoSQL برای سیستم هایی با حجم داده‌های بزرگ قابل استفاده است(چند صد میلیونی)، و شیوه طراحی آن به گونه ایی است که هرچه داده‌ها بیشتر شوند سرعت جستجو هم مطابق تابع نمایی بالا می‌رود.
مطالب
معماری پایگاه داده چند مستاجری (Multi-Tenant Data Architecture)
 اعتماد و یا فقدان آن، عامل شماره یک مسدود کردن استفاده از نرم افزار به عنوان خدمات است. معماری پایگاه داده چند مستاجری برای رسیدگی به مشکل نرم افزار به عنوان سرویس (SaaS) که می‌تواند خدمات به تعدادی کلاینت ارائه کند استفاده می‌شود . معماری دیتابیس چند مستاجری وقتی مفید است که یک نمونه از دیتابیس به تعدادی کلاینت خدمات دهد. وقتی که نرم افزار‌های محلی نصب می‌کنید نرم افزارهای به عنوان یک سرویس با مشتریان متمرکز، دسترسی به داده‌ها مبتنی بر شبکه با سربار کمتر را فراهم می‌کنند. اما به منظور برخورداری بیشتر از مزیت‌های یک نرم افزار سرویس، یک سازمان باید از سطحی از کنترل روی داده صرفنظر کند و به فروشنده نرم افزار جهت نگهداری و امنیت به دور از چشم آنها اعتماد کند.

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

  سه روش مدیریت چند مستاجری داده
  1. دیتابیس‌های جداگانه برای هر مستاجر
  2. دیتابیس مشترک و schema جداگانه برای هر مستاجر
  3. دیتابیس مشترک و schema مشترک 

  انتخاب روش مناسب برای برنامه شما به عوامل زیر بستگی دارد :
  • سایز دیتابیس هر مستاجر
  • تعداد مستاجران
  • تعداد کاربران هر مستاجر
  • نرخ رشد مستاجر
  • نرخ رشد دیتابیس مستاجر
  • امنیت  
  • هزینه

1) دیتابیس‌های جداگانه برای هر مستاجر :
ذخیره سازی داده‌های مستاجران در دیتابیس‌های جداگانه ساده‌ترین روش است. در این روش هر مستاجر یک دیتابیس دارد. منابع و کدهای برنامه معمولا در سرور بین همه مستاجران مشترک است اما هر مستاجر مجموعه ای از داده دارد که بطور منطقی از سایر مستاجران جدا شده است.

  مزایا :
  • امنیت بیشتر
  • سهولت سفارشی سازی برای هر مستاجر
  • سهولت نگهداری ( Backup و Restore ) برای هر مستاجر

معایب:
  • برای نگهداری سخت افزار قوی مورد نیاز است
  • این روش هزینه بیشتری برای تجهیزات ( Backup و Restore ) برای هر مستاجر دارد

  2)   دیتابیس مشترک و schema جداگانه برای هر مستاجر :
خدمات دهی به چندین مستاجر در یک دیتابیس مشترک اما هر مستاجر یک مجموعه از جداول گروهبندی شده دارد که با Schema جدا شده است که برای هر مستاجر الزامی است.

مزایا :
  • برای دیتابیس برنامه‌های کوچک مناسب است. وقتی تعداد جداول برای هر مشتری کم است
  • هزینه کمتری نسبت به روش اول دارد
  • برای مشتریانی که نگران امنیت هستند، سطح منطقی مناسبی برای جداسازی داده ه وجود دارد

معایب:
  • اطلاعات مستاجران در صورت بروز خطا به سختی restore می‌شود
  • مدیریت آن برای دیتابیس‌های بزرگ مشکل است

  3)   دیتابیس مشترک و schema مشترک :

این روش شمامل یک دیتابیس و یک مجموعه از جداول برای چندین مستاجر است. داده‌های جدول می‌تواند شامل رکورد‌های هر مستاجر باشد

مزایا :
  • در مقایسه با روش قبلی، کمترین هزینه سخت افزاری را دارد
  • می‌تواند مستاجران بیشتری رادر هر سرور پشتیبانی کند
  • قابلیت بروز رسانی آسان در یک جا برای همه مستاجران
  • مدیریت آسان دیتابیس و خطا و Backup و Restore
معایب:
  • امنیت بیشتری مورد نیاز است تا مطمئن شوید هیچکس به اطلاعات سایر مستاجران دسترسی ندارد.
  • می‌تواند روی کارایی کوئری‌ها تاثیر بگذارد چون تعداد رکورد‌ها زیاد است.
  • بروزرسانی و سفارشی کردن فقط برای یک مستاجر سخت است
 
منابع :
http://msdn.microsoft.com/en-us/library/aa479086.aspx
http://www.codeproject.com/Articles/51334/Multi-Tenants-Database-Architecture   
اشتراک‌ها
عرضه‌ی اولین نسخه RC برای SQL Server 2017
  • Linux support for tier-1, mission-critical workloads  SQL Server 2017 support for Linux includes the same high availability solutions on Linux as Windows Server, including Always On availability groups integrated with Linux native clustering solutions like Pacemaker.
  • Graph data processing in SQL Server  With the graph data features available in SQL Server 2017and Azure SQL Database, customers can create nodes and edges, and discover complex and many-to-many relationships.
  • Adaptive query processing  Adaptive query processing is a family of features in SQL Server 2017 that automatically keeps database queries running as efficiently as possible without requiring additional tuning from database administrators. In addition to the capability to adjust batch mode memory grants, the feature set includes batch mode adaptive joins and interleaved execution capabilities.
  • Python integration for advanced analytics  Microsoft Machine Learning Services now brings you the ability to run in-database analytics using Python or R in a parallelized and scalable way. The ability to run advanced analytics in your operational store without ETL means faster time to insights for customers while easy deployment and rich extensibility make it fast to get up and running on the right model. 
عرضه‌ی اولین نسخه RC برای SQL Server 2017
مطالب
استراتژی‌های کش کردن اطلاعات - قسمت 1
یکی از مواردی که می‌تواند بهبود سرعت یک نرم‌افزار را تضمین کند، caching می‌باشد. cache یکی از مواردی است که شاید در توسعه یک نرم افزار خیلی کمتر برای آن وقت میگذاریم و زیاد مورد توجه قرار نمی‌گیرد.  لازم به ذکر است که داشتن یک سیستم cache برای نرم افزارهای در مقایس بزرگ، نیازی ضروری به حساب می‌آید تا بتوان با سرعتی بهتر و قابل قبول‌تر (به نسبت سیستم بدون cache) به درخواست‌های کاربران جواب داد و یک حس خوب از نرم افزار را به کاربران منتقل کرد.
قبل از شروع به پیاده سازی یک سیستم caching، ابتدا نیاز است با روش‌های مختلف آن آشنا شویم و سپس اقدام به پیاده سازی و یا استفاده از یک سیستم cache کنیم. بدون شک انتخاب روشی مناسب، تاثیر چشم گیری را بر روی نتیجه‌ی خروجی خواهد داشت.
 
سوال: چرا باید از cache استفاده کنیم؟
پایین آوردن زمان پاسخ  (Response Time) به درخواست‌های ارسالی کاربران و پایین آوردن بار ترافیکی بر روی دیتابیس.
استراتژی‌های مختلفی که در ادامه در مورد آنها صحبت خواهیم کرد، وابستگی به نوع data و چگونگی دسترسی به آنها دارد؛ برای مثال اطلاعات چگونه ذخیره و خوانده می‌شوند که میتوان به چند مثال زیر اشاره کرد :
- آیا نرم افزار مورد نظر، اطلاعات زیادی را در دیتابیس ذخیره میکند و به نسبت آن، کمتر واکشی (read) اطلاعات را داریم؟ (مانند ثبت وقایع )
- آیا اطلاعات، یک بار نوشته خواهند شد و به کرّات واکشی می‌شوند؟ (مانند پرفایل کاربران یا اطلاعات یک کالا در یک فروشگاه اینترنتی)

Cache-Aside 


می‌توان این روش را یکی از متداول‌ترین و یا آشنا‌ترین روش‌های caching دانست و شاید حداقل یک بار، کارکردن با آن را تجربه کرده‌ایم.
در این رویکرد، برنامه به صورت مستقیم هم با دیتابیس اصلی کار میکند و هم cache.



نحوه‌ی کار به این صورت می‌باشد که:

1- برنامه ابتدا cache را بررسی می‌کند میکند و اگر اطلاعات مورد نظر در cache یافت شود، اطلاعات به کاربر برگشت داده می‌شوند.

2- اگر اطلاعات مورد نظر در cache یافت نشود، برنامه همان درخواست را به دیتابیس می‌فرستد و اطلاعات را به کاربر برمیگرداند؛ همچنین موظف است اطلاعات دریافتی از دیتابیس را در cache ذخیره کند تا در دفعات بعدی آن‌را از cache، واکشی کند.

مزایا و معایب
-  اگر cache به هر دلیلی از کار بیفتد، سیستم می‌تواند به کار خود ادامه دهد.
- اگر در نرم افزار شما درخواست‌های خواندن اطلاعات، بیشتر است و اطلاعات حالت استاتیک (به ندرت تغییر میکنند) را دارند، این مدل می‌تواند راه حل خوبی باشد. موارد پیشنهادی برای این حالت، Redis و Memcached هستند.
- یکی از معایبی که به این روش گرفته می‌شود، تا حدودی افزایش پیچیدگی کار برنامه می‌باشد؛ از این نظر که موظف است با دیتابیس و cache کار کند.

در این حالت بعد از به روزرسانی اطلاعات در دیتابیس، برای جلوگیری از ناسازگاری داده‌ها (inconsistent)  دو رویکرد برای همان اطلاعات در cache موجود است: 
1- برای رفع این مشکل از TTL  (Time to Live) استفاده می‌شود که بعد از مدت زمانی مشخص، اطلاعات در cache به صورت خودکار پاک خواهند شد. لازم به ذکر است باید در مقدار تعیین شده‌ی برای TTL، حداکثر دقت را انجام داد. تنظیم آن با مقدار کم می‌تواند باعث بالابردن درخواست‌های به دیتابیس شود.
2- بعد از به روزرسانی اطلاعات در دیتابیس، با استفاده از key مربوط به آن رکورد، اطلاعات موجود در cache، به حالت نامعتبر تبدیل شوند.
نمونه‌ای از کارکرد این روش می‌تواند شبیه به کد زیر باشد:
public  object GetMyEntity(int key)
{    
  // Try to get the entity from the cache.
  var value =  cache.StringGet(key);
  
  if (value == null) // Cache miss
  {
    // If there's a cache miss, get the entity from the original store and cache it.
    value = db.StringGet(key);

    // Avoid caching a null value.
    if (value != null)
    {
      // Put the item in the cache with a custom expiration time that 
       cache.StringSetAsync(key, JsonConvert.SerializeObject(value));
    }
  }
 return value;
}

Read-Through Cache 


در این حالت دیتابیس و cache به صورت پشت سر هم (in-line) قرار دارند و نحوه کار به این صورت است که همیشه درخواست‌ها در ابتدا به cache ارسال می‌شوند. تنها تفاوت این روش با روش قبل این است که برنامه‌ی ما همیشه با cache صحبت میکند.



مزایا و معایب
- یکی از مزایای این روش، کاهش پیچیدگی برنامه است؛ به این صورت که برنامه همیشه فقط با سیستم cache در ارتباط است.
- یکی از معایب این روش، اولین درخواست است. همیشه برای اولین درخواست‌ها چون اطلاعاتی در cache موجود نیست، باعث یک افزایش زمان پاسخ خواهد شد. برای رفع این مشکل از اصطلاحی تحت عنوان گرم کردن (warming) استفاده می‌شود. در اینجا برنامه نویس به صورت دستی درخواست‌هایی و یا کوئری‌هایی را اجرا خواهد کرد، صرفا به این دلیل که اطلاعات در cache قرار گیرند.

Write-Through Cache 

در این حالت اطلاعات ابتدا در cache ذخیره خواهند شد و بعد از آن در دیتابیس قرار خواهند گرفت. همچنین همانند روش Read-Through، برنامه همیشه با cache صحبت میکند.


این روش همه‌ی مزایای روش Read-Through را دارد به علاوه رفع معایب آن از جمله:
- ناسازگاری داده‌ها نمی‌توانند اتفاق بیفتند؛ زیرا اطلاعات همیشه ابتدا در cache نوشته خواهند شد و بعد در دیتابیس؛ به همین خاطر اطلاعات در هر دو نسخه یکسان هستند.
- بعد از درج اطلاعات جدید، نیازی به warming نیست. به این دلیل که در ابتدا در cache ذخیره خواهند شد.