آموزش برنامه نویسی

انواع داده‌های پرکاربرد در PostgreSQL

در PostgreSQL، انواع داده‌های پرکاربرد شامل **اعداد** (مثل `int`، `decimal` برای پول)، **رشته‌ها** (مثل `varchar`، `text`)، **تاریخ و زمان** (با توصیه استفاده از `timestamptz` به جای `timestamp`)، و **انواع خاص** (مثل `jsonb` برای داده‌های…

9 دقیقه مطالعه ۲۶ اسفند ۱۴۰۴ 52 بازدید مرتضی رستمیان
تصویر مقاله انواع داده‌های پرکاربرد در PostgreSQL
PostgreSQL و طراحی دیتابیس

انواع داده در PostgreSQL؛ برای هر ستون چه Data Type انتخاب کنیم؟

وقتی یک جدول در PostgreSQL می‌سازیم، یکی از اولین تصمیم‌ها این است که هر ستون چه نوع داده‌ای داشته باشد. در نگاه اول انتخاب بین integer، text یا timestamp ساده به نظر می‌رسد، اما همین انتخاب روی دقت داده و نحوه کار با دیتابیس اثر می‌گذارد.

قرار نیست تمام Data Typeهای PostgreSQL را حفظ کنید. چیزی که واقعاً لازم است بدانید این است که هر نوع داده برای چه موقعیتی ساخته شده و چه زمانی انتخاب دیگری منطقی‌تر است. در ادامه پرکاربردترین گزینه‌ها را با مثال‌های ساده بررسی می‌کنیم.

نماد سرور پایگاه داده و Database Server
Wikimedia Commons — CC0

چرا انتخاب نوع داده مهم‌تر از چیزی است که به نظر می‌رسد؟

فرض کنید برای قیمت محصول از یک عدد اعشاری تقریبی استفاده کنیم. ممکن است در محاسبات مالی با خطاهای کوچکی روبه‌رو شویم که اصلاً دوست نداریم در مبلغ نهایی سفارش دیده شوند. برای چنین داده‌ای، numeric انتخاب منطقی‌تری است.

همین موضوع برای تاریخ، شناسه، متن و حتی مقدارهای درست و غلط هم وجود دارد. نوع داده درست باعث می‌شود خود دیتابیس بخشی از قوانین داده را برای ما کنترل کند و بعداً مجبور نشویم همه چیز را در کد برنامه بررسی کنیم.

01 — Numeric Types

انواع عددی؛ از تعداد ساده تا مبلغ مالی

PostgreSQL چند نوع عددی مختلف دارد و لازم نیست همیشه بزرگ‌ترین نوع را انتخاب کنیم. بهتر است محدوده عدد و میزان دقتی که واقعاً نیاز داریم مشخص باشد.

نوع کاربرد معمول نکته
smallint عدد صحیح کوچک ۲ بایت و محدوده حدود ۳۲ هزار مثبت و منفی
integer شمارنده‌ها و اعداد معمولی یکی از رایج‌ترین انتخاب‌ها برای اعداد صحیح
bigint مقادیر صحیح بسیار بزرگ ۸ بایت و مناسب داده‌هایی که ممکن است خیلی رشد کنند
numeric / decimal قیمت و محاسبات دقیق عدد اعشاری دقیق؛ مناسب محاسبات مالی
real اعداد تقریبی حدود ۶ رقم دقت اعشاری
double precision محاسبات تقریبی دقیق‌تر حدود ۱۵ رقم دقت
یک مثال ساده:

اگر قرار است قیمت محصول ذخیره شود، چیزی مثل numeric(12,2) معمولاً از real انتخاب مطمئن‌تری است؛ چون در پول، دقت عدد اهمیت دارد.

02 — Character Types

برای متن از text استفاده کنیم یا varchar؟

یکی از سؤال‌های همیشگی هنگام طراحی جدول این است که برای نام، توضیحات یا عنوان باید text استفاده کنیم یا varchar.

char(n)

طول ثابت دارد و اگر متن کوتاه‌تر باشد با Space پر می‌شود. در پروژه‌های معمول وب کمتر به آن نیاز پیدا می‌کنیم.

varchar(n)

متن با حداکثر طول مشخص. مثلاً varchar(100) اجازه نمی‌دهد بیشتر از ۱۰۰ کاراکتر وارد شود.

text

برای متن‌هایی که نمی‌خواهیم محدودیت طول مشخصی برایشان تعریف کنیم. در PostgreSQL استفاده از text کاملاً رایج است.

نکته مهم این است که در PostgreSQL معمولاً text و varchar تفاوت عملکرد قابل توجهی ندارند. بنابراین اگر محدودیت طول واقعاً بخشی از قانون داده نیست، استفاده از text می‌تواند ساده‌تر باشد.

03 — Boolean

Boolean؛ وقتی جواب فقط بله یا خیر است

برای وضعیت‌هایی مثل فعال بودن حساب، تأیید شدن ایمیل یا منتشر شدن یک مقاله، نوع boolean انتخاب طبیعی است.

مقدار اصلی Boolean یا true است یا false. اگر ستون اجازه NULL داشته باشد، ممکن است مقدار آن نامشخص هم باشد. یعنی NULL خودش مقدار Boolean نیست؛ بلکه نشان می‌دهد فعلاً مقداری ثبت نشده است.

04 — Date & Time

تاریخ و زمان؛ timestamp و timestamptz را اشتباه نگیریم

بخش تاریخ و زمان یکی از جاهایی است که انتخاب نوع نامناسب بعداً دردسر درست می‌کند؛ مخصوصاً وقتی برنامه قرار است توسط کاربران چند منطقه زمانی استفاده شود.

date — فقط تاریخ، بدون ساعت.

time — فقط ساعت، بدون اطلاعات منطقه زمانی.

timestamp — تاریخ و ساعت بدون منطقه زمانی.

timestamptz — مناسب زمانی که یک لحظه واقعی در زمان اهمیت دارد؛ مثل زمان ثبت سفارش یا ایجاد حساب.

interval — برای مدت زمان؛ مثلاً ۳ روز یا ۲ ساعت.

timetz — زمان همراه با Offset زمانی؛ در بسیاری از پروژه‌های معمول کمتر استفاده می‌شود.

مثال عملی:

برای created_at یا updated_at در بسیاری از سیستم‌ها timestamptz انتخاب مناسب‌تری است.

نمونه خروجی Query در پایگاه داده SQL
Wikimedia Commons — CC0
05 — Binary

داده باینری با bytea

PostgreSQL برای ذخیره داده‌های باینری نوع bytea را در اختیار ما قرار می‌دهد. می‌توان از آن برای داده‌هایی استفاده کرد که به شکل متن معمولی نیستند.

البته اینکه فایل‌های بزرگ را مستقیم داخل دیتابیس نگه داریم یا در Object Storage و فقط آدرسشان را ذخیره کنیم، تصمیم معماری جداگانه‌ای است و به نوع پروژه بستگی دارد.

06 — Special Types

UUID، JSONB و Array؛ قابلیت‌هایی که PostgreSQL را جذاب‌تر می‌کنند

PostgreSQL فقط به عدد و متن محدود نیست. چند نوع داده کاربردی دیگر هم دارد که در پروژه‌های امروزی زیاد با آن‌ها روبه‌رو می‌شویم.

uuid

برای ذخیره شناسه‌های UUID؛ مخصوصاً زمانی که نمی‌خواهیم شناسه‌ها فقط اعداد پشت‌سرهم باشند.

json

داده JSON را تقریباً با همان شکل متنی ورودی نگه می‌دارد.

jsonb

JSON را در قالبی پردازش‌شده ذخیره می‌کند و برای جست‌وجو و Index کردن معمولاً انتخاب کاربردی‌تری است.

array

PostgreSQL اجازه می‌دهد یک ستون آرایه‌ای از نوع مشخص داشته باشیم؛ مثلاً آرایه‌ای از integer یا text. البته Array نباید جای طراحی درست Relationshipها را بگیرد.

نمونه نمودار ERD و طراحی ساختار دیتابیس SQL
Wikimedia Commons — CC0

JSON یا JSONB؟ معمولاً کدام را انتخاب کنیم؟

اگر قرار است فقط متن JSON را همان‌طور که وارد شده نگه دارید، json می‌تواند کافی باشد. اما در بیشتر برنامه‌هایی که قرار است داخل داده جست‌وجو کنیم، شرط بنویسیم یا Index بسازیم، jsonb کاربرد بیشتری دارد.

به همین دلیل نمی‌شود گفت jsonb همیشه و بدون استثنا بهتر است؛ انتخاب درست به این بستگی دارد که با داده بعداً چه کاری انجام می‌دهیم.

یک نمونه واقعی

برای جدول محصول چه Typeهایی ممکن است انتخاب کنیم؟

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

CREATE TABLE products (
    id uuid PRIMARY KEY,
    title text NOT NULL,
    price numeric(12,2) NOT NULL,
    stock integer NOT NULL,
    is_active boolean NOT NULL DEFAULT true,
    metadata jsonb,
    created_at timestamptz NOT NULL DEFAULT now()
);

اینجا هر Type دلیل مشخصی دارد: عنوان متن است، قیمت باید دقیق باشد، موجودی عدد صحیح است، وضعیت فعال بودن Boolean است و زمان ایجاد رکورد هم با timestamptz ثبت می‌شود.

اگر بخواهیم خیلی سریع انتخاب کنیم

نام و عنوان

text

تعداد و شمارنده

integer

قیمت

numeric

فعال / غیرفعال

boolean

زمان ثبت رویداد

timestamptz

داده منعطف JSON

jsonb

چند اشتباه رایج در انتخاب Data Type

ذخیره همه چیز به صورت text: ساده به نظر می‌رسد، اما دیتابیس دیگر نمی‌تواند نوع داده را درست کنترل کند.

استفاده از float برای قیمت: برای مقدار مالی، عدد دقیق مثل numeric انتخاب مناسب‌تری است.

استفاده از timestamp بدون توجه به منطقه زمانی: اگر زمان یک رویداد واقعی مهم است، معمولاً timestamptz ارزش بررسی بیشتری دارد.

ریختن همه اطلاعات داخل jsonb: JSONB بسیار کاربردی است، اما قرار نیست جای ستون‌ها و Relationshipهای مشخص را بگیرد.

سوالات متداول درباره Data Typeهای PostgreSQL

text بهتر است یا varchar؟

اگر محدودیت طول بخشی از قانون داده نیست، استفاده از text در PostgreSQL کاملاً طبیعی است. varchar(n) زمانی مفید است که واقعاً بخواهید حداکثر طول مشخصی اعمال شود.

برای قیمت از چه نوع داده‌ای استفاده کنیم؟

برای مقادیر مالی معمولاً numeric یا decimal انتخاب مناسبی است؛ چون مقدار را به‌صورت دقیق ذخیره می‌کند.

timestamp بهتر است یا timestamptz؟

برای زمان وقوع یک رویداد واقعی مثل زمان ثبت سفارش، معمولاً timestamptz انتخاب مناسبی است. timestamp بیشتر زمانی کاربرد دارد که زمان محلی بدون وابستگی به منطقه زمانی مدنظر باشد.

json بهتر است یا jsonb؟

در بسیاری از پروژه‌های کاربردی jsonb به دلیل قابلیت جست‌وجو و Index کردن بیشتر استفاده می‌شود، اما اگر شکل متنی اصلی JSON اهمیت داشته باشد، json هم کاربرد خودش را دارد.

جمع‌بندی

نوع داده را بر اساس معنی داده انتخاب کنید، نه فقط اندازه آن

انتخاب Data Type مناسب در PostgreSQL بیشتر از یک تصمیم ظاهری است. نوع داده مشخص می‌کند دیتابیس چه چیزی را معتبر بداند، داده چطور ذخیره شود و بعداً چه نوع Queryهایی بتوانیم روی آن بنویسیم.

برای متن معمولاً text، برای عدد صحیح integer، برای پول numeric، برای وضعیت boolean و برای زمان بسیاری از رویدادها timestamptz انتخاب‌های رایجی هستند.

مهم‌تر از حفظ کردن این فهرست این است که قبل از ساخت هر ستون از خودتان بپرسید: «این داده دقیقاً چه معنایی دارد و بعداً قرار است با آن چه کاری انجام بدهم؟» معمولاً جواب همین سؤال، Type مناسب را مشخص می‌کند.