Let's Go Further راه‌اندازی مدل کاربر و ثبت‌نام › راه‌اندازی جدول پایگاه داده کاربران
قبلی · فهرست مطالب · بعدی
فصل ۱۲.۱.

راه‌اندازی جدول پایگاه داده کاربران

بیایید با ایجاد یک جدول users جدید در پایگاه داده خود شروع کنیم. اگر دنبال می‌کنید، از ابزار migrate برای ایجاد یک جفت فایل migration SQL جدید استفاده کنید:

$ migrate create -seq -ext=.sql -dir=./migrations create_users_table
/home/alex/Projects/greenlight/migrations/000004_create_users_table.up.sql
/home/alex/Projects/greenlight/migrations/000004_create_users_table.down.sql

و سپس دستورات SQL زیر را به ترتیب به فایل‌های 'up' و 'down' اضافه کنید:

فایل: migrations/000004_create_users_table.up.sql
CREATE TABLE IF NOT EXISTS users (
    id bigserial PRIMARY KEY,
    created_at timestamp(0) with time zone NOT NULL DEFAULT NOW(),
    name text NOT NULL,
    email citext UNIQUE NOT NULL,
    password_hash bytea NOT NULL,
    activated bool NOT NULL,
    version integer NOT NULL DEFAULT 1
);
فایل: migrations/000004_create_users_table.down.sql
DROP TABLE IF EXISTS users;

چند نکته جالب درباره این دستور CREATE TABLE وجود دارد که می‌خواهم به سرعت توضیح دهم:

  1. ستون email دارای نوع citext (متن حساس به حالت نیست) است. این نوع داده‌های متنی را دقیقاً همانطور که وارد شده ذخیره می‌کند — بدون تغییر حالت به هیچ وجه — اما مقایسه‌ها با داده همیشه حساس به حالت نیستند… از جمله جستجوها در ایندکس‌های مرتبط.

  2. ما همچنین یک محدودیت UNIQUE روی ستون email داریم. ترکیب با نوع citext به این معنی است که هیچ دو ردیفی در پایگاه داده نمی‌توانند مقدار ایمیل یکسانی داشته باشند — حتی اگر حالت‌های متفاوتی داشته باشند. این در اصل یک قانون کسب‌وکار در سطح پایگاه داده را اجرا می‌کند که هیچ دو کاربری نباید با آدرس ایمیل یکسان وجود داشته باشند.

  3. ستون password_hash دارای نوع bytea (رشته باینری) است. در این ستون ما یک هش یک‌طرفه از رمز عبور کاربر را که با bcrypt تولید شده ذخیره خواهیم کرد — نه خود رمز عبور را به صورت متن ساده.

  4. ستون activated یک مقدار بولین را ذخیره می‌کند تا نشان دهد آیا حساب کاربری 'فعال' است یا نه. ما این مقدار را به صورت پیش‌فرض false هنگام ایجاد کاربر جدید تنظیم می‌کنیم و از کاربر می‌خواهیم آدرس ایمیل خود را قبل از تنظیم به true تأیید کند.

  5. ما همچنین یک ستون شماره version اضافه کرده‌ایم که هر بار یک رکورد کاربر به‌روزرسانی می‌شود آن را افزایش می‌دهیم. این به ما امکان می‌دهد از قفل‌گذاری خوش‌بینانه برای جلوگیری از شرایط مسابقه هنگام به‌روزرسانی رکوردهای کاربر استفاده کنیم، به همان روشی که قبلاً با فیلم‌ها در این کتاب انجام دادیم.

خوب، بیایید migration 'up' را اجرا کنیم:

$ migrate -path=./migrations -database=$GREENLIGHT_DB_DSN up
4/u create_users_table (62.43511ms)

و سپس باید بتوانید به پایگاه داده خود متصل شوید و بررسی کنید که جدول users جدید مطابق انتظار ایجاد شده است:

$ psql $GREENLIGHT_DB_DSN 
psql (15.4 (Ubuntu 15.4-1.pgdg22.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

greenlight=> \d users
                                          Table "public.users"
    Column     |            Type             | Collation | Nullable |              Default              
---------------+-----------------------------+-----------+----------+-----------------------------------
 id            | bigint                      |           | not null | nextval('users_id_seq'::regclass)
 created_at    | timestamp(0) with time zone |           | not null | now()
 name          | text                        |           | not null | 
 email         | citext                      |           | not null | 
 password_hash | bytea                       |           | not null | 
 activated     | boolean                     |           | not null | 
 version       | integer                     |           | not null | 1
Indexes:
    "users_pkey" PRIMARY KEY, btree (id)
    "users_email_key" UNIQUE CONSTRAINT, btree (email)

یک نکته مهم برای اشاره در اینجا: محدودیت UNIQUE روی ستون email ما به صورت خودکار نام users_email_key را دریافت کرده است. این در فصل بعدی مهم خواهد شد، زمانی که نیاز داریم هرگونه خطا ناشی از ثبت‌نام مجدد کاربر با آدرس ایمیل یکسان را مدیریت کنیم.