1. معرفی اطلس

atlas

اطلس یک ابزار بغیر از زبان است که بطور خاص برای مدیریت و مهاجرت اسکیمای پایگاه داده با استفاده از اصول DevOps مدرن طراحی شده است. این دو گزینه گری را ارائه می دهد:

  • تصریحی: مانند Terraform، اطلس وضعیت فعلی پایگاه داده را با وضعیت مطلوبی که با استفاده از HCL، SQL یا اسکیمای ORM تعریف شده است، مقایسه می کند. بر اساس این مقایسه، یک برنامه مهاجرت تولید می کند و اجرا می کند تا پایگاه داده را به وضعیت مطلوب خود منتقل کند.
  • نسخه بندی شده: برخلاف دیگر ابزارها، اطلس به صورت خودکار برای شما برنامه ریزی مهاجرت اسکیما را انجام می دهد. کاربران می توانند اسکیمای مطلوب پایگاه داده خود را با استفاده از HCL، SQL یا ORM انتخابی خودشان توصیف کنند و با اطلس، مهاجرت های لازم را برنامه ریزی، بررسی و اعمال کنند.

یکی از مزایای اصلی اطلس، ساده سازی پیچیدگی مدیریت پایگاه داده است که آن را برای کنترل نسخه، همکاری و پیاده سازی آسان می کند.

2. نصب اطلس

قبل از استفاده از اطلس برای مدیریت نسخه های پایگاه داده، باید آن را نصب کنیم. گام های نصب برای پلتفرم های مختلف به شرح زیر است.

2.1 نصب برای macOS + Linux

در سیستم های macOS یا Linux، می توانید آخرین نسخه اطلس را با استفاده از دستور خط فرمان زیر دانلود و نصب کنید:

curl -sSf https://atlasgo.sh | sh

این دستور به طور خودکار ورژن سیستم عامل را تشخیص می دهد، نسخه مناسب را دانلود می کند و فایل دودویی اطلس را در مسیر اجرایی قرار می دهد.

2.2 نصب از طریق Homebrew

اگر از macOS استفاده می کنید و پیش از این مدیر بسته Homebrew را نصب کرده باشید، نصب اطلس به سادگی انجام می شود. تنها کافی است دستور زیر را اجرا کنید:

brew install ariga/tap/atlas

این دستور آخرین نسخه اطلس را از مخزن Homebrew دریافت و نصب می کند.

2.3 نصب از طریق Docker

نصب و اجرای اطلس از طریق Docker یک روش سریع و مناسب است، به ویژه برای تست موقت یا کاربرانی که ترجیح می دهند نرم افزار اضافی را در سیستم میزبان خود نصب نکنند.

ابتدا، تصویر Docker اطلس را کش کنید:

docker pull arigaio/atlas

سپس، می توانید یک دستور راهنما اجرا کنید تا نصب موفقیت آمیز را تایید کنید:

docker run --rm arigaio/atlas --help

اگر کانتینر نیاز به دسترسی به شبکه میزبان یا دایرکتوری های محلی دارد، از پرچم --net=host استفاده کنید و دایرکتوری های مورد نیاز را mount کنید:

docker run --rm --net=host \
  -v $(pwd)/migrations:/migrations \
  arigaio/atlas migrate apply \
  --url "mysql://root:pass@:3306/test"

2.4 نصب برای ویندوز

فایل باینری را دانلود کرده و به مسیر نصبی متغیر محیط PATH سیستم اضافه کنید: https://release.ariga.io/atlas/atlas-windows-amd64-latest.exe

3. صدور ساختار جدول پایگاه داده موجود با استفاده از اطلاس

اطلاس دستور atlas schema inspect را فراهم می‌کند که برای صدور ساختار یک پایگاه داده موجود استفاده می‌شود. این دستور از خواندن توضیحات پایگاه داده از آدرس URL پایگاه داده پشتیبانی می‌کند و این توضیحات را به سه فرمت مختلف خروجی می‌دهد: فرمت پیش‌فرض Atlas HCL، فرمت SQL و فرمت JSON. در این راهنما، نحوه استفاده از فرمت‌های HCL و SQL از Atlas را نشان خواهیم داد، زیرا فرمت JSON معمولاً برای پردازش خروجی با jq استفاده می‌شود.

برای بازرسی یک نمونه MySQL موجود و نوشتن خروجی در یک فایل به نام schema.hcl، از دستور زیر استفاده نمایید:

atlas schema inspect -u "mysql://root:pass@localhost:3306/example" > schema.hcl

فایل schema.hcl را باز کنید تا تعریف ساختار جدول Atlas که توضیح پایگاه‌داده را توصیف می‌کند را مشاهده نمایید (HCL یک فرمت پیکربندی وابسته به پایگاه داده است که توسط Atlas تعریف شده است). به عنوان مثال، این فایل شامل محتوای زیر خواهد بود:

