Menu

SQLite CREATE TABLE: תחביר, אילוצים ודוגמאות

איך יוצרים טבלאות ב-SQLite: הגדרות עמודות, אילוצים, IF NOT EXISTS, טבלאות זמניות ו-CREATE TABLE AS SELECT.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

CREATE TABLE מגדירה סכמה

כל פיסת מידע מובנה ב-SQLite חיה בטבלה, וכל טבלה מתחילה בפקודת CREATE TABLE. נותנים לה שם, מפרטים את העמודות, ואפשר גם להצמיד אילוצים. SQLite כותבת את הסכמה לקובץ מסד הנתונים והטבלה מוכנה לשימוש.

הדוגמה השימושית הקטנה ביותר:

שלוש עמודות, מפתח ראשי אחד, כלל NOT NULL אחד. SQLite מילאה את id אוטומטית כי הוא מפתח ראשי מסוג integer, ונתנה ל-email להיות NULL בשורה השנייה כי שום דבר לא אמר אחרת. זה כל המבנה: שם, עמודות, אילוצים, וכל השאר בעמוד הזה הוא וריאציה עליו.

התחביר, חלק אחר חלק

הגדרת עמודה היא name TYPE constraint constraint .... ב-SQLite הקלאסית הטיפוס אופציונלי (עוד על זה בעמוד על type affinity), אבל זה הרגל טוב לכלול תמיד טיפוס: קוראים וכלים מסתמכים עליו.

כמה דברים שכדאי לשים לב אליהם:

  • אילוצים משורשרים עם רווחים: NOT NULL UNIQUE על sku אומר ששני הכללים חלים.
  • DEFAULT 1 על in_stock מאפשר ל-INSERT לדלג על העמודה הזו.
  • SQLite משתמשת ב-INTEGER לערכים בוליאניים: אין טיפוס BOOLEAN מובנה. 0 הוא שקר, 1 הוא אמת.
  • פסיק אחרי העמודה האחרונה הוא שגיאת תחביר. כאן SQL מחמירה יותר מ-JavaScript.

IF NOT EXISTS: לא לקרוס בהרצות חוזרות

הריצו CREATE TABLE על מסד נתונים שכבר יש בו את הטבלה הזו, ו-SQLite תזרוק שגיאה:

Error: table users already exists

בפעם הראשונה זה בסדר, בפעם המאה זה מעצבן. IF NOT EXISTS הופך את הפקודה לפעולה ריקה כשהטבלה כבר קיימת:

ה-CREATE TABLE השני לא עושה כלום: בלי שגיאה, בלי שינוי בסכמה. זו הצורה שאתם רוצים בקוד עלייה, בסקריפטים של מיגרציה ובכל מקום שבו אותו SQL עשוי לרוץ יותר מפעם אחת.

אזהרה, בכל זאת: IF NOT EXISTS בודק רק את ה_שם_. אם קיימת טבלה בשם הזה אבל עם עמודות אחרות, SQLite משאירה אותה כמו שהיא. היא לא "תתקן" ולא "תשדרג" את הסכמה בשבילכם. לזה נועדו מיגרציות.

אילוצים: כללים שנוסעים עם הסכמה

אילוצים הם הדרך לדחוף אימות לתוך מסד הנתונים עצמו. אלה שתשתמשו בהם כל הזמן:

  • PRIMARY KEY: מזהה שורה באופן ייחודי. עוד על זה במדריך על מפתחות ראשיים.
  • NOT NULL: לעמודה חייב להיות ערך.
  • DEFAULT value: משמש כש-INSERT משמיט את העמודה. יכול להיות ערך מילולי או ביטוי כמו datetime('now').
  • CHECK (expr): חייב להיות אמת בכל שורה.
  • UNIQUE (col, col): אילוץ ברמת הטבלה שאוכף ייחודיות על הצירוף.

אילוצים רצים בכל INSERT ו-UPDATE. שורה שמפרה אחד מהם נדחית והפקודה נכשלת. לתפוס נתונים גרועים במסד הנתונים זול בהרבה מלתפוס אותם אחרי שהתפשטו באפליקציה.

מפתחות זרים

מפתח זר אומר "העמודה הזו מצביעה על שורה בטבלה אחרת". הוא שומר על עקביות הנתונים: אי אפשר להפנות למשתמש שלא קיים, ו(עם האפשרויות הנכונות) מחיקת משתמש יכולה להתגלגל גם להזמנות שלו.

מלכודת של SQLite ששווה לזכור: אכיפת מפתחות זרים כבויה כברירת מחדל. צריך להריץ PRAGMA foreign_keys = ON בכל חיבור שרוצה שהאילוצים ייבדקו. רוב הדרייברים של אפליקציות עושים את זה בשבילכם או חושפים הגדרה; אם שלכם לא, הריצו את ה-pragma מיד אחרי ההתחברות.

ON DELETE CASCADE כאן אומר שמחיקת משתמש מוחקת אוטומטית את הפוסטים שלו. אפשרויות אחרות הן SET NULL, RESTRICT וברירת המחדל, NO ACTION, שדוחה את המחיקה אם יש שורות צאצא.

