שיעורי מודול (2/4)
אילוצים מרובים וברמת הטבלה
חשוב לוודא שהנתונים במסד הנתונים נכונים ברובד הבסיסי ביותר ("שלמות הנתונים"). אם תכתוב בטיחות רק ביישום Node.js, באגים עלולים לגרום לנתונים לא עקביים ב-DB. אילוצים ברמת DDL הם קו ההגנה האחרון והבלתי חדיר.
האילוצים העיקריים
בנוסף ל-PRIMARY KEY (מה שהופך עמודה לייחודית ולא NULL) ול-NOT NULL הקלאסיות וUNIQUE, ישנן שתי קטגוריות בסיסיות לעקביות הלוגית של הנתונים:
1. מפתח זר (שלמות התייחסות)
אילוץ REFERENCES מבטיח שמזהה מקשר באמת קיים בטבלת ה"אב" שאליה הוא מצביע.
לדוגמה, הזמנה חייבת להיות מקושרת ללקוח קיים.
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_id INTEGER REFERENCES customers(id)
);מה עושה מפתח הזר?
- זה מונע ממך להכניס
customer_idשלא קיים בcustomers. - זה מונע ממך
DELETE(למחוק) לקוח מ-customersאם יש הזמנות שמצביעות עליהם (הוא מגן מפני רשומות "יתומות").
אנחנו יכולים גם להחליט מה צריך לקרות כאשר "ההורה" נמחק:
customer_id INTEGER REFERENCES customers(id) ON DELETE CASCADEעם ON DELETE CASCADE, אם נמחק את הלקוח, Postgres תסיר אוטומטית את כל orders המקושרים! (השתמש בזהירות רבה; בדרך כלל הגדרת ברירת המחדל החוסמת את הפעולה עדיפה.)
2. בדוק אילוצים
אילוץ CHECK מאמת את השורה על ידי בדיקת ביטוי בוליאני לפני המשך השמירה.
CREATE TABLE contratti (
id SERIAL PRIMARY KEY,
stipendio NUMERIC(10,2) CHECK (stipendio > 0),
data_inizio DATE,
data_fine DATE,
CHECK (data_fine > data_inizio)
);CHECK הראשון הוא אילוץ עמודה (הוא מתייחס רק לstipendio).
ה-CHECK השני בתחתית הוא אילוץ טבלה (הוא יכול לחצות ערכים ממספר עמודות, ויש להכריז עליו בתחתית).
אם INSERT או UPDATE ינסו לשמור את הסוף לפני ההתחלה, Postgres ידחה אותו בשגיאה!
אילוצי שמות
לרוב, נוהג טוב לתת לאילוצים שם מפורש (באמצעות מילת המפתח CONSTRAINT). בדרך זו, כאשר Postgres חוסם רשומה, השגיאה תאמר לך למשל "הפרה של אילוץ 'stipendio_positivo'", וזה הרבה יותר ברור עבור ניפוי באגים!
CREATE TABLE prodotti (
id SERIAL PRIMARY KEY,
nome VARCHAR(50),
CONSTRAINT nome_univoco UNIQUE(nome)
);נסה את זה
צור טבלה 'prenotazioni' עם מזהה (SERIAL PRIMARY KEY) ו-'customer_id' (INTEGER). השתמש ב-CONSTRAINT fk_cliente FOREIGN KEY (customer_id) REFERENCES customers(id) כדי לתת שם מפורש לאילוץ המפתח הזר. עשה זאת בחלק התחתון, כאילוץ טבלה.
הצג רמז
כתוב CONSTRAINT fk_cliente מפתח זר (local_column) REFERENCES external_table(external_col)
הפתרון זמין לאחר 3 ניסיונות
אילוצים עם היגיון מותאם אישית
צור טבלת 'eventi' עם id (SERIAL PRIMARY KEY), posti_totali (INTEGER) ו- biglietti_venduti (INTEGER). הוסף אילוץ טבלה בשם 'check_capienza' שבו biglietti_venduti לעולם לא יהיה גדול מ-posti_totali.
הצג רמז
הוסף את האילוץ בתחתית באמצעות CONSTRAINT check_capienza CHECK ( ביטוי )
הפתרון זמין לאחר 3 ניסיונות