ניהול ערכי ברירת מחדל של מפתח ראשי

בדף הזה מוסבר על אסטרטגיות ליצירת ערכי מפתח ראשי בטבלה באמצעות ביטויי ערך ברירת מחדל. המידע בדף הזה רלוונטי למסדי נתונים של ניב GoogleSQL ולמסדי נתונים של ניב PostgreSQL. היתרונות של השיטות האלה:

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

שיטות ליצירת מפתחות ראשיים באופן אוטומטי

כדי ליצור באופן אוטומטי ערכים של מפתח ראשי, אפשר להשתמש באסטרטגיות הבאות בעמודה עם ביטויי DEFAULT:

  • פונקציית UUID שמייצרת ערכי UUID בגרסה 4.
  • עמודות IDENTITY שיוצרות באופן אוטומטי ערכים של מספרים שלמים לעמודות מפתח ולעמודות שאינן מפתח.
  • SERIAL ב-PostgreSQL ו-AUTO_INCREMENT ב-GoogleSQL, שהם כינויי DDL לעמודות IDENTITY.
  • אובייקט סכימה, SEQUENCE, שיש לו אפשרות bit_reversed_positive. ‫SEQUENCE זמין גם ב-GoogleSQL וגם ב-PostgreSQL.

מזהה ייחודי אוניברסלי (UUID)

מערכת Spanner יכולה ליצור באופן אוטומטי מזהה ייחודי אוניברסלי (UUID) בגרסה 4 לשימוש כמפתח ראשי. מזהי UUID מתאימים לאפליקציות חדשות ולטבלאות עם הרבה שורות. הם מפוזרים באופן אחיד בערך במרחב המפתחות, מה שמונע נקודות חמות בקנה מידה גדול. יצירת UUID יכולה ליצור מספר גדול של ערכים (2122), וכל ערך הוא ייחודי. לדוגמה, כדי לקבל הסתברות של 50% להתנגשות, צריך 2.71‎×1018 ערכים, או מיליארד ערכים בשנייה למשך 86 שנים. השימוש בפונקציה הזו מבטיח ערכים ייחודיים כשמשתמשים בה בטבלאות גדולות. מזהי UUID הם ייחודיים, בין אם יוצרים אותם במסד הנתונים או בלקוח. מומלץ להשתמש ב-UUID כשאפשר. אפשר לשלב בבטחה מזהי UUID שנוצרו על ידי הלקוח ומזהי UUID שנוצרו על ידי Spanner באותה טבלה, אם מזהי ה-UUID שנוצרו על ידי הלקוח עוברים סריאליזציה באותיות קטנות, בהתאם ל-RFC 4122.

כדי ליצור ערכי ברירת מחדל לעמודה, אפשר להשתמש בפונקציה NEW_UUID של GoogleSQL או בפונקציה gen_random_uuid() של PostgreSQL. בדוגמה הבאה מוצג אופן יצירת טבלה שבה לעמודת המפתח FanId יש UUID שנוצר בעמודת הערך כערך ברירת המחדל שלה.

GoogleSQL

CREATE TABLE Fans (
  FanId UUID DEFAULT (NEW_UUID()),
  Name STRING(MAX),
) PRIMARY KEY (FanId);

PostgreSQL

CREATE TABLE Fans (
  FanId uuid DEFAULT gen_random_uuid(),
  Name text,
  PRIMARY KEY (FanId)
);

GoogleSQL

INSERT INTO Fans (Name) VALUES ('Melissa Garcia')
THEN RETURN FanId;

PostgreSQL

INSERT INTO fans (name) VALUES ('Melissa Garcia')
RETURNING (fanid);

ההצהרה הזו מחזירה תוצאה שדומה לתוצאה הבאה:

FanId
6af91072-f009-4c15-8c42-ebe38ae83751

מידע נוסף על פונקציות UUID שנוצרו זמין בדף העזר בנושא GoogleSQL או PostgreSQL.

IDENTITY עמודות

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

