Data Manipulation Language (DML) ו-Mutations הם שני ממשקי API ב-Spanner שאפשר להשתמש בהם כדי לשנות נתונים. כל אחד מהם מציע תכונות דומות של מניפולציה של נתונים. בדף הזה מוצגות השוואות בין שתי הגישות.
מהי שפת טיפול בנתונים (DML)?
שפת הטיפול בנתונים (DML) ב-Spanner מאפשרת לכם לטפל בנתונים בטבלאות של מסד הנתונים באמצעות הצהרות INSERT, UPDATE ו-DELETE. אפשר להריץ הצהרות DML באמצעות ספריות הלקוח, מסוףGoogle Cloud ו-gcloud spanner.
Spanner מציע את שתי ההטמעות הבאות של ביצוע DML, שלכל אחת מהן יש מאפיינים שונים.
Standard DML – מתאים לעומסי עבודה רגילים של עיבוד עסקאות אונליין (OLTP).
מידע נוסף, כולל דוגמאות קוד, זמין במאמר שימוש ב-DML.
Partitioned DML – מיועד לעדכונים ולמחיקות של מספר פריטים בו-זמנית, כמו בדוגמאות הבאות.
ניקוי תקופתי ו-garbage collection. לדוגמה, מחיקה של שורות ישנות או הגדרת עמודות ל-NULL.
מילוי חוזר של עמודות חדשות בערכי ברירת מחדל. לדוגמה, אפשר להשתמש בהצהרת UPDATE כדי להגדיר את הערך של עמודה חדשה כ-False במקרים שבהם הוא NULL.
מידע נוסף, כולל דוגמאות קוד, זמין במאמר בנושא שימוש ב-DML מחולק.
אפשר להשתמש בכתיבה של קבוצות גדולות של פעולות כתיבה בלי פעולות קריאה שלא דורשות טרנזקציות אטומיות. מידע נוסף מופיע במאמר שינוי נתונים באמצעות כתיבה באצווה.
מהן מוטציות?
מוטציה מייצגת רצף של פעולות הוספה, עדכון ומחיקה שמערכת Spanner מבצעת באופן אטומי בשורות ובטבלאות שונות במסד נתונים. אפשר לכלול במוטציה פעולות שחלות על שורות שונות או על טבלאות שונות. אחרי שמגדירים מוטציה אחת או יותר שמכילה כתיבה אחת או יותר, צריך להחיל את המוטציה כדי לבצע את הכתיבה. כל שינוי מוחל לפי הסדר שבו הוא נוסף למוטציה.
למידע נוסף, כולל דוגמאות קוד, תוכלו לקרוא את המאמר בנושא הוספה, עדכון ומחיקה של נתונים באמצעות מוטציות.
השוואה בין תכונות של DML לבין מוטציות
בטבלה הבאה מפורט סיכום של התמיכה ב-DML ובמוטציות של פעולות ותכונות נפוצות במסדי נתונים.
| תפעול | DML | מוטציות |
|---|---|---|
| הוספת נתונים | נתמך | נתמך |
| מחיקת נתונים | נתמך | נתמך |
| עדכון נתונים | נתמך | נתמך |
| הוספה או התעלמות מהנתונים | נתמך | לא נתמך |
| קריאה של מה שכתבתם (RYW) | נתמך | לא נתמך |
| הוספה או עדכון של נתונים (Upsert) | נתמך | נתמך |
| תחביר SQL | נתמך | לא נתמך |
| בדיקת מגבלות | אחרי כל הצהרה | בזמן השמירה |
יש הבדלים בין DML לבין מוטציות בתמיכה בתכונות הבאות:
Read Your Writes: קריאת תוצאות לא מחויבות בתוך טרנזקציה פעילה. שינויים שמבצעים באמצעות הצהרות DML גלויים להצהרות הבאות באותה עסקה. זה שונה משימוש במוטציות, שבהן השינויים לא גלויים בקריאות (כולל קריאות שמתבצעות באותה טרנזקציה) עד שהטרנזקציה מתבצעת. הסיבה לכך היא שמוטציות בעסקה נשמרות במאגר זמני בצד הלקוח (באופן מקומי) ונשלחות לשרת כחלק מפעולת השמירה. כתוצאה מכך, מוטציות בבקשת השמירה לא גלויות להצהרות SQL או DML באותה טרנזקציה.
בדיקת אילוצים: מערכת Spanner בודקת אילוצים אחרי כל פקודת DML. זה שונה משימוש במוטציות, שבהן Spanner מאחסן את המוטציות בזיכרון הזמני של הלקוח עד לביצוע commit, ובודק את האילוצים בזמן ה-commit. הערכת האילוצים אחרי כל פקודת DML מאפשרת ל-Spanner להבטיח שהנתונים שמוחזרים על ידי שאילתה עוקבת באותה טרנזקציה יהיו עקביים עם הסכימה.
תחביר SQL: שפת DML מספקת דרך מקובלת לטיפול בנתונים. אפשר להשתמש מחדש בכישורי SQL כדי לשנות את הנתונים באמצעות DML API.
שיטה מומלצת – לא מומלץ לערבב DML ושינוי באותה טרנזקציה
אם טרנזקציה מכילה גם הצהרות DML וגם מוטציות בבקשת האישור, Spanner מבצע את הצהרות ה-DML לפני המוטציות. כדי להימנע מהצורך להתחשב בסדר הביצוע בקוד של ספריית הלקוח, מומלץ להשתמש בהצהרות DML או בשינויים בעסקה אחת, אבל לא בשניהם.
בדוגמה הבאה של Java אפשר לראות התנהגות שעשויה להפתיע. הקוד מוסיף שתי שורות לטבלה Albums באמצעות Mutation API. הקטע קוד הזה קורא ל-executeUpdate() כדי לעדכן את השורות החדשות שנוספו וקורא ל-executeQuery() כדי לקרוא את האלבומים המעודכנים.
static void updateMarketingBudget(DatabaseClient dbClient) {
dbClient
.readWriteTransaction()
.run(
new TransactionCallable<Void>() {
@Override
public Void run(TransactionContext transaction) throws Exception {
transaction.buffer(
Mutation.newInsertBuilder("Albums")
.set("SingerId")
.to(1)
.set("AlbumId")
.to(1)
.set("AlbumTitle")
.to("Total Junk")
.set("MarketingBudget")
.to(800)
.build());
transaction.buffer(
Mutation.newInsertBuilder("Albums")
.set("SingerId")
.to(1)
.set("AlbumId")
.to(2)
.set("AlbumTitle")
.to("Go Go Go")
.set("MarketingBudget")
.to(200)
.build());
// This UPDATE will not include the Albums inserted above.
String sql =
"UPDATE Albums SET MarketingBudget = MarketingBudget * 2"
+ " WHERE SingerId = 1";
long rowCount = transaction.executeUpdate(Statement.of(sql));
System.out.printf("%d records updated.\n", rowCount);
// Read a newly updated record.
sql =
"SELECT SingerId, AlbumId, AlbumTitle FROM Albums"
+ " WHERE SingerId = 1 AND MarketingBudget < 1000";
ResultSet resultSet =
transaction.executeQuery(Statement.of(sql));
while (resultSet.next()) {
System.out.printf(
"%s %s\n",
resultSet.getString("FirstName"),
resultSet.getString("LastName"));
}
return null;
}
});
}
אם תפעילו את הקוד הזה, תראו את ההודעה 0 רשומות עודכנו. למה? זה קורה כי השינויים שביצענו באמצעות Mutations לא גלויים להצהרות הבאות עד שהטרנזקציה מתבצעת. באופן אידיאלי, צריך לבצע כתיבות בזיכרון המטמון רק בסוף העסקה.
מה השלב הבא?
כדי לראות את מספר השינויים בעסקה, אפשר לעיין במאמר בנושא אחזור נתוני התחייבות לעסקה.