none
מחיקת שורות עם "מפתח זר" foreign key. RRS feed

  • שאלה

  • שלום לכולם,

    כיצד ניתן לבצע, ללא הורדת מערכת, מחיקת נתונים מבסיס הנתונים כאשר הטבלאות מקושורות? האם להוריד מלמטה עד לטבלה הראשית או שיש פעולת "קסם" שמבצעת את המחיקה למעלה עד למטה, ז"א כל הטבלאות המקושרות לה?

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

    אני עובד על SQL SERVER 2008 R2.

    תקנו אותי אם אני טועה, שאם אני מבצע מחיקה של נתונים בטבלה אני "נועל" את הטבלה. אם כן, פעולת ה INSERT עלולה להיכשל.

     

    יום ראשון 12 דצמבר 2010 14:17

תשובות

  • הי עידו,

    במידה והטבלאות מקושרות ב 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
    יום ראשון 12 דצמבר 2010 15:46

כל התגובות

  • הי עידו,

    במידה והטבלאות מקושרות ב 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
    יום ראשון 12 דצמבר 2010 15:46
  • היי אסף, תודה על תשובתך, היא מצויינת.

    השימוש ב Switch Out נראית לי טובה מאוד למטרה שלי. אנסה לחפש אינפורמציה בעניין, אם יש לך אשמח לקבל.

    לקבל מחיקת ה Constraints והגדרתו מחדש. אם בתהליך המחיקה אני אכניס נתונים לא תקינים, אזי, בעת הגדרת ה Constraints מחדש אני אכשל, לאכן?!

     

    יום שני 13 דצמבר 2010 08:51
  • שכחתי לציין כי אני משתמש ב Express Edition כך שהפקודה PARTITION FUNCTION  אינה נתמכת בגרסה זו.

    לכן, אני הולך על אפשרות של On Delete cascade מאחר ואין לי יותר מידי nesting בטבלאות, הם אינן יותרי מידי עמוקות, מקסימום nesting של 3.

     

    יום שני 13 דצמבר 2010 10:12
  • הי עידו,

    לינק מצויין שמסביר על 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
    
    יום טוב
    אסף שלם
    יום שני 13 דצמבר 2010 10:27
  • הי עידו,

    Partitioning אכן לא נתמך בגרסת express ועל תרגיש מקופח גם לא בגרסת Standard, אך בכל זאת קריאת המאמר תעזור לך להבין נושא חשוב זה.

    קריאה נעימה


    אסף שלם
    יום שני 13 דצמבר 2010 10:29
  • תודה רבה, עזרת לי מאוד.
    יום שני 13 דצמבר 2010 16:15