כדי להשתמש בעמודות IDENTITY, אפשר לספק ערך של מספר שלם להתחלה כשיוצרים את הרצף, או לאפשר ל-Spanner ליצור את רצף המספרים השלמים בשבילכם. כדי לספק ערך התחלתי של מספר שלם, צריך להשתמש באפשרות START COUNTER WITH ובערך התחלתי חיובי INT64. מערכת Spanner משתמשת בערך הזה כדי להגדיר את הערך הבא של מונה הרצף הפנימי שנוצר אוטומטית, והופכת את סדר הביטים של הערך לפני שהיא מוסיפה אותו לעמודה הזו.

ב-Spanner, יש תמיכה בעמודות IDENTITY ב-GoogleSQL וב-PostgreSQL.

GoogleSQL

בדוגמה הבאה מוצג איך להשתמש בעמודות IDENTITY כדי ליצור עמודת מפתח ראשי של מספר שלם שנוצר אוטומטית עבור SingerId כשיוצרים טבלה חדשה באמצעות הפקודה CREATE TABLE:

CREATE TABLE Singers (
  SingerId INT64 GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE),
  Name STRING(MAX),
  Rank INT64
) PRIMARY KEY (SingerId);

אפשר גם לציין את נקודת ההתחלה של המונה בעמודה באמצעות האפשרות START_WITH_COUNTER. בדוגמה הבאה, נוצרת עמודה של מספרים שלמים שנוצרה אוטומטית עבור SingerId, עם ערכים חיוביים שהביטים שלהם הפוכים ומונה פנימי שמתחיל ב-1,000.

CREATE TABLE Singers (
  SingerId INT64 GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE START COUNTER WITH 1000),
  Name STRING(MAX),
  Rank INT64
) PRIMARY KEY (SingerId);

PostgreSQL

בדוגמה הבאה מוצג שימוש בעמודות IDENTITY כדי ליצור עמודת מספרים שלמים שנוצרת אוטומטית עבור SingerId כשיוצרים טבלה חדשה באמצעות הפקודה CREATE TABLE:

CREATE TABLE Singers (
  SingerId bigint GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE),
  Name text,
  PRIMARY KEY (SingerId)
);

אפשר גם לציין את נקודת ההתחלה של המונה בעמודה באמצעות האפשרות START COUNTER WITH. בדוגמה הבאה, נוצרת עמודה של מספרים שלמים שנוצרה אוטומטית עבור SingerId, שמפיקה ערכים חיוביים הפוכים בביטים. המונה הפנימי, לפני היפוך הביטים, מתחיל מ-1,000.

CREATE TABLE Singers (
  SingerId bigint GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE START COUNTER WITH 1000),
  Name text,
  PRIMARY KEY (SingerId)
);

SERIAL וגם AUTO_INCREMENT

‫Spanner תומך ב-SERIAL ב-PostgreSQL וב-AUTO_INCREMENT ב-GoogleSQL, שהם כינויים ל-DDL של עמודות IDENTITY ומשמשים ליצירת עמודות ייחודיות של מספרים שלמים. קודם צריך להגדיר את האפשרות default_sequence_kind של מסד הנתונים לפני שמשתמשים ב-SERIAL או ב-AUTO_INCREMENT. אפשר להשתמש בהצהרת ה-SQL הבאה כדי להגדיר את האפשרות default_squence_kind למסד הנתונים:

GoogleSQL

ALTER DATABASE db SET OPTIONS (default_sequence_kind = 'bit_reversed_positive');

CREATE TABLE Singers (
  id INT64 AUTO_INCREMENT PRIMARY KEY,
  name STRING(MAX),
)

PostgreSQL

ALTER DATABASE db SET spanner.default_sequence_kind = 'bit_reversed_positive';

CREATE TABLE Singers (
  id serial PRIMARY KEY,
  name text
);

שימו לב: מכיוון שהמיפוי של SERIAL ו-AUTO_INCREMENT הוא לעמודות IDENTITY, הן לא יופיעו כשמבצעים סריאליזציה של הסכימה. בסכימה הזו, הפלט של GetDatabaseDDL יהיה:

