תחילת העבודה עם Spanner ב-PHP

מטרות

במדריך הזה מפורטים השלבים הבאים לשימוש בספריית הלקוח של Spanner ל-PHP:‏

  • יוצרים מכונה ומסד נתונים ב-Spanner.
  • לכתוב, לקרוא ולהריץ שאילתות SQL על נתונים במסד הנתונים.
  • מעדכנים את הסכימה של מסד הנתונים.
  • עדכון נתונים באמצעות טרנזקציה של קריאה וכתיבה.
  • מוסיפים אינדקס משני למסד הנתונים.
  • השימוש באינדקס מאפשר לקרוא ולהריץ שאילתות SQL על נתונים.
  • אחזור נתונים באמצעות טרנזקציה לקריאה בלבד.

עלויות

במדריך הזה נעשה שימוש ב-Spanner, שהוא רכיב בתשלום שלGoogle Cloud. מידע על עלות השימוש ב-Spanner מופיע בקטע תמחור.

לפני שמתחילים

צריך לבצע את השלבים שמפורטים במאמר הגדרה, שכוללים יצירה והגדרה של פרויקט ברירת מחדל Google Cloud , הפעלת החיוב, הפעלת Cloud Spanner API והגדרת OAuth 2.0 כדי לקבל אישורי אימות לשימוש ב-Cloud Spanner API.

בפרט, חשוב להריץ את הפקודה gcloud auth application-default login כדי להגדיר את סביבת הפיתוח המקומית עם פרטי אימות.

הכנת סביבת PHP מקומית

  1. פועלים לפי השלבים במאמר חשבונות שירות כדי להגדיר חשבון שירות כ-Application Default Credentials. אחרי שמבצעים את השלבים האלה, אמורים לקבל קובץ מפתח של חשבון שירות (בפורמט JSON) ומשתנה סביבה GOOGLE_APPLICATION_CREDENTIALS שמאפשר לאמת את הזהות שלכם ב-Spanner API.

  2. אם הפריטים הבאים לא מותקנים במחשב הפיתוח, צריך להתקין אותם:

  3. משכפלים את מאגר האפליקציה לדוגמה ומעבירים אותו למכונה המקומית:

    git clone https://github.com/GoogleCloudPlatform/php-docs-samples
    

    אפשרות נוספת היא להוריד את הדוגמה כקובץ ZIP ולחלץ אותה.

  4. עוברים לספרייה שמכילה את הקוד לדוגמה של Spanner:

    cd php-docs-samples/spanner
    
  5. יחסי תלות של התקנות:

    composer install
    

    הפקודה הזו מתקינה את ספריית הלקוח של Spanner ל-PHP, שאפשר להוסיף לכל פרויקט על ידי הפעלת composer require google/cloud-spanner.