CREATE TABLE AS SELECT

לפעמים רוצים עותק מהיר של תוצאת שאילתה כטבלה חדשה: לתמונת מצב, לגיבוי או לטבלת עבודה בזמן ניתוח. CREATE TABLE ... AS SELECT עושה את זה:

הטבלה החדשה מעתיקה את שמות העמודות, את הטיפוסים (ככל האפשר) ואת הנתונים. מה שהיא לא מעתיקה חשוב באותה מידה: בלי מפתח ראשי, בלי NOT NULL, בלי אינדקסים, בלי מפתחות זרים. זו תמונת מצב שטוחה. התייחסו אליה כנקודת התחלה לעבודה אד הוק, לא כדרך לשכפל סכמה אמיתית.

אם אתם רוצים את המבנה בלי הנתונים, הוסיפו WHERE 0:

מקבלים טבלה ריקה עם אותו מבנה עמודות: שימושי לטבלאות ארכיון שתמלאו אחר כך.

טבלאות זמניות

טבלת TEMP חיה רק לאורך החיבור הנוכחי למסד הנתונים. סגרו את החיבור והיא נעלמת: בלי ניקוי, בלי סכמה שנשארת מאחור:

שימושים טובים: הכנת שורות לשאילתה של כמה שלבים, החזקת תוצאות ביניים מבולגנות מדי ל-CTE, בידוד נתונים לכל חיבור בסשן ארוך. CREATE TEMP TABLE ו-CREATE TEMPORARY TABLE הם אותו דבר.

אפשר לשלב גם עם AS SELECT: CREATE TEMP TABLE snapshot AS SELECT ... הוא דפוס נפוץ להקפאת תוצאה באמצע ניתוח.

מירכאות סביב שמות

ברוב הזמן, שמות עמודות וטבלאות הם מזהים פשוטים. אם חייבים להשתמש במילה שמורה או בשם עם רווחים, עטפו אותו במירכאות כפולות (תקן SQL) או ב-backticks (הרגל של MySQL ש-SQLite גם מקבלת):

זה עובד, אבל זה חיכוך בכל פעם שפונים לטבלה. העדיפו שמות פשוטים כמו orders, selection, user_id ותחסכו את המירכאות לגמרי.

דוגמה מציאותית

כשמחברים את החלקים, הנה סכמה קטנה לאפליקציית משימות, עם IF NOT EXISTS כדי שתוכל לרוץ בכל עלייה:

זו סכמה שאפשר לשחרר: יצירה אידמפוטנטית, מפתחות זרים נאכפים, CHECK ששומר על done הגון, ערכי ברירת מחדל הגיוניים וחותמות זמן שממלאות את עצמן.

הבא בתור: טיפוסי נתונים

CREATE TABLE מאפשרת לכתוב INTEGER, TEXT, REAL, אבל SQLite ידועה בגישה הנינוחה שלה לאופן שבו היא שומרת את הערכים האלה. העמוד הבא מכסה את חמש מחלקות האחסון ש-SQLite באמת משתמשת בהן, ולמה הטיפוס שכתבתם הוא לא תמיד הטיפוס שתקבלו.

שאלות נפוצות

איך יוצרים טבלה ב-SQLite?

משתמשים ב-CREATE TABLE name (column1 TYPE, column2 TYPE, ...). כל עמודה מקבלת שם וטיפוס אופציונלי, ואפשר להוסיף אילוצים כמו PRIMARY KEY, NOT NULL או DEFAULT. הפקודה רצה מיד והטבלה נשארת בקובץ מסד הנתונים.

מה עושה IF NOT EXISTS ב-CREATE TABLE?

CREATE TABLE IF NOT EXISTS name (...) יוצרת את הטבלה רק אם עוד לא קיימת טבלה בשם הזה. בלי זה, הרצה חוזרת של הסקריפט על מסד נתונים קיים זורקת את השגיאה table already exists. זו ההגנה הסטנדרטית בסקריפטים של מיגרציה ובקוד העלייה של אפליקציות.

אפשר ליצור טבלה מ-SELECT ב-SQLite?

כן: CREATE TABLE new_name AS SELECT ... בונה טבלה חדשה מתוצאת שאילתה. הטבלה החדשה מעתיקה שמות עמודות ונתונים, אבל לא מעתיקה אילוצים, מפתחות ראשיים או אינדקסים מהמקור. השתמשו בזה לתמונות מצב ולטבלאות עבודה, לא כתחליף לסכמה אמיתית.

מה ההבדל בין טבלה זמנית לטבלה רגילה?

CREATE TEMP TABLE (או CREATE TEMPORARY TABLE) יוצרת טבלה שקיימת רק לחיבור הנוכחי למסד הנתונים ונעלמת כשהחיבור נסגר. טבלאות רגילות נשמרות בקובץ מסד הנתונים. טבלאות זמניות שימושיות להחזקת תוצאות ביניים של שאילתות בלי ללכלך את הסכמה.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל