شرح PostgreSQL للمبتدئين: أقوى قاعدة بيانات مفتوحة المصدر
قواعد البيانات

شرح PostgreSQL للمبتدئين: أقوى قاعدة بيانات مفتوحة المصدر

PostgreSQL أكثر قواعد البيانات العلائقية تقدّماً. تعلّم الأساسيات: الجداول، الاستعلامات، الفهارس، والعلاقات.

م
مؤسس LahbabiGuide
5 دقائق قراءة
شارك:

لماذا PostgreSQL؟

PostgreSQL (أو Postgres اختصاراً) قاعدة بيانات علائقية مفتوحة المصدر مع مجتمع ضخم ومستقبل ممتاز. تستخدمها شركات كـ Apple, Instagram, Spotify, Reddit.

مقارنةً بـ MySQL:

  • أقوى في SQL القياسي
  • أفضل للبيانات المعقّدة (JSON, arrays, geometric types)
  • Extensions قوية (PostGIS للخرائط، pgvector للـ AI)

التثبيت

Windows

حمّل من postgresql.org/download. أثناء التثبيت:

  • اختر كلمة سر قوية لـ postgres
  • اترك المنفذ الافتراضي 5432

Mac

bash
brew install postgresql@16
brew services start postgresql@16

Linux (Ubuntu/Debian)

bash
sudo apt install postgresql
sudo systemctl start postgresql

أول اتصال

bash
psql -U postgres -h localhost

سترى:

postgres=#
إعلان

إنشاء قاعدة ومستخدم

sql
-- أنشئ قاعدة
CREATE DATABASE mystore;

-- أنشئ مستخدماً
CREATE USER app_user WITH PASSWORD 'secret123';

-- امنحه صلاحيات
GRANT ALL PRIVILEGES ON DATABASE mystore TO app_user;

-- انتقل للقاعدة
\c mystore

الجداول: أساس كل شيء