יצירת מופע

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

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

  • ‫Google Cloud CLI
  • מסוף Google Cloud
  • ספריית לקוח (C++‎,‏ C#‎,‏ Go,‏ Java,‏ Node.js,‏ PHP,‏ Python או Ruby)

עיון בקבצים לדוגמה

מאגר הדוגמאות מכיל דוגמה שמראה איך להשתמש ב-Spanner עם PHP.

כדאי לעיין בפונקציות ב-src/create_database.php וב-src/add_column.php, שבהן מוסבר איך ליצור מסד נתונים ולשנות סכימה של מסד נתונים. הנתונים משתמשים בסכימה לדוגמה שמוצגת בדף סכימה ומודל נתונים.

יצירת מסד נתונים

GoogleSQL

php src/create_database.php test-instance example-db

PostgreSQL

php src/pg_create_database.php test-instance example-db

הפרטים שמוצגים הם:

Created database example-db on instance test-instance
הקוד הבא יוצר מסד נתונים ושתי טבלאות במסד הנתונים.

GoogleSQL

use Google\Cloud\Spanner\Admin\Database\V1\Client\DatabaseAdminClient;
use Google\Cloud\Spanner\Admin\Database\V1\CreateDatabaseRequest;

/**
 * Creates a database and tables for sample data.
 * Example:
 * ```
 * create_database($instanceId, $databaseId);
 * ```
 *
 * @param string $projectId The Google Cloud project ID.
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function create_database(string $projectId, string $instanceId, string $databaseId): void
{
    $databaseAdminClient = new DatabaseAdminClient();
    $instance = $databaseAdminClient->instanceName($projectId, $instanceId);

    $operation = $databaseAdminClient->createDatabase(
        new CreateDatabaseRequest([
            'parent' => $instance,
            'create_statement' => sprintf('CREATE DATABASE `%s`', $databaseId),
            'extra_statements' => [
                'CREATE TABLE Singers (' .
                'SingerId     INT64 NOT NULL,' .
                'FirstName    STRING(1024),' .
                'LastName     STRING(1024),' .
                'SingerInfo   BYTES(MAX),' .
                'FullName     STRING(2048) AS' .
                '(ARRAY_TO_STRING([FirstName, LastName], " ")) STORED' .
                ') PRIMARY KEY (SingerId)',
                'CREATE TABLE Albums (' .
                    'SingerId     INT64 NOT NULL,' .
                    'AlbumId      INT64 NOT NULL,' .
                    'AlbumTitle   STRING(MAX)' .
                ') PRIMARY KEY (SingerId, AlbumId),' .
                'INTERLEAVE IN PARENT Singers ON DELETE CASCADE'
            ]
        ])
    );

    print('Waiting for operation to complete...' . PHP_EOL);
    $operation->pollUntilComplete();

    printf('Created database %s on instance %s' . PHP_EOL,
        $databaseId, $instanceId);
}

PostgreSQL

use Google\Cloud\Spanner\Admin\Database\V1\Client\DatabaseAdminClient;
use Google\Cloud\Spanner\Admin\Database\V1\CreateDatabaseRequest;
use Google\Cloud\Spanner\Admin\Database\V1\DatabaseDialect;
use Google\Cloud\Spanner\Admin\Database\V1\GetDatabaseRequest;
use Google\Cloud\Spanner\Admin\Database\V1\UpdateDatabaseDdlRequest;

/**
 * Creates a database that uses Postgres dialect
 *
 * @param string $projectId The Google Cloud project ID.
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function pg_create_database(string $projectId, string $instanceId, string $databaseId): void
{
    $databaseAdminClient = new DatabaseAdminClient();
    $instance = $databaseAdminClient->instanceName($projectId, $instanceId);
    $databaseName = $databaseAdminClient->databaseName($projectId, $instanceId, $databaseId);

    $table1Query = 'CREATE TABLE Singers (
        SingerId   bigint NOT NULL PRIMARY KEY,
        FirstName  varchar(1024),
        LastName   varchar(1024),
        SingerInfo bytea,
        FullName character varying(2048) GENERATED
        ALWAYS AS (FirstName || \' \' || LastName) STORED
    )';
    $table2Query = 'CREATE TABLE Albums (
        AlbumId      bigint NOT NULL,
        SingerId     bigint NOT NULL REFERENCES Singers (SingerId),
        AlbumTitle   text,
        PRIMARY KEY(SingerId, AlbumId)
    )';

    $operation = $databaseAdminClient->createDatabase(
        new CreateDatabaseRequest([
            'parent' => $instance,
            'create_statement' => sprintf('CREATE DATABASE "%s"', $databaseId),
            'extra_statements' => [],
            'database_dialect' => DatabaseDialect::POSTGRESQL
        ])
    );

    print('Waiting for operation to complete...' . PHP_EOL);
    $operation->pollUntilComplete();

    $request = new UpdateDatabaseDdlRequest([
        'database' => $databaseName,
        'statements' => [$table1Query, $table2Query]
    ]);

    $operation = $databaseAdminClient->updateDatabaseDdl($request);
    $operation->pollUntilComplete();

    $database = $databaseAdminClient->getDatabase(
        new GetDatabaseRequest(['name' => $databaseAdminClient->databaseName($projectId, $instanceId, $databaseId)])
    );
    $dialect = DatabaseDialect::name($database->getDatabaseDialect());

    printf('Created database %s with dialect %s on instance %s' . PHP_EOL,
        $databaseId, $dialect, $instanceId);
}

השלב הבא הוא כתיבת נתונים למסד הנתונים.

יצירת לקוח מסד נתונים

כדי לבצע פעולות קריאה וכתיבה, צריך לקבל מופע של Google\Cloud\Spanner\Database.

# Includes the autoloader for libraries installed with composer
require __DIR__ . '/vendor/autoload.php';

# Imports the Google Cloud client library
use Google\Cloud\Spanner\SpannerClient;

# Your Google Cloud Platform project ID
$projectId = 'YOUR_PROJECT_ID';

# Instantiates a client
$spanner = new SpannerClient([
    'projectId' => $projectId
]);

# Your Cloud Spanner instance ID.
$instanceId = 'your-instance-id';

# Get a Cloud Spanner instance by ID.
$instance = $spanner->instance($instanceId);

# Your Cloud Spanner database ID.
$databaseId = 'your-database-id';

# Get a Cloud Spanner database by ID.
$database = $instance->database($databaseId);

# Execute a simple SQL statement.
$results = $database->execute('SELECT "Hello World" as test');

foreach ($results as $row) {
    print($row['test'] . PHP_EOL);
}

אפשר לחשוב על Database בתור חיבור למסד נתונים: כל האינטראקציות עם Spanner חייבות לעבור דרך Database. בדרך כלל יוצרים Database כשמפעילים את האפליקציה, ואז משתמשים שוב באותו Database כדי לקרוא, לכתוב ולהריץ עסקאות. כל לקוח משתמש במשאבים ב-Spanner.

אם יוצרים כמה לקוחות באותה אפליקציה, צריך להפעיל את הפונקציה Database::close כדי לנקות את המשאבים של הלקוח, כולל חיבורי רשת, ברגע שהם כבר לא נחוצים.

מידע נוסף זמין במאמר בנושא Database.

כתיבת נתונים באמצעות DML

אפשר להוסיף נתונים באמצעות שפת טיפול בנתונים (DML) בעסקת קריאה-כתיבה.

משתמשים ב-executeUpdate() method כדי להריץ פקודת DML.

use Google\Cloud\Spanner\SpannerClient;
use Google\Cloud\Spanner\Transaction;

/**
 * Inserts sample data into the given database with a DML statement.
 *
 * The database and table must already exist and can be created using
 * `create_database`.
 * Example:
 * ```
 * insert_data($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function write_data_with_dml(string $instanceId, string $databaseId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $database->runTransaction(function (Transaction $t) {
        $rowCount = $t->executeUpdate(
            'INSERT Singers (SingerId, FirstName, LastName) VALUES '
            . "(12, 'Melissa', 'Garcia'), "
            . "(13, 'Russell', 'Morales'), "
            . "(14, 'Jacqueline', 'Long'), "
            . "(15, 'Dylan', 'Shaw')");
        $t->commit();
        printf('Inserted %d row(s).' . PHP_EOL, $rowCount);
    });
}

מריצים את הקובץ לדוגמה src/write_data_with_dml.php.

php src/write_data_with_dml.php test-instance example-db

הפרטים שמוצגים הם:

Inserted 4 row(s).

כתיבת נתונים באמצעות מוטציות

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

כדי לכתוב נתונים, משתמשים ב-method‏ Database::insertBatch. ‫insertBatch מוסיף שורות חדשות לטבלה. כל ההוספות בחבילה אחת מוחלות באופן אטומי.

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

use Google\Cloud\Spanner\SpannerClient;

/**
 * Inserts sample data into the given database.
 *
 * The database and table must already exist and can be created using
 * `create_database`.
 * Example:
 * ```
 * insert_data($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function insert_data(string $instanceId, string $databaseId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $operation = $database->transaction(['singleUse' => true])
        ->insertBatch('Singers', [
            ['SingerId' => 1, 'FirstName' => 'Marc', 'LastName' => 'Richards'],
            ['SingerId' => 2, 'FirstName' => 'Catalina', 'LastName' => 'Smith'],
            ['SingerId' => 3, 'FirstName' => 'Alice', 'LastName' => 'Trentor'],
            ['SingerId' => 4, 'FirstName' => 'Lea', 'LastName' => 'Martin'],
            ['SingerId' => 5, 'FirstName' => 'David', 'LastName' => 'Lomond'],
        ])
        ->insertBatch('Albums', [
            ['SingerId' => 1, 'AlbumId' => 1, 'AlbumTitle' => 'Total Junk'],
            ['SingerId' => 1, 'AlbumId' => 2, 'AlbumTitle' => 'Go, Go, Go'],
            ['SingerId' => 2, 'AlbumId' => 1, 'AlbumTitle' => 'Green'],
            ['SingerId' => 2, 'AlbumId' => 2, 'AlbumTitle' => 'Forever Hold Your Peace'],
            ['SingerId' => 2, 'AlbumId' => 3, 'AlbumTitle' => 'Terrified']
        ])
        ->commit();

    print('Inserted data.' . PHP_EOL);
}

מריצים את הקובץ לדוגמה src/insert_data.php.

php src/insert_data.php test-instance example-db

הפרטים שמוצגים הם:

Inserted data.

הרצת שאילתות על נתונים באמצעות SQL

‫Spanner תומך בממשק SQL לקריאת נתונים, שאפשר לגשת אליו בשורת הפקודה באמצעות Google Cloud CLI או באופן פרוגרמטי באמצעות ספריית הלקוח של Spanner ל-PHP.

בשורת הפקודה

מריצים את הצהרת ה-SQL הבאה כדי לקרוא את הערכים של כל העמודות מהטבלה Albums:

gcloud spanner databases execute-sql example-db --instance=test-instance \
    --sql='SELECT SingerId, AlbumId, AlbumTitle FROM Albums'

התוצאה:

SingerId AlbumId AlbumTitle
1        1       Total Junk
1        2       Go, Go, Go
2        1       Green
2        2       Forever Hold Your Peace
2        3       Terrified

שימוש בספריית הלקוח של Spanner ל-PHP

בנוסף להרצת הצהרת SQL בשורת הפקודה, אפשר להנפיק את אותה הצהרת SQL באופן פרוגרמטי באמצעות ספריית הלקוח של Spanner ל-PHP.

משתמשים ב-Database::execute() כדי להריץ את שאילתת ה-SQL.

כך מריצים את השאילתה וניגשים לנתונים:

use Google\Cloud\Spanner\SpannerClient;

/**
 * Queries sample data from the database using SQL.
 * Example:
 * ```
 * query_data($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function query_data(string $instanceId, string $databaseId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $results = $database->execute(
        'SELECT SingerId, AlbumId, AlbumTitle FROM Albums'
    );

    foreach ($results as $row) {
        printf('SingerId: %s, AlbumId: %s, AlbumTitle: %s' . PHP_EOL,
            $row['SingerId'], $row['AlbumId'], $row['AlbumTitle']);
    }
}

מריצים את הקובץ לדוגמה src/query_data.php.

php src/query_data.php test-instance example-db

אמורה להתקבל התוצאה הבאה:

SingerId: 2, AlbumId: 2, AlbumTitle: Forever Hold Your Peace
SingerId: 1, AlbumId: 2, AlbumTitle: Go, Go, Go
SingerId: 2, AlbumId: 1, AlbumTitle: Green
SingerId: 2, AlbumId: 3, AlbumTitle: Terrified
SingerId: 1, AlbumId: 1, AlbumTitle: Total Junk

התוצאות לא בהכרח יוצגו בסדר הזה. אם אתם צריכים לוודא שהתוצאה תהיה מסודרת, אתם יכולים להשתמש בסעיף ORDER BY, כמו שמתואר בשיטות המומלצות ל-SQL.

שאילתה באמצעות פרמטר SQL

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

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

GoogleSQL

use Google\Cloud\Spanner\SpannerClient;

/**
 * Queries sample data from the database using SQL with a parameter.
 * Example:
 * ```
 * query_data_with_parameter($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function query_data_with_parameter(string $instanceId, string $databaseId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $results = $database->execute(
        'SELECT SingerId, FirstName, LastName FROM Singers ' .
        'WHERE LastName = @lastName',
        ['parameters' => ['lastName' => 'Garcia']]
    );

    foreach ($results as $row) {
        printf('SingerId: %s, FirstName: %s, LastName: %s' . PHP_EOL,
            $row['SingerId'], $row['FirstName'], $row['LastName']);
    }
}

PostgreSQL

use Google\Cloud\Spanner\SpannerClient;

/**
 * Execute a query with parameters on a Spanner PostgreSQL database.
 * The PostgreSQL dialect uses positional parameters, as
 * opposed to the named parameters of Cloud Spanner.
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function pg_query_parameter(string $instanceId, string $databaseId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    printf('Listing all singers with a last name that starts with \'A\'' . PHP_EOL);

    $results = $database->execute(
        'SELECT SingerId, FirstName, LastName' .
        ' FROM Singers' .
        ' WHERE LastName LIKE $1',
        [
        'parameters' => [
            'p1' => 'A%'
        ]
    ]
    );

    foreach ($results as $row) {
        printf('SingerId: %s, Firstname: %s, LastName: %s' . PHP_EOL, $row['singerid'], $row['firstname'], $row['lastname']);
    }
}

מריצים את הקובץ לדוגמה src/query_data_with_parameter.php.

php src/query_data_with_parameter.php test-instance example-db

אמורה להתקבל התוצאה הבאה:

SingerId: 12, FirstName: Melissa, LastName: Garcia

קריאת נתונים באמצעות read API

בנוסף לממשק ה-SQL של Spanner, ‏ Spanner תומך גם בממשק קריאה.

כדי לקרוא שורות ממסד הנתונים, משתמשים ב-Database::read(). משתמשים באובייקט KeySet כדי להגדיר אוסף של מפתחות וטווחים של מפתחות לקריאה.

כך קוראים את הנתונים:

use Google\Cloud\Spanner\SpannerClient;

/**
 * Reads sample data from the database.
 * Example:
 * ```
 * read_data($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function read_data(string $instanceId, string $databaseId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $keySet = $spanner->keySet(['all' => true]);
    $results = $database->read(
        'Albums',
        $keySet,
        ['SingerId', 'AlbumId', 'AlbumTitle']
    );

    foreach ($results->rows() as $row) {
        printf('SingerId: %s, AlbumId: %s, AlbumTitle: %s' . PHP_EOL,
            $row['SingerId'], $row['AlbumId'], $row['AlbumTitle']);
    }
}

מריצים את הדוגמה בקובץ read_data.php.

php read_data.php test-instance example-db

הפלט אמור להיראות כך:

SingerId: 1, AlbumId: 1, AlbumTitle: Total Junk
SingerId: 1, AlbumId: 2, AlbumTitle: Go, Go, Go
SingerId: 2, AlbumId: 1, AlbumTitle: Green
SingerId: 2, AlbumId: 2, AlbumTitle: Forever Hold your Peace
SingerId: 2, AlbumId: 3, AlbumTitle: Terrified

עדכון הסכימה של מסד הנתונים

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

הוספת עמודה

אפשר להוסיף עמודה בשורת הפקודה באמצעות Google Cloud CLI או באופן פרוגרמטי באמצעות ספריית הלקוח של Spanner ל-PHP.

בשורת הפקודה

כדי להוסיף את העמודה החדשה לטבלה, משתמשים בפקודה ALTER TABLE הבאה:

GoogleSQL

gcloud spanner databases ddl update example-db --instance=test-instance \
    --ddl='ALTER TABLE Albums ADD COLUMN MarketingBudget INT64'

PostgreSQL

gcloud spanner databases ddl update example-db --instance=test-instance \
    --ddl='ALTER TABLE Albums ADD COLUMN MarketingBudget BIGINT'

הפרטים שמוצגים הם:

Schema updating...done.

שימוש בספריית הלקוח של Spanner ל-PHP

משתמשים ב-Database::updateDdl כדי לשנות את הסכימה:

GoogleSQL

use Google\Cloud\Spanner\Admin\Database\V1\Client\DatabaseAdminClient;
use Google\Cloud\Spanner\Admin\Database\V1\UpdateDatabaseDdlRequest;

/**
 * Adds a new column to the Albums table in the example database.
 * Example:
 * ```
 * add_column($projectId, $instanceId, $databaseId);
 * ```
 *
 * @param string $projectId The Google Cloud project ID.
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function add_column(string $projectId, string $instanceId, string $databaseId): void
{
    $databaseAdminClient = new DatabaseAdminClient();
    $databaseName = DatabaseAdminClient::databaseName($projectId, $instanceId, $databaseId);

    $request = new UpdateDatabaseDdlRequest([
        'database' => $databaseName,
        'statements' => ['ALTER TABLE Albums ADD COLUMN MarketingBudget INT64']
    ]);

    $operation = $databaseAdminClient->updateDatabaseDdl($request);

    print('Waiting for operation to complete...' . PHP_EOL);
    $operation->pollUntilComplete();

    printf('Added the MarketingBudget column.' . PHP_EOL);
}

PostgreSQL

use Google\Cloud\Spanner\Admin\Database\V1\Client\DatabaseAdminClient;
use Google\Cloud\Spanner\Admin\Database\V1\UpdateDatabaseDdlRequest;

/**
 * Add a column to a table present in a PG Spanner database.
 *
 * @param string $projectId The Google Cloud project ID.
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function pg_add_column(string $projectId, string $instanceId, string $databaseId): void
{
    $databaseAdminClient = new DatabaseAdminClient();
    $databaseName = DatabaseAdminClient::databaseName($projectId, $instanceId, $databaseId);
    $statement = 'ALTER TABLE Albums ADD COLUMN MarketingBudget bigint';
    $request = new UpdateDatabaseDdlRequest([
        'database' => $databaseName,
        'statements' => [$statement]
    ]);

    $operation = $databaseAdminClient->updateDatabaseDdl($request);

    print('Waiting for operation to complete...' . PHP_EOL);
    $operation->pollUntilComplete();

    print('Added column MarketingBudget on table Albums' . PHP_EOL);
}

מריצים את הקובץ לדוגמה src/add_column.php.

php src/add_column.php test-instance example-db

הפרטים שמוצגים הם:

Added the MarketingBudget column.

כתיבת נתונים בעמודה החדשה

הקוד הבא כותב נתונים בעמודה החדשה. הפונקציה מגדירה את MarketingBudget ל-100000 בשורה עם מפתח Albums(1, 1), ול-500000 בשורה עם מפתח Albums(2, 2).

use Google\Cloud\Spanner\SpannerClient;

/**
 * Updates sample data in the database.
 *
 * This updates the `MarketingBudget` column which must be created before
 * running this sample. You can add the column by running the `add_column`
 * sample or by running this DDL statement against your database:
 *
 *     ALTER TABLE Albums ADD COLUMN MarketingBudget INT64
 *
 * Example:
 * ```
 * update_data($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function update_data(string $instanceId, string $databaseId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $operation = $database->transaction(['singleUse' => true])
        ->updateBatch('Albums', [
            ['SingerId' => 1, 'AlbumId' => 1, 'MarketingBudget' => 100000],
            ['SingerId' => 2, 'AlbumId' => 2, 'MarketingBudget' => 500000],
        ])
        ->commit();

    print('Updated data.' . PHP_EOL);
}

מריצים את הקובץ לדוגמה src/update_data.php.

php src/update_data.php test-instance example-db

הפרטים שמוצגים הם:

Updated data.

אפשר גם להריץ שאילתת SQL או קריאת נתונים כדי לאחזר את הערכים שזה עתה כתבתם.

הנה הקוד להרצת השאילתה:

use Google\Cloud\Spanner\SpannerClient;

/**
 * Queries sample data from the database using SQL.
 * This sample uses the `MarketingBudget` column. You can add the column
 * by running the `add_column` sample or by running this DDL statement against
 * your database:
 *
 *      ALTER TABLE Albums ADD COLUMN MarketingBudget INT64
 *
 * Example:
 * ```
 * query_data_with_new_column($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function query_data_with_new_column(string $instanceId, string $databaseId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $results = $database->execute(
        'SELECT SingerId, AlbumId, MarketingBudget FROM Albums'
    );

    foreach ($results as $row) {
        printf('SingerId: %s, AlbumId: %s, MarketingBudget: %d' . PHP_EOL,
            $row['SingerId'], $row['AlbumId'], $row['MarketingBudget']);
    }
}

כדי להריץ את השאילתה הזו, מריצים את קובץ הדוגמה src/query-data-with-new-column.php.

php src/query_data_with_new_column.php test-instance example-db

הפרטים שמוצגים הם:

SingerId: 1, AlbumId: 1, MarketingBudget: 100000
SingerId: 1, AlbumId: 2, MarketingBudget: 0
SingerId: 2, AlbumId: 1, MarketingBudget: 0
SingerId: 2, AlbumId: 2, MarketingBudget: 500000
SingerId: 2, AlbumId: 3, MarketingBudget: 0

עדכון נתונים

אפשר לעדכן נתונים באמצעות DML בעסקת קריאה-כתיבה.

משתמשים ב-executeUpdate() method כדי להריץ פקודת DML.

GoogleSQL

use Google\Cloud\Spanner\SpannerClient;
use Google\Cloud\Spanner\Transaction;

/**
 * Performs a read-write transaction to update two sample records in the
 * database.
 *
 * This will transfer 200,000 from the `MarketingBudget` field for the second
 * Album to the first Album. If the `MarketingBudget` for the second Album is
 * too low, it will raise an exception.
 *
 * Before running this sample, you will need to run the `update_data` sample
 * to populate the fields.
 * Example:
 * ```
 * write_data_with_dml_transaction($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function write_data_with_dml_transaction(string $instanceId, string $databaseId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $database->runTransaction(function (Transaction $t) {
        // Transfer marketing budget from one album to another. We do it in a transaction to
        // ensure that the transfer is atomic.
        $transferAmount = 200000;

        $results = $t->execute(
            'SELECT MarketingBudget from Albums WHERE SingerId = 2 and AlbumId = 2'
        );
        $resultsRow = $results->rows()->current();
        $album2budget = $resultsRow['MarketingBudget'];

        // Transaction will only be committed if this condition still holds at the time of
        // commit. Otherwise it will be aborted and the callable will be rerun by the
        // client library.
        if ($album2budget >= $transferAmount) {
            $results = $t->execute(
                'SELECT MarketingBudget from Albums WHERE SingerId = 1 and AlbumId = 1'
            );
            $resultsRow = $results->rows()->current();
            $album1budget = $resultsRow['MarketingBudget'];

            $album2budget -= $transferAmount;
            $album1budget += $transferAmount;

            // Update the albums
            $t->executeUpdate(
                'UPDATE Albums '
                . 'SET MarketingBudget = @AlbumBudget '
                . 'WHERE SingerId = 1 and AlbumId = 1',
                [
                    'parameters' => [
                        'AlbumBudget' => $album1budget
                    ]
                ]
            );
            $t->executeUpdate(
                'UPDATE Albums '
                . 'SET MarketingBudget = @AlbumBudget '
                . 'WHERE SingerId = 2 and AlbumId = 2',
                [
                    'parameters' => [
                        'AlbumBudget' => $album2budget
                    ]
                ]
            );

            $t->commit();

            print('Transaction complete.' . PHP_EOL);
        }
    });
}

PostgreSQL

use Google\Cloud\Spanner\SpannerClient;
use Google\Cloud\Spanner\Transaction;

/**
 *
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function pg_dml_getting_started_update(string $instanceId, string $databaseId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    // Transfer marketing budget from one album to another. We do it in a transaction to
    // ensure that the transfer is atomic.
    $database->runTransaction(function (Transaction $t) {
        $sql = 'SELECT marketingbudget as "MarketingBudget" from Albums WHERE '
        . 'SingerId = 2 and AlbumId = 2';

        $result = $t->execute($sql);
        $row = $result->rows()->current();
        $budgetAlbum2 = $row['MarketingBudget'];
        $transfer = 200000;

        // Transaction will only be committed if this condition still holds at the time of
        // commit. Otherwise it will be aborted.
        if ($budgetAlbum2 > $transfer) {
            $sql = 'SELECT marketingbudget as "MarketingBudget" from Albums WHERE '
            . 'SingerId = 1 and AlbumId = 1';
            $result = $t->execute($sql);
            $row = $result->rows()->current();
            $budgetAlbum1 = $row['MarketingBudget'];

            $budgetAlbum1 += $transfer;
            $budgetAlbum2 -= $transfer;

            $t->executeUpdateBatch([
                [
                    'sql' => 'UPDATE Albums '
                    . 'SET MarketingBudget = $1 '
                    . 'WHERE SingerId = 1 and AlbumId = 1',
                    [
                        'parameters' => [
                            'p1' => $budgetAlbum1
                        ]
                    ]
                ],
                [
                    'sql' => 'UPDATE Albums '
                    . 'SET MarketingBudget = $1 '
                    . 'WHERE SingerId = 2 and AlbumId = 2',
                    [
                        'parameters' => [
                            'p1' => $budgetAlbum2
                        ]
                    ]
                ],
            ]);
            $t->commit();

            print('Marketing budget updated.' . PHP_EOL);
        } else {
            $t->rollback();
        }
    });
}

מריצים את הקובץ לדוגמה src/write_data_with_dml_transaction.php.

php src/write_data_with_dml_transaction.php test-instance example-db

הפרטים שמוצגים הם:

Transaction complete.

שימוש באינדקס משני

נניח שרוצים לאחזר את כל השורות של Albums שיש להן ערכים של AlbumTitle בטווח מסוים. אפשר לקרוא את כל הערכים מהעמודה AlbumTitle באמצעות הצהרת SQL או קריאת קובץ, ואז להשליך את השורות שלא עומדות בקריטריונים. אבל סריקה מלאה של הטבלה היא פעולה יקרה, במיוחד בטבלאות עם הרבה שורות. במקום זאת, אפשר להאיץ את אחזור השורות כשמחפשים לפי עמודות שאינן מפתח ראשי, על ידי יצירת אינדקס משני בטבלה.

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

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

הוספת אינדקס משני

אפשר להוסיף אינדקס בשורת הפקודה באמצעות ה-CLI של gcloud או באופן פרוגרמטי באמצעות ספריית הלקוח של Spanner ל-PHP.

בשורת הפקודה

משתמשים בפקודה CREATE INDEX הבאה כדי להוסיף אינדקס למסד הנתונים:

gcloud spanner databases ddl update example-db --instance=test-instance \
    --ddl='CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)'

הפרטים שמוצגים הם:

Schema updating...done.

שימוש בספריית הלקוח של Spanner ל-PHP

כדי להוסיף אינדקס, משתמשים ב-Database::updateDdl:

use Google\Cloud\Spanner\Admin\Database\V1\Client\DatabaseAdminClient;
use Google\Cloud\Spanner\Admin\Database\V1\UpdateDatabaseDdlRequest;

/**
 * Adds a simple index to the example database.
 * Example:
 * ```
 * create_index($projectId, $instanceId, $databaseId);
 * ```
 *
 * @param string $projectId The Google Cloud project ID.
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function create_index(string $projectId, string $instanceId, string $databaseId): void
{
    $databaseAdminClient = new DatabaseAdminClient();
    $databaseName = DatabaseAdminClient::databaseName($projectId, $instanceId, $databaseId);
    $statement = 'CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)';
    $request = new UpdateDatabaseDdlRequest([
        'database' => $databaseName,
        'statements' => [$statement]
    ]);

    $operation = $databaseAdminClient->updateDatabaseDdl($request);

    print('Waiting for operation to complete...' . PHP_EOL);
    $operation->pollUntilComplete();

    printf('Added the AlbumsByAlbumTitle index.' . PHP_EOL);
}

מריצים את הקובץ לדוגמה src/create_index.php.

php src/create_index.php test-instance example-db

הוספת אינדקס יכולה להימשך כמה דקות. אחרי שמוסיפים את האינדקס, אמורים לראות:

Added the AlbumsByAlbumTitle index.

קריאה באמצעות האינדקס

בשאילתות SQL, ‏ Spanner משתמש באופן אוטומטי באינדקס מתאים. בממשק הקריאה, צריך לציין את האינדקס בבקשה.

כדי להשתמש באינדקס בממשק הקריאה, משתמשים בשיטה Database::read.

use Google\Cloud\Spanner\SpannerClient;

/**
 * Reads sample data from the database using an index.
 *
 * The index must exist before running this sample. You can add the index
 * by running the `add_index` sample or by running this DDL statement against
 * your database:
 *
 *     CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle)
 *
 * Example:
 * ```
 * read_data_with_index($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function read_data_with_index(string $instanceId, string $databaseId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $keySet = $spanner->keySet(['all' => true]);
    $results = $database->read(
        'Albums',
        $keySet,
        ['AlbumId', 'AlbumTitle'],
        ['index' => 'AlbumsByAlbumTitle']
    );

    foreach ($results->rows() as $row) {
        printf('AlbumId: %s, AlbumTitle: %s' . PHP_EOL,
            $row['AlbumId'], $row['AlbumTitle']);
    }
}

מריצים את הקובץ לדוגמה src/read_data_with_index.php.

php src/read_data_with_index.php test-instance example-db

הפרטים שמוצגים הם:

AlbumId: 2, AlbumTitle: Forever Hold your Peace
AlbumId: 2, AlbumTitle: Go, Go, Go
AlbumId: 1, AlbumTitle: Green
AlbumId: 3, AlbumTitle: Terrified
AlbumId: 1, AlbumTitle: Total Junk

הוספת אינדקס לקריאות של אינדקס בלבד

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

יוצרים הגדרה חלופית של AlbumsByAlbumTitle ששומרת עותק של MarketingBudget באינדקס.

בשורת הפקודה

GoogleSQL

gcloud spanner databases ddl update example-db --instance=test-instance \
    --ddl='CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) STORING (MarketingBudget)

PostgreSQL

gcloud spanner databases ddl update example-db --instance=test-instance \
    --ddl='CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) INCLUDE (MarketingBudget)

הוספת אינדקס יכולה להימשך כמה דקות. אחרי שמוסיפים את האינדקס, אמורים לראות:

Schema updating...done.

שימוש בספריית הלקוח של Spanner ל-PHP

משתמשים בפקודה Database::updateDdl כדי להוסיף אינדקס עם פסקה STORING:

use Google\Cloud\Spanner\Admin\Database\V1\Client\DatabaseAdminClient;
use Google\Cloud\Spanner\Admin\Database\V1\UpdateDatabaseDdlRequest;

/**
 * Adds an storing index to the example database.
 *
 * This sample uses the `MarketingBudget` column. You can add the column
 * by running the `add_column` sample or by running this DDL statement against
 * your database:
 *
 *     ALTER TABLE Albums ADD COLUMN MarketingBudget INT64
 *
 * Example:
 * ```
 * create_storing_index($projectId, $instanceId, $databaseId);
 * ```
 *
 * @param string $projectId The Google Cloud project ID.
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function create_storing_index(string $projectId, string $instanceId, string $databaseId): void
{
    $databaseAdminClient = new DatabaseAdminClient();
    $databaseName = DatabaseAdminClient::databaseName($projectId, $instanceId, $databaseId);
    $statement = 'CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle) ' .
        'STORING (MarketingBudget)';
    $request = new UpdateDatabaseDdlRequest([
        'database' => $databaseName,
        'statements' => [$statement]
    ]);

    $operation = $databaseAdminClient->updateDatabaseDdl($request);

    print('Waiting for operation to complete...' . PHP_EOL);
    $operation->pollUntilComplete();

    printf('Added the AlbumsByAlbumTitle2 index.' . PHP_EOL);
}

מריצים את הקובץ לדוגמה src/create_storing_index.php.

php src/create_storing_index.php test-instance example-db

הפרטים שמוצגים הם:

Added the AlbumsByAlbumTitle2 index.

עכשיו אפשר להריץ קריאה שמביאה את כל העמודות AlbumId, AlbumTitle ו-MarketingBudget מהאינדקס AlbumsByAlbumTitle2:

use Google\Cloud\Spanner\SpannerClient;

/**
 * Reads sample data from the database using an index with a storing
 * clause.
 *
 * The index must exist before running this sample. You can add the index
 * by running the `add_storing_index` sample or by running this DDL statement
 * against your database:
 *
 *     CREATE INDEX AlbumsByAlbumTitle2 ON Albums(AlbumTitle)
 *     STORING (MarketingBudget)
 *
 * Example:
 * ```
 * read_data_with_storing_index($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function read_data_with_storing_index(string $instanceId, string $databaseId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $keySet = $spanner->keySet(['all' => true]);
    $results = $database->read(
        'Albums',
        $keySet,
        ['AlbumId', 'AlbumTitle', 'MarketingBudget'],
        ['index' => 'AlbumsByAlbumTitle2']
    );

    foreach ($results->rows() as $row) {
        printf('AlbumId: %s, AlbumTitle: %s, MarketingBudget: %d' . PHP_EOL,
            $row['AlbumId'], $row['AlbumTitle'], $row['MarketingBudget']);
    }
}

מריצים את הקובץ לדוגמה src/read_data_with_storing_index.php.

php src/read_data_with_storing_index.php test-instance example-db

הפלט אמור להיראות כך:

AlbumId: 2, AlbumTitle: Forever Hold your Peace, MarketingBudget: 300000
AlbumId: 2, AlbumTitle: Go, Go, Go, MarketingBudget: 0
AlbumId: 1, AlbumTitle: Green, MarketingBudget: 0
AlbumId: 3, AlbumTitle: Terrified, MarketingBudget: 0
AlbumId: 1, AlbumTitle: Total Junk, MarketingBudget: 300000

אחזור נתונים באמצעות טרנזקציות לקריאה בלבד

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

בדוגמה הבאה מוצג איך להריץ שאילתה ולבצע קריאה באותה טרנזקציה לקריאה בלבד:

use Google\Cloud\Spanner\SpannerClient;

/**
 * Reads data inside of a read-only transaction.
 *
 * Within the read-only transaction, or "snapshot", the application sees
 * consistent view of the database at a particular timestamp.
 * Example:
 * ```
 * read_only_transaction($instanceId, $databaseId);
 * ```
 *
 * @param string $instanceId The Spanner instance ID.
 * @param string $databaseId The Spanner database ID.
 */
function read_only_transaction(string $instanceId, string $databaseId): void
{
    $spanner = new SpannerClient();
    $instance = $spanner->instance($instanceId);
    $database = $instance->database($databaseId);

    $snapshot = $database->snapshot();
    $results = $snapshot->execute(
        'SELECT SingerId, AlbumId, AlbumTitle FROM Albums'
    );
    print('Results from the first read:' . PHP_EOL);
    foreach ($results as $row) {
        printf('SingerId: %s, AlbumId: %s, AlbumTitle: %s' . PHP_EOL,
            $row['SingerId'], $row['AlbumId'], $row['AlbumTitle']);
    }

    // Perform another read using the `read` method. Even if the data
    // is updated in-between the reads, the snapshot ensures that both
    // return the same data.
    $keySet = $spanner->keySet(['all' => true]);
    $results = $database->read(
        'Albums',
        $keySet,
        ['SingerId', 'AlbumId', 'AlbumTitle']
    );

    print('Results from the second read:' . PHP_EOL);
    foreach ($results->rows() as $row) {
        printf('SingerId: %s, AlbumId: %s, AlbumTitle: %s' . PHP_EOL,
            $row['SingerId'], $row['AlbumId'], $row['AlbumTitle']);
    }
}

מריצים את הקובץ לדוגמה src/read_only_transaction.php.

php src/read_only_transaction.php test-instance example-db

הפלט אמור להיראות כך:

Results from first read:
SingerId: 2, AlbumId: 2, AlbumTitle: Forever Hold Your Peace
SingerId: 1, AlbumId: 2, AlbumTitle: Go, Go, Go
SingerId: 2, AlbumId: 1, AlbumTitle: Green
SingerId: 2, AlbumId: 3, AlbumTitle: Terrified
SingerId: 1, AlbumId: 1, AlbumTitle: Total Junk
Results from second read:
SingerId: 1, AlbumId: 1, AlbumTitle: Total Junk
SingerId: 1, AlbumId: 2, AlbumTitle: Go, Go, Go
SingerId: 2, AlbumId: 1, AlbumTitle: Green
SingerId: 2, AlbumId: 2, AlbumTitle: Forever Hold Your Peace
SingerId: 2, AlbumId: 3, AlbumTitle: Terrified

הסרת המשאבים

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

מחיקת מסד הנתונים

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

בשורת הפקודה

gcloud spanner databases delete example-db --instance=test-instance

שימוש במסוף Google Cloud

  1. נכנסים לדף Spanner Instances במסוף Google Cloud .

    כניסה לדף Instances

  2. לוחצים על המופע.

  3. לוחצים על מסד הנתונים שרוצים למחוק.

  4. בדף פרטי מסד הנתונים, לוחצים על מחיקה.

  5. מאשרים שרוצים למחוק את מסד הנתונים ולוחצים על מחיקה.

מחיקת המכונה

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

בשורת הפקודה

gcloud spanner instances delete test-instance

שימוש במסוף Google Cloud

  1. נכנסים לדף Spanner Instances במסוף Google Cloud .

    כניסה לדף Instances

  2. לוחצים על המופע.

  3. לוחצים על Delete.

  4. מאשרים שרוצים למחוק את המופע ולוחצים על מחיקה.

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