GoogleSQL

ALTER DATABASE db SET OPTIONS (default_sequence_kind = 'bit_reversed_positive');

CREATE TABLE Singers (
  id INT64 GENERATED BY DEFAULT AS IDENTITY,
  name STRING(MAX),
) PRIMARY KEY (id);

PostgreSQL

ALTER DATABASE db SET spanner.default_sequence_kind = 'bit_reversed_positive';

CREATE TABLE Singers (
  id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
  name character varying,
  PRIMARY KEY(id)
);

רצף הפוך של ביטים

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

ב-Spanner, משתמשים בהצהרות DDL יחד עם המאפיין bit_reversed_positive כדי ליצור, לשנות או להסיר רצף שמפיק ערכים חיוביים הפוכים (GoogleSQL או PostgreSQL).SEQUENCE

כל רצף שומר על קבוצה של מוני פנימיים ומשתמש בהם כדי ליצור ערך. מונה הרצף מספק את הקלט לאלגוריתם של היפוך הביטים.

כשמגדירים עמודה עם ביטוי DEFAULT שמשתמש בפונקציה GET_NEXT_SEQUENCE_VALUE של GoogleSQL או בפונקציה nextval של PostgreSQL כערך ברירת המחדל שלה, מערכת Spanner קוראת לפונקציה באופן אוטומטי ומכניסה לעמודה את ערכי הפלט שהתקבלו אחרי היפוך הביטים. רצפים עם היפוך ביטים שימושיים במיוחד למפתחות ראשיים, כי ערכים עם היפוך ביטים מפוזרים באופן שווה במרחב המפתחות, כך שהם לא גורמים לנקודות חמות.

בדוגמה הבאה מוצגות שתי דרכים ליצור רצף הפוך-ביטים וטבלה שבה עמודת המפתח משתמשת ברצף כערך ברירת המחדל:

GoogleSQL

CREATE SEQUENCE SingerIdSequence OPTIONS (
  sequence_kind="bit_reversed_positive"
);

CREATE TABLE Singers (
  SingerId INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE SingerIdSequence)),
  Name STRING(MAX),
  Rank INT64,
) PRIMARY KEY (SingerId);

PostgreSQL

CREATE SEQUENCE SingerIdSequence bit_reversed_positive;

CREATE TABLE Singers (
  SingerId bigint DEFAULT nextval('SingerIdSequence'),
  Name text,
  PRIMARY KEY (SingerId)
);

לאחר מכן אפשר להשתמש בהצהרת ה-SQL הבאה כדי להוסיף את ערך המפתח הראשי ולהחזיר אותו:

GoogleSQL

INSERT INTO Singers (Name) VALUES ('Melissa Garcia')
THEN RETURN SingerId;

PostgreSQL

INSERT INTO Singers (name) VALUES ('Melissa Garcia')
RETURNING (SingerId);

ההצהרה הזו מחזירה תוצאה שדומה לתוצאה הבאה:

SingerId
3458764513820540928

תרחישים לשימוש ב-UUID וברצפים כערכי ברירת מחדל למפתחות ראשיים

התרחישים של UUID ורצפים כוללים את האפשרויות הבאות:

  • אפליקציות חדשות
  • מיגרציות

בקטעים הבאים מתואר כל תרחיש.

אפליקציות חדשות

באפליקציות חדשות, מומלץ להשתמש ב-Spanner במזהה ייחודי אוניברסלי (UUID) למפתחות ראשיים. מידע נוסף זמין במאמר שימוש במזהה ייחודי אוניברסלי (UUID).

אם האפליקציה הקיימת שלכם דורשת מפתחות INT64 ב-GoogleSQL או מפתחות bigint ב-PostgreSQL,‏ Spanner מציע את אובייקט הסכימה של רצף חיובי הפוך-ביטים (PostgreSQL או GoogleSQL).

מיגרציות

כשמעבירים טבלאות ל-Spanner, יש לכם את האפשרויות הבאות:

המאמרים הבאים