table "users" {
  schema = schema.example
  column "id" {
    null = false
    type = int
  }
  column "name" {
    null = true
    type = varchar(100)
  }
  primary_key {
    columns = [column.id]
  }
}

این بلوک کد یک ساختار جدول با ستون‌های id و name را نمایش می‌دهد. فیلد schema به تعریف مدل example ارجاع می‌کند که در جای دیگری در این سند تعریف شده است. علاوه بر این، زیربلوک primary_key ستون id را به عنوان کلید اصلی برای جدول مشخص می‌کند. Atlas کوشش می‌کند تا به دستور زبان پایگاه داده‌ای که در حال عملکرد است نزدیک شود. در این مثال، ستون id دارای نوع int است، در حالی که ستون name دارای نوع varchar(100) است.

به همین ترتیب، برای صدور تعریف مدل SQL پایگاه داده، می‌توانید از دستور زیر استفاده کنید:

atlas schema inspect -u "mysql://root:pass@localhost:3306/example" --format '{{ sql . }}' > schema.sql

فایل schema.sql را باز کنید تا توضیح SQL پایگاه داده را مشاهده نمایید که معمولاً شامل برخی اظهاریه‌های CREATE TABLE است.

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

4.1 گردش کار اعلامی

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

در زیر نحوه استفاده از گردش کار اعلامی برای تعریف و دستیابی به وضعیت موردنظر پایگاه داده آمده است:

4.1.1 تعریف ساختار جدول مقصد

ابتدا، شما باید یک فایل بسازید که ساختار موردنظر پایگاه داده را تعریف می‌کند که می‌تواند به‌صورت HCL، SQL یا ORM (Object-Relational Mapping) باشد.

به‌عنوان مثال برای فرمت HCL، یک جدول جدید به نام blog_posts را تعریف نمایید:

table "blog_posts" {
  schema = schema.example
  column "id" {
    null = false
    type = int
  }
  column "title" {
    null = true
    type = varchar(100)
  }
  column "body" {
    null = true
    type = text
  }
  column "author_id" {
    null = true
    type = int
  }
  primary_key {
    columns = [column.id]
  }
  foreign_key "author_fk" {
    columns     = [column.author_id]
    ref_columns = [table.users.column.id]
  }
}

نکته: فرمت نحوه‌ی اینجا خوانی HCL در بخش‌های بعدی مورد بررسی قرار خواهد گرفت.

4.1.2 انجام مهاجرت با استفاده از ابزار اطلاس

هنگامی که تعریف ساختار جدول پایگاه داده تکمیل شد، می‌توانید از دستور schema apply اطلاس برای انجام مهاجرت استفاده کنید.

atlas schema apply \
  -u "mysql://root:pass@localhost:3306/example" \
  --to file://schema.hcl

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

4.2 گردش کار نسخه‌بندی شده

گردش کار نسخه‌بندی شده یک حالت دیگر پشتیبانی‌شده توسط اطلاس است، گاهی به آن به عنوان "مهاجرت براساس تغییر" اشاره می‌شود. این حالت برای سناریوهایی که نیاز به کنترل نسخه تغییرات ساختار پایگاه داده و بررسی آن در فرآیند بررسی کد است مناسب است.

مراحل گردش کار نسخه‌بندی شده شامل:

4.2.1 محاسبه اختلاف‌ها

قبل از شروع مهاجرت، ضروری است که ساختار پایگاه داده فعلی را با وضعیت مطلوب مقایسه کرده و اختلاف‌ها بین دو حالت را تعیین کنیم. این کار با اجرای دستور atlas migrate diff قابل انجام است.

atlas migrate diff create_blog_posts \
  --dir "file://migrations" \
  --to "file://schema.hcl" \
  --dev-url "docker://mysql/8/example"

پارامتر --dir آدرس URL پوشه مهاجرت را مشخص می‌کند که به صورت پیش‌فرض به file://migrations تنظیم شده است. پارامتر --to نشانی URL وضعیت مطلوب (به عنوان مثال، پایگاه داده محیط توسعه شما) و --dev-url یک URL برای پایگاه داده توسعه استفاده شده برای محاسبه اختلاف‌ها را فراهم می‌کند (توجه داشته باشید که --dev-url باید به یک پایگاه داده خالی اشاره کند که Atlas برای محاسبه اختلاف‌ها استفاده می‌کند).

نکته: اگر می‌خواهید فایل‌های SQL تولید کنید، به بخش قبلی برای تنظیم فرمت آن با استفاده از پارامتر --format مراجعه کنید.

4.2.2 اعمال تغییرات مهاجرت

