משיב מוביל
מחיקת שורות עם "מפתח זר" foreign key.

שאלה
-
שלום לכולם,
כיצד ניתן לבצע, ללא הורדת מערכת, מחיקת נתונים מבסיס הנתונים כאשר הטבלאות מקושורות? האם להוריד מלמטה עד לטבלה הראשית או שיש פעולת "קסם" שמבצעת את המחיקה למעלה עד למטה, ז"א כל הטבלאות המקושרות לה?
תרחיש קצר: יש לי 5 טבלאות המקושרות זה לזה ובאופן תמידי יש לי הכנסות לבסיס הנתונים. אני מעוניין שבכל יום בשעה מסויימת אני אבצע מחיקת נתונים, אני מעוניין לשמור X ימים אחורה וכל השאר למחוק. המחיקה מתבצעת על ידי השוואה של עמודת התאריך.
אני עובד על SQL SERVER 2008 R2.
תקנו אותי אם אני טועה, שאם אני מבצע מחיקה של נתונים בטבלה אני "נועל" את הטבלה. אם כן, פעולת ה INSERT עלולה להיכשל.
תשובות
-
הי עידו,
במידה והטבלאות מקושרות ב Foreign Key אתה יכול להגדיר מאפיין, ביצירת הקשר, עבור פעולת מחיקה שנקרא On Delete cascade.
בעת מחיקה מטבלת האב תתבצע מחיקה גם מטבלת הבן וכן הלאה בשרשרת עד הטבלה הנמוכה ביותר.
לדעתי עדיף לנהל את המחיקה מאשר להגדיר את המאפיין הנ"ל וכך לשלוט בצורה טובה יותר במה שמתרחש, במידה ותבחר לבצע את המחיקה יש לך שתי אופציות:
1. מחיקה מלמטה כלפי מעלה.
2. לנטרל את ה- Foreign keys ע"י פקודת Alter פשוטה ואז למחוק בסדר שאתה רוצה ובסיום המחיקה והפעיל את ה- Constraints מחדש.
לגבי השאלה השניה, רמת הנעילה תיקבע ביחס לכמות הרשומות שנמחקות לעומת כמות הרשומות בטבלה כך שלא בטוח שיתבצע table lock.
לגבי ההשפעות על ה- Inserts, במידה וה- clustered key בטבלה הוא אינקרמנטלי אזי כל רשומה חדשה תכנס בדף האחרון כך שבמידה ורמת הנעילה שנקבע בסעיף הקודם לא נועלת דף זה לא תחווה שום בעיה.
באופן כללי ובמידת האפשר, אם אתה מעוניין לשמור בטבלה רק ערכים בטווח מסויים של תאריכים הדרך היעילה והמהירה ביותר זה לעשות Partitions ואז בעזרת Switch out "למחוק" נתונים שפג תוקפם.
אסף שלם- הוצע כתשובה על-ידי EitanBlumin יום שני 13 דצמבר 2010 06:34
- סומן כתשובה על-ידי Idoamrani יום שני 13 דצמבר 2010 08:45
כל התגובות
-
הי עידו,
במידה והטבלאות מקושרות ב Foreign Key אתה יכול להגדיר מאפיין, ביצירת הקשר, עבור פעולת מחיקה שנקרא On Delete cascade.
בעת מחיקה מטבלת האב תתבצע מחיקה גם מטבלת הבן וכן הלאה בשרשרת עד הטבלה הנמוכה ביותר.
לדעתי עדיף לנהל את המחיקה מאשר להגדיר את המאפיין הנ"ל וכך לשלוט בצורה טובה יותר במה שמתרחש, במידה ותבחר לבצע את המחיקה יש לך שתי אופציות:
1. מחיקה מלמטה כלפי מעלה.
2. לנטרל את ה- Foreign keys ע"י פקודת Alter פשוטה ואז למחוק בסדר שאתה רוצה ובסיום המחיקה והפעיל את ה- Constraints מחדש.
לגבי השאלה השניה, רמת הנעילה תיקבע ביחס לכמות הרשומות שנמחקות לעומת כמות הרשומות בטבלה כך שלא בטוח שיתבצע table lock.
לגבי ההשפעות על ה- Inserts, במידה וה- clustered key בטבלה הוא אינקרמנטלי אזי כל רשומה חדשה תכנס בדף האחרון כך שבמידה ורמת הנעילה שנקבע בסעיף הקודם לא נועלת דף זה לא תחווה שום בעיה.
באופן כללי ובמידת האפשר, אם אתה מעוניין לשמור בטבלה רק ערכים בטווח מסויים של תאריכים הדרך היעילה והמהירה ביותר זה לעשות Partitions ואז בעזרת Switch out "למחוק" נתונים שפג תוקפם.
אסף שלם- הוצע כתשובה על-ידי EitanBlumin יום שני 13 דצמבר 2010 06:34
- סומן כתשובה על-ידי Idoamrani יום שני 13 דצמבר 2010 08:45
-
היי אסף, תודה על תשובתך, היא מצויינת.
השימוש ב Switch Out נראית לי טובה מאוד למטרה שלי. אנסה לחפש אינפורמציה בעניין, אם יש לך אשמח לקבל.
לקבל מחיקת ה Constraints והגדרתו מחדש. אם בתהליך המחיקה אני אכניס נתונים לא תקינים, אזי, בעת הגדרת ה Constraints מחדש אני אכשל, לאכן?!
-
-
הי עידו,
לינק מצויין שמסביר על partition tables:
http://www.madeira.co.il/partitioning-on-sql-server/
לגבי ה - Constraints
שאתה עושה Enable ל- Constraint אתה יכול לקבוע האם לבדוק נתונים קיימים או לא.
הסינטקס הוא כזה:
יום טוב-- Disable all constraint on table Alter table [table_name] nocheck constraint all -- Enable all constraint , do not check existing data. Alter table [table_name] check constraint all -- Enable all constraint , check existing data. Alter table [table_name] with check check constraint all
אסף שלם -
-