sql
CREATE TABLE products (
  id SERIAL PRIMARY KEY,
  name VARCHAR(200) NOT NULL,
  price DECIMAL(10, 2) NOT NULL,
  stock INTEGER DEFAULT 0,
  description TEXT,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

أنواع البيانات الأساسية

| النوع | للاستخدام | |------|----------| | SERIAL | ID تلقائي الزيادة | | VARCHAR(n) | نص بطول محدّد | | TEXT | نص بدون حدّ | | INTEGER | أرقام صحيحة | | DECIMAL(n,m) | أرقام عشرية دقيقة (للأموال) | | BOOLEAN | true/false | | TIMESTAMPTZ | تاريخ + وقت + منطقة زمنية | | JSONB | JSON مُفهرَس | | TEXT[] | مصفوفة نصوص |

CRUD: العمليات الأساسية

Insert (إضافة)

sql
INSERT INTO products (name, price, stock)
VALUES ('لابتوب', 5999.99, 10);

-- عدّة سجلات دفعة واحدة
INSERT INTO products (name, price) VALUES
  ('ماوس', 99),
  ('لوحة مفاتيح', 249),
  ('شاشة', 1299);

-- مع إرجاع الـ id
INSERT INTO products (name, price)
VALUES ('سمّاعة', 199)
RETURNING id, name;

Select (استعلام)

sql
-- الكل
SELECT * FROM products;

-- أعمدة محدّدة
SELECT name, price FROM products;

-- شرط
SELECT * FROM products WHERE price > 500;

-- عدّة شروط
SELECT * FROM products
WHERE price BETWEEN 100 AND 1000
AND stock > 0;

-- ترتيب
SELECT * FROM products
ORDER BY price DESC
LIMIT 5;

-- بحث نصّي
SELECT * FROM products
WHERE name ILIKE '%لابتوب%';

Update (تحديث)

sql
UPDATE products
SET price = 4999
WHERE id = 1;

-- تحديث عدّة صفوف
UPDATE products
SET stock = stock - 1
WHERE id IN (1, 3, 5);

⚠️ احذر: UPDATE products SET price = 0 بدون WHERE يُحدّث كل الجدول.

Delete (حذف)

sql
DELETE FROM products WHERE stock = 0;

-- مسح الجدول كاملاً
TRUNCATE products;

العلاقات (JOINs)

جدولان مرتبطان

sql
CREATE TABLE categories (
  id SERIAL PRIMARY KEY,
  name VARCHAR(100) NOT NULL
);

ALTER TABLE products
ADD COLUMN category_id INTEGER REFERENCES categories(id);

INNER JOIN — العلاقة المشتركة

sql
SELECT p.name, p.price, c.name AS category
FROM products p
INNER JOIN categories c ON p.category_id = c.id;

LEFT JOIN — كل السجلات من الجدول الأيسر

sql
-- حتى المنتجات بدون فئة
SELECT p.name, c.name AS category
FROM products p
LEFT JOIN categories c ON p.category_id = c.id;

التجميع (GROUP BY)

sql
-- عدد المنتجات في كل فئة
SELECT c.name, COUNT(p.id) AS product_count
FROM categories c
LEFT JOIN products p ON p.category_id = c.id
GROUP BY c.id, c.name
ORDER BY product_count DESC;

-- إحصاءات
SELECT
  category_id,
  COUNT(*) AS count,
  AVG(price) AS avg_price,
  SUM(stock) AS total_stock,
  MIN(price) AS cheapest,
  MAX(price) AS most_expensive
FROM products
GROUP BY category_id;

الفهارس (Indexes) — للسرعة

الفهرس يُسرّع الاستعلامات على الأعمدة المفهرسة بآلاف المرّات.

sql
-- فهرس على عمود واحد
CREATE INDEX idx_products_name ON products(name);

-- فهرس مركّب
CREATE INDEX idx_products_cat_price ON products(category_id, price);

-- فهرس للبحث النصّي (أسرع بكثير من LIKE)
CREATE INDEX idx_products_name_trgm
ON products USING gin(name gin_trgm_ops);

-- فهرس فريد
CREATE UNIQUE INDEX idx_users_email ON users(email);

متى تفهرس: على الأعمدة التي تظهر في WHERE, ORDER BY, JOIN.

متى لا تفهرس: كل فهرس يُبطّئ INSERT/UPDATE. لا تفهرس أعمدة لا تُستخدم في البحث.

JSON في PostgreSQL

PostgreSQL يدعم JSON أصيل:

sql
CREATE TABLE events (
  id SERIAL PRIMARY KEY,
  data JSONB NOT NULL
);

INSERT INTO events (data) VALUES
  ('{"type": "click", "x": 100, "y": 200}'),
  ('{"type": "submit", "form": "login"}');

-- استعلام داخل JSON
SELECT * FROM events WHERE data->>'type' = 'click';

-- فهرس على JSON
CREATE INDEX idx_events_type ON events((data->>'type'));

المعاملات (Transactions)

لضمان أن عدّة أوامر إما تنجح كلها أو تفشل كلها:

sql
BEGIN;

UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;

-- إن كلاهما نجح
COMMIT;

-- أو إن فشل شيء
ROLLBACK;

أفضل الممارسات

  • استخدم DECIMAL للأموال — لا FLOAT أبداً (أخطاء تقريب)
  • TIMESTAMPTZ دائماً — يتجنّب مشاكل المناطق الزمنية
  • UNIQUE constraints للإيميلات ومفاتيح العمل
  • FOREIGN KEY لضمان تكامل البيانات
  • Soft delete (deleted_at بدل DELETE) للبيانات المهمّة
  • Backup يومي على خادم الإنتاج

الاتصال من Node.js

js
import pg from "pg";

const pool = new pg.Pool({
  connectionString: process.env.DATABASE_URL,
});

const { rows } = await pool.query(
  "SELECT * FROM products WHERE price > $1",
  [500]
);
console.log(rows);

الأسئلة الشائعة

PostgreSQL vs MySQL؟

  • Postgres: أغنى ميزات، أفضل لقواعد معقّدة
  • MySQL: أبسط، أشهر في الاستضافة الرخيصة

ابدأ بـ Postgres إن كنت تختار الآن.

ما هو Prisma؟

ORM لـ JavaScript/TypeScript يسهّل العمل مع Postgres دون كتابة SQL خاماً. ممتاز للمشاريع الحديثة.

كيف أحمي بياناتي من الضياع؟

bash
# نسخة احتياطية
pg_dump -U postgres mystore > backup.sql

# استعادة
psql -U postgres mystore < backup.sql
اقرأ أيضاً

مقالات ذات صلة