پس از اتمام محاسبه اختلاف، Atlas دو فایل مهاجرت تولید شده را در پوشه migrations ذخیره می‌کند. به عنوان مثال، اگر فرمت انتخاب شده SQL باشد، فایل‌های تولید شده توسط دستور diff شامل دستورات مهاجرت برای ایجاد یک جدول جدید می‌شوند:

-- ایجاد جدول "blog_posts"
CREATE TABLE `blog_posts` (
  `id` int NOT NULL,
  `title` varchar(100) DEFAULT NULL,
  `body` text DEFAULT NULL,
  `author_id` int NULL REFERENCES `users`(id),
  PRIMARY KEY (`id`)
);

هنگامی که فایل‌های مهاجرت تولید شوند، می‌توانید از ابزارهای کنترل نسخه (به عنوان مثال، Git) استفاده کنید تا این تغییرات را مدیریت کنید. این رویکرد امکان انجام تغییرات فراوانی را در ساختار جداول پایگاه داده در محیط توسعه فراهم می‌کند و هنگامی که زمان انتشار فرا رسد، با استفاده از دستورات Atlas جداول محیط توسعه و محیط UAT را مقایسه کرده و فایل‌های مهاجرت ساختار جدول پایگاه داده تولید شده را تولید کند. این فایل‌های مهاجرت سپس به محیط UAT و تولیدی اعمال می‌شوند تا پایگاه داده به‌روزرسانی شود.

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

5. توضیح فرمت HCL

5.1 معرفی

HCL یک زبان اعلانی است که برای توصیف تعاریف ساختار جدول پایگاه داده استفاده می‌شود. Atlas از فرمت HCL برای نوشتن طرح‌های پایگاه داده استفاده می‌کند که یک ساختار غنی برای توصیف جنبه‌های مختلف پایگاه داده فراهم می‌کند. مزیت HCL در قابلیت خوانایی، آسانی نگهداری و پشتیبانی از ویژگی‌هایی مانند تزریق متغیر و حاشیه‌نویسی‌های اضافی می‌باشد.

نکته: اگر پروژه شما نیاز دارد که با چندین پایگاه داده سازگار باشد، توصیف ساختارهای جدول در یک روش غیر وابسته به پایگاه داده با استفاده از HCL می‌تواند بسیار ملایم باشد.

5.2 شی schema

شی schema برای توصیف طرح پایگاه داده استفاده می‌شود. در MySQL و SQLite، این شی نمایانگر DATABASE است در حالی که در PostgreSQL، نمایانگر SCHEMA می‌باشد. یک فایل HCL می‌تواند شامل یک یا چند شی schema باشد.

schema "public" {
  comment = "یک توضیحات اسکیما"
}

schema "private" {}

5.3 شی table

شی table برای توصیف یک جدول در یک پایگاه داده SQL استفاده می‌شود که شامل ستون‌ها، شاخص‌ها، محدودیت‌ها و مختلف ویژگی‌های اضافی پشتیبانی شده توسط رانندگان مختلف پایگاه داده می‌باشد.

table "users" {
  schema = schema.public
  column "id" {
    type = int
  }
  column "name" {
    type = varchar(255)
  }
  column "manager_id" {
    type = int
  }
  primary_key {
    columns = [
      column.id
    ]
  }
  index "idx_name" {
    columns = [
      column.name
    ]
    unique = true
  }
  foreign_key "manager_fk" {
    columns     = [column.manager_id]
    ref_columns = [table.users.column.id]
    on_delete   = CASCADE
    on_update   = NO_ACTION
  }
}

5.4 شی column

شی column یک زیر-منبع از table استفاده می‌شود برای تعریف ستون‌ها در جدول است.

column "name" {
  type = text
  null = false
}

column "age" {
  type = integer
  default = 42
}

column "active" {
  type = tinyint(1)
  default = true
}

5.5 اشیاء primary_key

primary_key یک زیر-منبع از table است که کلید اصلی جدول را تعریف می‌کند.

primary_key {
  columns = [column.id]
}

5.6 اشیاء foreign_key

foreign_key یک زیر-منبع از table است که ستون‌های ارجاع دهنده به ستون‌های دیگر در جداول دیگر را تعریف می‌کند.

table "سفارشات" {
  schema = schema.market
  // ...
  column "owner_id" {
    type = integer
  }
  foreign_key "owner_id" {
    columns     = [column.owner_id]
    ref_columns = [table.users.column.id]
    on_update   = NO_ACTION
    on_delete   = NO_ACTION
  }
}

5.7 اشیاء index

اشیاء index یک شاخص روی جدول را نمایندگی می‌کند.

index "idx_name" {
  columns = [
    column.name
  ]
  unique = true
}