1. ภาพรวม
Google Cloud Spanner เป็นบริการฐานข้อมูลเชิงสัมพันธ์ที่มีการจัดการครบวงจรซึ่งปรับขนาดในแนวนอนได้ กระจายอยู่ทั่วโลก และมอบธุรกรรม ACID และความหมายของ SQL โดยไม่ลดทอนประสิทธิภาพและความพร้อมใช้งานสูง
ในแล็บนี้ คุณจะได้เรียนรู้วิธีตั้งค่าอินสแตนซ์ Cloud Spanner คุณจะได้ดูขั้นตอนการสร้างฐานข้อมูลและสคีมาที่ใช้กับลีดเดอร์บอร์ดเกมได้ คุณจะเริ่มต้นด้วยการสร้างตารางผู้เล่นเพื่อจัดเก็บข้อมูลผู้เล่น และตารางคะแนนเพื่อจัดเก็บคะแนนของผู้เล่น
จากนั้นคุณจะป้อนข้อมูลตัวอย่างลงในตาราง จากนั้นคุณจะสรุปแล็บด้วยการเรียกใช้ตัวอย่างคำค้นหายอดนิยม 10 อันดับ และสุดท้ายคือลบอินสแตนซ์เพื่อเพิ่มพื้นที่ว่างสำหรับทรัพยากร
สิ่งที่คุณจะได้เรียนรู้
- วิธีตั้งค่าอินสแตนซ์ Cloud Spanner
- วิธีสร้างฐานข้อมูลและตาราง
- วิธีใช้คอลัมน์การประทับเวลาการคอมมิต
- วิธีโหลดข้อมูลลงในตารางฐานข้อมูล Cloud Spanner ที่มีแสตมป์เวลา
- วิธีค้นหาฐานข้อมูล Cloud Spanner
- วิธียกเลิกอินสแตนซ์ Cloud Spanner
สิ่งที่คุณ ต้องมี
คุณจะใช้บทแนะนำนี้อย่างไร
คุณจะให้คะแนนประสบการณ์การใช้งาน Google Cloud Platform เท่าไร
2. การตั้งค่าและข้อกำหนด
การตั้งค่าสภาพแวดล้อมแบบเรียนรู้ด้วยตนเอง
หากยังไม่มีบัญชี Google (Gmail หรือ Google Apps) คุณต้องสร้างบัญชี ลงชื่อเข้าใช้คอนโซล Google Cloud Platform ( console.cloud.google.com) แล้วสร้างโปรเจ็กต์ใหม่
หากมีโปรเจ็กต์อยู่แล้ว ให้คลิกเมนูแบบเลื่อนลงเพื่อเลือกโปรเจ็กต์ที่ด้านซ้ายบนของคอนโซล

แล้วคลิกปุ่ม "โปรเจ็กต์ใหม่" ในกล่องโต้ตอบที่ปรากฏขึ้นเพื่อสร้างโปรเจ็กต์ใหม่

หากยังไม่มีโปรเจ็กต์ คุณจะเห็นกล่องโต้ตอบแบบนี้เพื่อสร้างโปรเจ็กต์แรก

กล่องโต้ตอบการสร้างโปรเจ็กต์ในภายหลังจะช่วยให้คุณป้อนรายละเอียดของโปรเจ็กต์ใหม่ได้

โปรดจดจำรหัสโปรเจ็กต์ ซึ่งเป็นชื่อที่ไม่ซ้ำกันในโปรเจ็กต์ Google Cloud ทั้งหมด (ชื่อด้านบนมีผู้ใช้แล้วและจะใช้ไม่ได้ ขออภัย) ซึ่งจะเรียกว่า PROJECT_ID ในภายหลังใน Codelab นี้
จากนั้น หากยังไม่ได้ดำเนินการ คุณจะต้องเปิดใช้การเรียกเก็บเงินใน Developers Console เพื่อใช้ทรัพยากร Google Cloud และเปิดใช้ Cloud Spanner API

การทำตาม Codelab นี้ไม่ควรมีค่าใช้จ่ายเกิน 2-3 ดอลลาร์ แต่ก็อาจมีค่าใช้จ่ายมากกว่านี้หากคุณตัดสินใจใช้ทรัพยากรเพิ่มเติมหรือปล่อยให้ทรัพยากรทำงานต่อไป (ดูส่วน "การล้างข้อมูล" ที่ท้ายเอกสารนี้) ดูเอกสารประกอบเกี่ยวกับการกำหนดราคาของ Google Cloud Spanner ได้ที่นี่
ผู้ใช้ใหม่ของ Google Cloud Platform มีสิทธิ์รับช่วงทดลองใช้ฟรีมูลค่า$300 ซึ่งจะทำให้ Codelab นี้ไม่มีค่าใช้จ่ายใดๆ
การตั้งค่า Google Cloud Shell
แม้ว่าคุณจะใช้งาน Google Cloud และ Spanner จากแล็ปท็อประยะไกลได้ แต่ใน Codelab นี้เราจะใช้ Google Cloud Shell ซึ่งเป็นสภาพแวดล้อมบรรทัดคำสั่งที่ทำงานในระบบคลาวด์
เครื่องเสมือนที่ใช้ Debian นี้มาพร้อมเครื่องมือพัฒนาทั้งหมดที่คุณต้องการ โดยมีไดเรกทอรีหลักแบบถาวรขนาด 5 GB และทำงานใน Google Cloud ซึ่งช่วยเพิ่มประสิทธิภาพเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก ซึ่งหมายความว่าคุณจะต้องมีเพียงเบราว์เซอร์เท่านั้นสำหรับโค้ดแล็บนี้ (ใช่แล้ว ใช้ได้ใน Chromebook)
- หากต้องการเปิดใช้งาน Cloud Shell จาก Cloud Console เพียงคลิกเปิดใช้งาน Cloud Shell
(ระบบจะใช้เวลาเพียงไม่กี่นาทีในการจัดสรรและเชื่อมต่อกับสภาพแวดล้อม)
เมื่อเชื่อมต่อกับ Cloud Shell แล้ว คุณควรเห็นว่าระบบได้ตรวจสอบสิทธิ์คุณแล้ว และตั้งค่าโปรเจ็กต์เป็น PROJECT_ID แล้ว
gcloud auth list
เอาต์พุตของคำสั่ง
Credentialed accounts: - <myaccount>@<mydomain>.com (active)
gcloud config list project
เอาต์พุตของคำสั่ง
[core] project = <PROJECT_ID>
หากไม่ได้ตั้งค่าโปรเจ็กต์ด้วยเหตุผลบางประการ ให้เรียกใช้คำสั่งต่อไปนี้
gcloud config set project <PROJECT_ID>
หากกำลังมองหา PROJECT_ID ตรวจสอบว่าคุณใช้รหัสใดในขั้นตอนการตั้งค่า หรือค้นหารหัสในแดชบอร์ด Cloud Console
นอกจากนี้ Cloud Shell ยังตั้งค่าตัวแปรสภาพแวดล้อมบางอย่างโดยค่าเริ่มต้น ซึ่งอาจมีประโยชน์เมื่อคุณเรียกใช้คำสั่งในอนาคต
echo $GOOGLE_CLOUD_PROJECT
เอาต์พุตของคำสั่ง
<PROJECT_ID>
- สุดท้าย ให้ตั้งค่าโซนเริ่มต้นและการกำหนดค่าโปรเจ็กต์
gcloud config set compute/zone us-central1-f
คุณเลือกโซนต่างๆ ได้หลากหลาย ดูข้อมูลเพิ่มเติมได้ที่ภูมิภาคและโซน
สรุป
ในขั้นตอนนี้ คุณจะได้ตั้งค่าสภาพแวดล้อม
ถัดไป
จากนั้นคุณจะตั้งค่าอินสแตนซ์ Cloud Spanner
3. ตั้งค่าอินสแตนซ์ Cloud Spanner
ในขั้นตอนนี้ เราจะตั้งค่าอินสแตนซ์ Cloud Spanner สำหรับ Codelab นี้ ค้นหารายการ Spanner
ในเมนูแฮมเบอร์เกอร์ด้านซ้ายบน
หรือค้นหา Spanner โดยกด "/" แล้วพิมพ์ "Spanner"

จากนั้นคลิก
แล้วกรอกแบบฟอร์มโดยป้อนชื่ออินสแตนซ์ cloudspanner-leaderboard สำหรับอินสแตนซ์ เลือกการกำหนดค่า (เลือกอินสแตนซ์ระดับภูมิภาค) และตั้งค่าจำนวนโหนด สำหรับ Codelab นี้ เราต้องการเพียง 1 โหนด สำหรับอินสแตนซ์ที่ใช้งานจริงและเพื่อให้มีสิทธิ์รับ SLA ของ Cloud Spanner คุณจะต้องเรียกใช้โหนดอย่างน้อย 3 โหนดในอินสแตนซ์ Cloud Spanner
สุดท้าย ให้คลิก "สร้าง" แล้วคุณจะมีอินสแตนซ์ Cloud Spanner พร้อมใช้งานภายในไม่กี่วินาที

ในขั้นตอนถัดไป เราจะใช้ไลบรารีของไคลเอ็นต์ C# เพื่อสร้างฐานข้อมูลและสคีมาในอินสแตนซ์ใหม่
4. สร้างฐานข้อมูลและสคีมา
ในขั้นตอนนี้ เราจะสร้างฐานข้อมูลและสคีมาตัวอย่าง
มาใช้ไลบรารีไคลเอ็นต์ C# เพื่อสร้างตาราง 2 ตารางกัน ตาราง Players สำหรับข้อมูลผู้เล่น และตาราง Scores สำหรับจัดเก็บคะแนนของผู้เล่น เราจะทำสิ่งนี้โดยดูขั้นตอนการสร้างแอปพลิเคชันคอนโซล C# ใน Cloud Shell
ก่อนอื่นให้โคลนโค้ดตัวอย่างสำหรับ Codelab นี้จาก Github โดยพิมพ์คำสั่งต่อไปนี้ใน Cloud Shell
git clone https://github.com/GoogleCloudPlatform/dotnet-docs-samples.git
จากนั้นเปลี่ยนไดเรกทอรีเป็นไดเรกทอรี "applications" ที่คุณจะสร้างแอปพลิเคชัน
cd dotnet-docs-samples/applications/
โค้ดทั้งหมดที่จำเป็นสำหรับ Codelab นี้อยู่ในไดเรกทอรี dotnet-docs-samples/applications/leaderboard ที่มีอยู่แล้วในรูปแบบแอปพลิเคชัน C# ที่เรียกใช้ได้ชื่อ Leaderboard เพื่อใช้เป็นข้อมูลอ้างอิงขณะที่คุณทำตาม Codelab เราจะสร้างไดเรกทอรีใหม่และสร้างสำเนาแอปพลิเคชันลีดเดอร์บอร์ดเป็นระยะๆ
สร้างไดเรกทอรีใหม่ชื่อ "codelab" สำหรับแอปพลิเคชัน แล้วเปลี่ยนไดเรกทอรีเป็นไดเรกทอรีดังกล่าวด้วยคำสั่งต่อไปนี้
mkdir codelab && cd $_
สร้างแอปพลิเคชันคอนโซล .NET C# ใหม่ชื่อ "ลีดเดอร์บอร์ด" โดยใช้คำสั่งต่อไปนี้
dotnet new console -n Leaderboard
คำสั่งนี้จะสร้างแอปพลิเคชันคอนโซลอย่างง่ายซึ่งประกอบด้วยไฟล์หลัก 2 ไฟล์ ได้แก่ ไฟล์โปรเจ็กต์ Leaderboard.csproj และไฟล์โปรแกรม Program.cs
มาเริ่มกันเลย เปลี่ยนไดเรกทอรีเป็นไดเรกทอลีดเดอร์บอร์ดที่สร้างขึ้นใหม่ซึ่งแอปพลิเคชันอยู่
cd Leaderboard
จากนั้นป้อนคำสั่งต่อไปนี้เพื่อเรียกใช้
dotnet run
คุณควรเห็นเอาต์พุตของแอปพลิเคชันเป็น "Hello World!"
ตอนนี้มาอัปเดตแอปคอนโซลโดยแก้ไข Program.cs เพื่อใช้ไลบรารีไคลเอ็นต์ Spanner ของ C# เพื่อสร้างลีดเดอร์บอร์ดที่ประกอบด้วยตาราง 2 ตาราง ได้แก่ Players และ Scores คุณทำได้ใน Cloud Shell Editor โดยทำดังนี้
เปิด Cloud Shell Editor โดยคลิกไอคอนที่ไฮไลต์ด้านล่าง

จากนั้นเปิดไฟล์ Program.cs ใน Cloud Shell Editor แล้วแทนที่โค้ดที่มีอยู่ของไฟล์ด้วยโค้ดที่จำเป็นในการสร้างฐานข้อมูล leaderboard และตาราง Players กับ Scores โดยวางโค้ดแอปพลิเคชัน C# ต่อไปนี้ลงในไฟล์ Program.cs
using System;
using System.Threading.Tasks;
using Google.Cloud.Spanner.Data;
using CommandLine;
namespace GoogleCloudSamples.Leaderboard
{
[Verb("create", HelpText = "Create a sample Cloud Spanner database "
+ "along with sample 'Players' and 'Scores' tables in your project.")]
class CreateOptions
{
[Value(0, HelpText = "The project ID of the project to use "
+ "when creating Cloud Spanner resources.", Required = true)]
public string projectId { get; set; }
[Value(1, HelpText = "The ID of the instance where the sample database "
+ "will be created.", Required = true)]
public string instanceId { get; set; }
[Value(2, HelpText = "The ID of the sample database to create.",
Required = true)]
public string databaseId { get; set; }
}
public class Program
{
enum ExitCode : int
{
Success = 0,
InvalidParameter = 1,
}
public static object Create(string projectId,
string instanceId, string databaseId)
{
var response =
CreateAsync(projectId, instanceId, databaseId);
Console.WriteLine("Waiting for operation to complete...");
response.Wait();
Console.WriteLine($"Operation status: {response.Status}");
Console.WriteLine($"Created sample database {databaseId} on "
+ $"instance {instanceId}");
return ExitCode.Success;
}
public static async Task CreateAsync(
string projectId, string instanceId, string databaseId)
{
// Initialize request connection string for database creation.
string connectionString =
$"Data Source=projects/{projectId}/instances/{instanceId}";
using (var connection = new SpannerConnection(connectionString))
{
string createStatement = $"CREATE DATABASE `{databaseId}`";
string[] createTableStatements = new string[] {
// Define create table statement for Players table.
@"CREATE TABLE Players(
PlayerId INT64 NOT NULL,
PlayerName STRING(2048) NOT NULL
) PRIMARY KEY(PlayerId)",
// Define create table statement for Scores table.
@"CREATE TABLE Scores(
PlayerId INT64 NOT NULL,
Score INT64 NOT NULL,
Timestamp TIMESTAMP NOT NULL OPTIONS(allow_commit_timestamp=true)
) PRIMARY KEY(PlayerId, Timestamp),
INTERLEAVE IN PARENT Players ON DELETE NO ACTION" };
// Make the request.
var cmd = connection.CreateDdlCommand(
createStatement, createTableStatements);
try
{
await cmd.ExecuteNonQueryAsync();
}
catch (SpannerException e) when
(e.ErrorCode == ErrorCode.AlreadyExists)
{
// OK.
}
}
}
public static int Main(string[] args)
{
var verbMap = new VerbMap<object>();
verbMap
.Add((CreateOptions opts) => Create(
opts.projectId, opts.instanceId, opts.databaseId))
.NotParsedFunc = (err) => 1;
return (int)verbMap.Run(args);
}
}
}
เพื่อให้เห็นภาพโค้ดโปรแกรมได้ชัดเจนยิ่งขึ้น นี่คือแผนภาพของโปรแกรมที่มีการติดป้ายกำกับคอมโพเนนต์หลัก

คุณใช้ไฟล์ Program.cs ในไดเรกทอรี dotnet-docs-samples/applications/leaderboard/step4 เพื่อดูตัวอย่างลักษณะของไฟล์ Program.cs หลังจากเพิ่มโค้ดเพื่อเปิดใช้คำสั่ง create แล้วได้
จากนั้นใช้ Cloud Shell Editor เพื่อเปิดและแก้ไขไฟล์โปรเจ็กต์ของโปรแกรม Leaderboard.csproj โดยอัปเดตให้มีลักษณะเหมือนโค้ดต่อไปนี้ โปรดตรวจสอบว่าได้บันทึกการเปลี่ยนแปลงทั้งหมดโดยใช้เมนู "ไฟล์" ของ Cloud Shell Editor
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Cloud.Spanner.Data" Version="3.3.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\commandlineutil\Lib\CommandLineUtil.csproj" />
</ItemGroup>
</Project>
การเปลี่ยนแปลงนี้ได้เพิ่มข้อมูลอ้างอิงไปยังแพ็กเกจ C# Spanner Nuget Google.Cloud.Spanner.Data ที่เราต้องใช้เพื่อโต้ตอบกับ Cloud Spanner API การเปลี่ยนแปลงนี้ยังเพิ่มการอ้างอิงถึงโปรเจ็กต์ CommandLineUtil ซึ่งเป็นส่วนหนึ่งของที่เก็บ dotnet-doc-samples ใน Github และมีส่วนขยาย "verbmap" ที่มีประโยชน์สำหรับ CommandLineParser แบบโอเพนซอร์ส ซึ่งเป็นไลบรารีที่มีประโยชน์สำหรับการจัดการอินพุตบรรทัดคำสั่งสำหรับแอปพลิเคชันคอนโซล
คุณใช้ไฟล์ Leaderboard.csproj ในไดเรกทอรี dotnet-docs-samples/applications/leaderboard/step4 เพื่อดูตัวอย่างลักษณะของไฟล์ Leaderboard.csproj หลังจากเพิ่มโค้ดเพื่อเปิดใช้คำสั่ง create แล้วได้
ตอนนี้คุณพร้อมที่จะเรียกใช้ตัวอย่างที่อัปเดตแล้ว พิมพ์ข้อความต่อไปนี้เพื่อดูคำตอบเริ่มต้นของแอปพลิเคชันที่อัปเดตแล้ว
dotnet run
คุณควรเห็นเอาต์พุตดังต่อไปนี้
Leaderboard 1.0.0 Copyright (C) 2018 Leaderboard ERROR(S): No verb selected. create Create a sample Cloud Spanner database along with sample 'Players' and 'Scores' tables in your project. help Display more information on a specific command. version Display version information.
จากคำตอบนี้ เราจะเห็นว่านี่คือแอปพลิเคชัน Leaderboard ซึ่งสามารถเรียกใช้ด้วยคำสั่งที่เป็นไปได้ 3 คำสั่ง ได้แก่ create, help และ version
มาลองใช้คำสั่ง create เพื่อสร้างฐานข้อมูลและตาราง Spanner กัน เรียกใช้คำสั่งโดยไม่มีอาร์กิวเมนต์เพื่อดูอาร์กิวเมนต์ที่คาดไว้ของคำสั่ง
dotnet run create
คุณควรเห็นคำตอบที่มีลักษณะดังนี้
Leaderboard 1.0.0 Copyright (C) 2018 Leaderboard ERROR(S): A required value not bound to option name is missing. --help Display this help screen. --version Display version information. value pos. 0 Required. The project ID of the project to use when creating Cloud Spanner resources. value pos. 1 Required. The ID of the instance where the sample database will be created. value pos. 2 Required. The ID of the sample database to create.
ในที่นี้ เราจะเห็นว่าอาร์กิวเมนต์ที่คาดไว้ของคำสั่ง create คือรหัสโปรเจ็กต์ รหัสอินสแตนซ์ และรหัสฐานข้อมูล
ตอนนี้ให้เรียกใช้คำสั่งต่อไปนี้ ตรวจสอบว่าคุณได้แทนที่ PROJECT_ID ด้วยรหัสโปรเจ็กต์ที่สร้างไว้ตอนต้นของโค้ดแล็บนี้
dotnet run create PROJECT_ID cloudspanner-leaderboard leaderboard
หลังจากผ่านไป 2-3 วินาที คุณควรเห็นการตอบกลับดังต่อไปนี้
Waiting for operation to complete... Operation status: RanToCompletion Created sample database leaderboard on instance cloudspanner-leaderboard
ในส่วน Cloud Spanner ของ Cloud Console คุณควรเห็นฐานข้อมูลและตารางใหม่ปรากฏในเมนูด้านซ้าย

ในขั้นตอนถัดไป เราจะอัปเดตแอปพลิเคชันเพื่อโหลดข้อมูลบางอย่างลงในฐานข้อมูลใหม่
5. โหลดข้อมูล
ตอนนี้เรามีฐานข้อมูลชื่อ leaderboard ซึ่งมี 2 ตาราง ได้แก่ Players และ Scores ตอนนี้เรามาใช้ไลบรารีไคลเอ็นต์ C# เพื่อป้อนข้อมูลตาราง Players ด้วยผู้เล่น และตาราง Scores ด้วยคะแนนแบบสุ่มสำหรับผู้เล่นแต่ละคนกัน
เปิด Cloud Shell Editor โดยคลิกไอคอนที่ไฮไลต์ด้านล่าง

จากนั้นแก้ไขไฟล์ Program.cs ใน Cloud Shell Editor เพื่อเพิ่มคำสั่ง insert ที่ใช้เพื่อแทรกผู้เล่น 100 คนลงในตาราง Players หรือใช้เพื่อแทรกคะแนนแบบสุ่ม 4 รายการในตาราง Scores สำหรับผู้เล่นแต่ละคนในตาราง Players
ก่อนอื่นให้เพิ่มบล็อกคำสั่ง insert ใหม่ใน "Verbmap" ที่ด้านบนของโปรแกรมใต้บล็อกคำสั่ง create ที่มีอยู่
[Verb("insert", HelpText = "Insert sample 'players' records or 'scores' records "
+ "into the database.")]
class InsertOptions
{
[Value(0, HelpText = "The project ID of the project to use "
+ "when managing Cloud Spanner resources.", Required = true)]
public string projectId { get; set; }
[Value(1, HelpText = "The ID of the instance where the sample database resides.",
Required = true)]
public string instanceId { get; set; }
[Value(2, HelpText = "The ID of the database where the sample database resides.",
Required = true)]
public string databaseId { get; set; }
[Value(3, HelpText = "The type of insert to perform, 'players' or 'scores'.",
Required = true)]
public string insertType { get; set; }
}
จากนั้นเพิ่มวิธีการ Insert, InsertPlayersAsync และ InsertScoresAsync ต่อไปนี้ใต้เมธอด CreateAsync ที่มีอยู่
public static object Insert(string projectId,
string instanceId, string databaseId, string insertType)
{
if (insertType.ToLower() == "players")
{
var responseTask =
InsertPlayersAsync(projectId, instanceId, databaseId);
Console.WriteLine("Waiting for insert players operation to complete...");
responseTask.Wait();
Console.WriteLine($"Operation status: {responseTask.Status}");
}
else if (insertType.ToLower() == "scores")
{
var responseTask =
InsertScoresAsync(projectId, instanceId, databaseId);
Console.WriteLine("Waiting for insert scores operation to complete...");
responseTask.Wait();
Console.WriteLine($"Operation status: {responseTask.Status}");
}
else
{
Console.WriteLine("Invalid value for 'type of insert'. "
+ "Specify 'players' or 'scores'.");
return ExitCode.InvalidParameter;
}
Console.WriteLine($"Inserted {insertType} into sample database "
+ $"{databaseId} on instance {instanceId}");
return ExitCode.Success;
}
public static async Task InsertPlayersAsync(string projectId,
string instanceId, string databaseId)
{
string connectionString =
$"Data Source=projects/{projectId}/instances/{instanceId}"
+ $"/databases/{databaseId}";
long numberOfPlayers = 0;
using (var connection = new SpannerConnection(connectionString))
{
await connection.OpenAsync();
await connection.RunWithRetriableTransactionAsync(async (transaction) =>
{
// Execute a SQL statement to get current number of records
// in the Players table to use as an incrementing value
// for each PlayerName to be inserted.
var cmd = connection.CreateSelectCommand(
@"SELECT Count(PlayerId) as PlayerCount FROM Players");
numberOfPlayers = await cmd.ExecuteScalarAsync<long>();
// Insert 100 player records into the Players table.
SpannerBatchCommand cmdBatch = connection.CreateBatchDmlCommand();
for (int i = 0; i < 100; i++)
{
numberOfPlayers++;
SpannerCommand cmdInsert = connection.CreateDmlCommand(
"INSERT INTO Players "
+ "(PlayerId, PlayerName) "
+ "VALUES (@PlayerId, @PlayerName)",
new SpannerParameterCollection {
{"PlayerId", SpannerDbType.Int64},
{"PlayerName", SpannerDbType.String}});
cmdInsert.Parameters["PlayerId"].Value =
Math.Abs(Guid.NewGuid().GetHashCode());
cmdInsert.Parameters["PlayerName"].Value =
$"Player {numberOfPlayers}";
cmdBatch.Add(cmdInsert);
}
await cmdBatch.ExecuteNonQueryAsync();
});
}
Console.WriteLine("Done inserting player records...");
}
public static async Task InsertScoresAsync(
string projectId, string instanceId, string databaseId)
{
string connectionString =
$"Data Source=projects/{projectId}/instances/{instanceId}"
+ $"/databases/{databaseId}";
// Insert 4 score records into the Scores table for each player
// in the Players table.
using (var connection = new SpannerConnection(connectionString))
{
await connection.OpenAsync();
await connection.RunWithRetriableTransactionAsync(async (transaction) =>
{
Random r = new Random();
bool playerRecordsFound = false;
SpannerBatchCommand cmdBatch =
connection.CreateBatchDmlCommand();
var cmdLookup =
connection.CreateSelectCommand("SELECT * FROM Players");
using (var reader = await cmdLookup.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
{
playerRecordsFound = true;
for (int i = 0; i < 4; i++)
{
DateTime randomTimestamp = DateTime.Now
.AddYears(r.Next(-2, 1))
.AddMonths(r.Next(-12, 1))
.AddDays(r.Next(-28, 0))
.AddHours(r.Next(-24, 0))
.AddSeconds(r.Next(-60, 0))
.AddMilliseconds(r.Next(-100000, 0));
SpannerCommand cmdInsert =
connection.CreateDmlCommand(
"INSERT INTO Scores "
+ "(PlayerId, Score, Timestamp) "
+ "VALUES (@PlayerId, @Score, @Timestamp)",
new SpannerParameterCollection {
{"PlayerId", SpannerDbType.Int64},
{"Score", SpannerDbType.Int64},
{"Timestamp",
SpannerDbType.Timestamp}});
cmdInsert.Parameters["PlayerId"].Value =
reader.GetFieldValue<int>("PlayerId");
cmdInsert.Parameters["Score"].Value =
r.Next(1000, 1000001);
cmdInsert.Parameters["Timestamp"].Value =
randomTimestamp.ToString("o");
cmdBatch.Add(cmdInsert);
}
}
if (!playerRecordsFound)
{
Console.WriteLine("Parameter 'scores' is invalid "
+ "since no player records currently exist. First "
+ "insert players then insert scores.");
Environment.Exit((int)ExitCode.InvalidParameter);
}
else
{
await cmdBatch.ExecuteNonQueryAsync();
Console.WriteLine(
"Done inserting score records..."
);
}
}
});
}
}
จากนั้นเพิ่มโค้ดต่อไปนี้ลงในเมธอด "Main" ของโปรแกรมเพื่อให้คำสั่ง insert ทำงานได้
.Add((InsertOptions opts) => Insert(
opts.projectId, opts.instanceId, opts.databaseId, opts.insertType))
คุณใช้ไฟล์ Program.cs ในไดเรกทอรี dotnet-docs-samples/applications/leaderboard/step5 เพื่อดูตัวอย่างลักษณะของไฟล์ Program.cs หลังจากเพิ่มโค้ดเพื่อเปิดใช้คำสั่ง insert แล้วได้
ตอนนี้เรามาเรียกใช้โปรแกรมเพื่อยืนยันว่าคำสั่ง insert ใหม่รวมอยู่ในรายการคำสั่งที่เป็นไปได้ของโปรแกรม เรียกใช้คำสั่งต่อไปนี้
dotnet run
ตอนนี้คุณควรเห็นคำสั่ง insert รวมอยู่ในเอาต์พุตเริ่มต้นของโปรแกรมแล้ว
Leaderboard 1.0.0 Copyright (C) 2018 Leaderboard ERROR(S): No verb selected. create Create a sample Cloud Spanner database along with sample 'Players' and 'Scores' tables in your project. insert Insert sample 'players' records or 'scores' records into the database. help Display more information on a specific command. version Display version information.
ตอนนี้มาเรียกใช้คำสั่ง insert เพื่อดูอาร์กิวเมนต์อินพุตกัน ป้อนคำสั่งต่อไปนี้
dotnet run insert
ซึ่งควรแสดงการตอบกลับต่อไปนี้
Leaderboard 1.0.0 Copyright (C) 2018 Leaderboard ERROR(S): A required value not bound to option name is missing. --help Display this help screen. --version Display version information. value pos. 0 Required. The project ID of the project to use when managing Cloud Spanner resources. value pos. 1 Required. The ID of the instance where the sample database resides. value pos. 2 Required. The ID of the database where the sample database resides. value pos. 3 Required. The type of insert to perform, 'players' or 'scores'.
คุณจะเห็นจากการตอบกลับว่านอกจากรหัสโปรเจ็กต์ รหัสอินสแตนซ์ และรหัสฐานข้อมูลแล้ว ยังมีอาร์กิวเมนต์อีกรายการหนึ่งที่value pos. 3คาดไว้ ซึ่งก็คือ "ประเภทการแทรก" ที่จะดำเนินการ อาร์กิวเมนต์นี้อาจมีค่าเป็น "players" หรือ "scores"
ตอนนี้มาเรียกใช้คำสั่ง insert โดยใช้ค่าอาร์กิวเมนต์เดียวกันกับที่เราใช้เมื่อเรียกใช้คำสั่ง create โดยเพิ่ม "ผู้เล่น" เป็นอาร์กิวเมนต์ "ประเภทของการแทรก" เพิ่มเติม ตรวจสอบว่าคุณได้แทนที่ PROJECT_ID ด้วยรหัสโปรเจ็กต์ที่สร้างไว้ตอนต้นของโค้ดแล็บนี้
dotnet run insert PROJECT_ID cloudspanner-leaderboard leaderboard players
หลังจากผ่านไป 2-3 วินาที คุณควรเห็นการตอบกลับดังต่อไปนี้
Waiting for insert players operation to complete... Done inserting player records... Operation status: RanToCompletion Inserted players into sample database leaderboard on instance cloudspanner-leaderboard
ตอนนี้เรามาใช้ไลบรารีไคลเอ็นต์ C# เพื่อป้อนข้อมูลลงในตาราง Scores ด้วยคะแนนแบบสุ่ม 4 รายการพร้อมกับการประทับเวลาสำหรับผู้เล่นแต่ละคนในตาราง Players
เรากำหนดคอลัมน์ Timestamp ของScoresตารางเป็นคอลัมน์ "การประทับเวลาการคอมมิต" ผ่านคำสั่ง SQL ต่อไปนี้ซึ่งดำเนินการเมื่อเราเรียกใช้คำสั่ง create ก่อนหน้านี้
CREATE TABLE Scores(
PlayerId INT64 NOT NULL,
Score INT64 NOT NULL,
Timestamp TIMESTAMP NOT NULL OPTIONS(allow_commit_timestamp=true)
) PRIMARY KEY(PlayerId, Timestamp),
INTERLEAVE IN PARENT Players ON DELETE NO ACTION
สังเกตแอตทริบิวต์ OPTIONS(allow_commit_timestamp=true) ซึ่งจะทำให้ Timestamp เป็นคอลัมน์ "การประทับเวลาการคอมมิต" และช่วยให้ระบบป้อนข้อมูลการประทับเวลาธุรกรรมที่แน่นอนโดยอัตโนมัติสำหรับการดำเนินการ INSERT และ UPDATE ในแถวของตารางที่กำหนด
นอกจากนี้ คุณยังแทรกค่าการประทับเวลาของคุณเองลงในคอลัมน์ "การประทับเวลาการคอมมิต" ได้ตราบใดที่คุณแทรกการประทับเวลาที่มีค่าเป็นอดีต ซึ่งเป็นสิ่งที่เราจะทำเพื่อวัตถุประสงค์ของ Codelab นี้
ตอนนี้มาเรียกใช้คำสั่ง insert โดยใช้ค่าอาร์กิวเมนต์เดียวกันกับที่เราใช้เมื่อเรียกใช้คำสั่ง create โดยเพิ่ม "scores" เป็นอาร์กิวเมนต์ "type of insert" เพิ่มเติม ตรวจสอบว่าคุณได้แทนที่ PROJECT_ID ด้วยรหัสโปรเจ็กต์ที่สร้างไว้ตอนต้นของโค้ดแล็บนี้
dotnet run insert PROJECT_ID cloudspanner-leaderboard leaderboard scores
หลังจากผ่านไป 2-3 วินาที คุณควรเห็นการตอบกลับดังต่อไปนี้
Waiting for insert players operation to complete... Done inserting player records... Operation status: RanToCompletion Inserted players into sample database leaderboard on instance cloudspanner-leaderboard
การเรียกใช้ insert โดยระบุ "ประเภทการแทรก" เป็น scores จะเรียกใช้เมธอด InsertScoresAsync ซึ่งใช้ข้อมูลโค้ดต่อไปนี้เพื่อแทรกการประทับเวลาที่สร้างขึ้นแบบสุ่มพร้อมวันที่และเวลาที่เกิดขึ้นในอดีต
DateTime randomTimestamp = DateTime.Now
.AddYears(r.Next(-2, 1))
.AddMonths(r.Next(-12, 1))
.AddDays(r.Next(-28, 0))
.AddHours(r.Next(-24, 0))
.AddSeconds(r.Next(-60, 0))
.AddMilliseconds(r.Next(-100000, 0));
...
cmdInsert.Parameters["Timestamp"].Value = randomTimestamp.ToString("o");
หากต้องการป้อนข้อมูลในคอลัมน์ Timestamp โดยอัตโนมัติด้วยการประทับเวลาที่ตรงกับเวลาที่เกิดธุรกรรม "แทรก" คุณสามารถแทรกลักษณะค่าคงที่ C# SpannerParameter.CommitTimestamp แทนได้ ดังเช่นในข้อมูลโค้ดต่อไปนี้
cmd.Parameters["Timestamp"].Value = SpannerParameter.CommitTimestamp;
ตอนนี้เราโหลดข้อมูลเสร็จแล้ว มายืนยันค่าที่เราเพิ่งเขียนลงในตารางใหม่กัน ก่อนอื่นให้เลือกleaderboardฐานข้อมูล แล้วเลือกPlayersตาราง คลิกแท็บ Data คุณควรเห็นว่ามีข้อมูลในคอลัมน์ PlayerId และ PlayerName ของตาราง

จากนั้นมาตรวจสอบว่าตารางคะแนนมีข้อมูลด้วยหรือไม่โดยคลิกตาราง Scores แล้วเลือกแท็บ Data คุณควรเห็นว่ามีข้อมูลในคอลัมน์ PlayerId, Timestamp และ Score ของตาราง

เยี่ยมมาก! มาอัปเดตโปรแกรมเพื่อเรียกใช้คำค้นหาที่เราใช้สร้างลีดเดอร์บอร์ดเกมได้กัน
6. เรียกใช้การค้นหาลีดเดอร์บอร์ด
ตอนนี้เราได้ตั้งค่าฐานข้อมูลและโหลดข้อมูลลงในตารางแล้ว มาสร้างลีดเดอร์บอร์ดโดยใช้ข้อมูลนี้กัน โดยเราต้องตอบคำถาม 4 ข้อต่อไปนี้
- ผู้เล่นคนใดเป็น "10 อันดับ" ตลอดกาล
- ผู้เล่นคนใดเป็น "10 อันดับแรก" ของปี
- ผู้เล่นคนใดเป็น "10 อันดับแรก" ของเดือน
- ผู้เล่นคนใดเป็น "10 อันดับแรก" ของสัปดาห์
มาอัปเดตโปรแกรมเพื่อเรียกใช้การค้นหา SQL ที่จะตอบคำถามเหล่านี้กัน
เราจะเพิ่มqueryคำสั่งที่จะช่วยให้คุณเรียกใช้คำค้นหาเพื่อตอบคำถามที่จะสร้างข้อมูลที่จำเป็นสำหรับลีดเดอร์บอร์ดของเราได้
แก้ไขไฟล์ Program.cs ใน Cloud Shell Editor เพื่ออัปเดตโปรแกรมเพื่อเพิ่มคำสั่ง query
ก่อนอื่นให้เพิ่มบล็อกคำสั่ง query ใหม่ใน "Verbmap" ที่ด้านบนของโปรแกรมใต้บล็อกคำสั่ง insert ที่มีอยู่
[Verb("query", HelpText = "Query players with 'Top Ten' scores within a specific timespan "
+ "from sample Cloud Spanner database table.")]
class QueryOptions
{
[Value(0, HelpText = "The project ID of the project to use "
+ "when managing Cloud Spanner resources.", Required = true)]
public string projectId { get; set; }
[Value(1, HelpText = "The ID of the instance where the sample data resides.",
Required = true)]
public string instanceId { get; set; }
[Value(2, HelpText = "The ID of the database where the sample data resides.",
Required = true)]
public string databaseId { get; set; }
[Value(3, Default = 0, HelpText = "The timespan in hours that will be used to filter the "
+ "results based on a record's timestamp. The default will return the "
+ "'Top Ten' scores of all time.")]
public int timespan { get; set; }
}
จากนั้นเพิ่มเมธอด Query และ QueryAsync ต่อไปนี้ใต้เมธอด InsertScoresAsync ที่มีอยู่
public static object Query(string projectId,
string instanceId, string databaseId, int timespan)
{
var response = QueryAsync(
projectId, instanceId, databaseId, timespan);
response.Wait();
return ExitCode.Success;
}
public static async Task QueryAsync(
string projectId, string instanceId, string databaseId, int timespan)
{
string connectionString =
$"Data Source=projects/{projectId}/instances/"
+ $"{instanceId}/databases/{databaseId}";
// Create connection to Cloud Spanner.
using (var connection = new SpannerConnection(connectionString))
{
string sqlCommand;
if (timespan == 0)
{
// No timespan specified. Query Top Ten scores of all time.
sqlCommand =
@"SELECT p.PlayerId, p.PlayerName, s.Score, s.Timestamp
FROM Players p
JOIN Scores s ON p.PlayerId = s.PlayerId
ORDER BY s.Score DESC LIMIT 10";
}
else
{
// Query Top Ten scores filtered by the timepan specified.
sqlCommand =
$@"SELECT p.PlayerId, p.PlayerName, s.Score, s.Timestamp
FROM Players p
JOIN Scores s ON p.PlayerId = s.PlayerId
WHERE s.Timestamp >
TIMESTAMP_SUB(CURRENT_TIMESTAMP(),
INTERVAL {timespan.ToString()} HOUR)
ORDER BY s.Score DESC LIMIT 10";
}
var cmd = connection.CreateSelectCommand(sqlCommand);
using (var reader = await cmd.ExecuteReaderAsync())
{
while (await reader.ReadAsync())
{
Console.WriteLine("PlayerId : "
+ reader.GetFieldValue<string>("PlayerId")
+ " PlayerName : "
+ reader.GetFieldValue<string>("PlayerName")
+ " Score : "
+ string.Format("{0:n0}",
Int64.Parse(reader.GetFieldValue<string>("Score")))
+ " Timestamp : "
+ reader.GetFieldValue<string>("Timestamp").Substring(0, 10));
}
}
}
}
จากนั้นเพิ่มโค้ดต่อไปนี้ลงในเมธอด "Main" ของโปรแกรมเพื่อให้คำสั่ง query ทำงานได้
.Add((QueryOptions opts) => Query(
opts.projectId, opts.instanceId, opts.databaseId, opts.timespan))
คุณใช้ไฟล์ Program.cs ในไดเรกทอรี dotnet-docs-samples/applications/leaderboard/step6 เพื่อดูตัวอย่างลักษณะของไฟล์ Program.cs หลังจากเพิ่มโค้ดเพื่อเปิดใช้คำสั่ง query แล้วได้
ตอนนี้เรามาเรียกใช้โปรแกรมเพื่อยืนยันว่าคำสั่ง query ใหม่รวมอยู่ในรายการคำสั่งที่เป็นไปได้ของโปรแกรม เรียกใช้คำสั่งต่อไปนี้
dotnet run
คุณควรเห็นคำสั่ง query รวมอยู่ในเอาต์พุตเริ่มต้นของโปรแกรมเป็นตัวเลือกคำสั่งใหม่ ดังนี้
Leaderboard 1.0.0 Copyright (C) 2018 Leaderboard ERROR(S): No verb selected. create Create a sample Cloud Spanner database along with sample 'Players' and 'Scores' tables in your project. insert Insert sample 'players' records or 'scores' records into the database. query Query players with 'Top Ten' scores within a specific timespan from sample Cloud Spanner database table. help Display more information on a specific command. version Display version information.
ตอนนี้มาเรียกใช้คำสั่ง query เพื่อดูอาร์กิวเมนต์อินพุตกัน ป้อนคำสั่ง
dotnet run query
ซึ่งจะแสดงการตอบกลับต่อไปนี้
Leaderboard 1.0.0 Copyright (C) 2018 Leaderboard ERROR(S): A required value not bound to option name is missing. --help Display this help screen. --version Display version information. value pos. 0 Required. The project ID of the project to use when managing Cloud Spanner resources. value pos. 1 Required. The ID of the instance where the sample data resides. value pos. 2 Required. The ID of the database where the sample data resides. value pos. 3 (Default: 0) The timespan in hours that will be used to filter the results based on a record's timestamp. The default will return the 'Top Ten' scores of all time.
คุณจะเห็นจากการตอบกลับว่านอกจากรหัสโปรเจ็กต์ รหัสอินสแตนซ์ และรหัสฐานข้อมูลแล้ว ยังมีอาร์กิวเมนต์อีกรายการที่คาดไว้ value pos. 3 ซึ่งช่วยให้เราระบุช่วงเวลาเป็นจำนวนชั่วโมงเพื่อใช้ในการกรองระเบียนตามค่าในคอลัมน์ Timestamp ของตาราง Scores ได้ อาร์กิวเมนต์นี้มีค่าเริ่มต้นเป็น 0 ซึ่งหมายความว่าจะไม่มีการกรองระเบียนตามการประทับเวลา เราจึงใช้คำสั่ง query โดยไม่มีค่า "ช่วงเวลา" เพื่อดูรายชื่อผู้เล่น "10 อันดับ" ตลอดกาลได้
มาเรียกใช้คําสั่ง query โดยไม่ต้องระบุ "timespan" โดยใช้ค่าอาร์กิวเมนต์เดียวกันกับที่เราใช้เมื่อเรียกใช้คําสั่ง create ตรวจสอบว่าคุณได้แทนที่ PROJECT_ID ด้วยรหัสโปรเจ็กต์ที่สร้างไว้ตอนต้นของโค้ดแล็บนี้
dotnet run query PROJECT_ID cloudspanner-leaderboard leaderboard
คุณควรเห็นคำตอบที่มีผู้เล่น "10 อันดับแรก" ตลอดกาล เช่น
PlayerId : 1843159180 PlayerName : Player 87 Score : 998,955 Timestamp : 2016-03-23
PlayerId : 61891198 PlayerName : Player 19 Score : 998,720 Timestamp : 2016-03-26
PlayerId : 340906298 PlayerName : Player 48 Score : 993,302 Timestamp : 2015-08-27
PlayerId : 541473117 PlayerName : Player 22 Score : 991,368 Timestamp : 2018-04-30
PlayerId : 857460496 PlayerName : Player 68 Score : 988,010 Timestamp : 2015-05-25
PlayerId : 1826646419 PlayerName : Player 91 Score : 984,022 Timestamp : 2016-11-26
PlayerId : 1002199735 PlayerName : Player 35 Score : 982,933 Timestamp : 2015-09-26
PlayerId : 2002563755 PlayerName : Player 23 Score : 979,041 Timestamp : 2016-10-25
PlayerId : 1377548191 PlayerName : Player 2 Score : 978,632 Timestamp : 2016-05-02
PlayerId : 1358098565 PlayerName : Player 65 Score : 973,257 Timestamp : 2016-10-30
ตอนนี้เรามาเรียกใช้คำสั่ง query พร้อมอาร์กิวเมนต์ที่จำเป็นเพื่อค้นหาผู้เล่น "10 อันดับแรก" ของปีโดยระบุ "ช่วงเวลา" เท่ากับจำนวนชั่วโมงใน 1 ปี ซึ่งก็คือ 8760 ตรวจสอบว่าคุณได้แทนที่ PROJECT_ID ด้วยรหัสโปรเจ็กต์ที่สร้างไว้ตอนต้นของโค้ดแล็บนี้
dotnet run query PROJECT_ID cloudspanner-leaderboard leaderboard 8760
คุณควรเห็นคำตอบที่มีผู้เล่น "10 อันดับแรก" ของปี เช่น คำตอบต่อไปนี้
PlayerId : 541473117 PlayerName : Player 22 Score : 991,368 Timestamp : 2018-04-30
PlayerId : 228469898 PlayerName : Player 82 Score : 967,177 Timestamp : 2018-01-26
PlayerId : 1131343000 PlayerName : Player 26 Score : 944,725 Timestamp : 2017-05-26
PlayerId : 396780730 PlayerName : Player 41 Score : 929,455 Timestamp : 2017-09-26
PlayerId : 61891198 PlayerName : Player 19 Score : 921,251 Timestamp : 2018-05-01
PlayerId : 634269851 PlayerName : Player 54 Score : 909,379 Timestamp : 2017-07-24
PlayerId : 821111159 PlayerName : Player 55 Score : 908,402 Timestamp : 2017-05-25
PlayerId : 228469898 PlayerName : Player 82 Score : 889,040 Timestamp : 2017-12-26
PlayerId : 1408782275 PlayerName : Player 27 Score : 874,124 Timestamp : 2017-09-24
PlayerId : 1002199735 PlayerName : Player 35 Score : 864,758 Timestamp : 2018-04-24
ตอนนี้เรามาเรียกใช้คำสั่ง query เพื่อค้นหาผู้เล่น "10 อันดับแรก" ของเดือนโดยระบุ "ช่วงเวลา" เท่ากับจำนวนชั่วโมงใน 1 เดือน ซึ่งก็คือ 730 ตรวจสอบว่าคุณได้แทนที่ PROJECT_ID ด้วยรหัสโปรเจ็กต์ที่สร้างไว้ตอนต้นของโค้ดแล็บนี้
dotnet run query PROJECT_ID cloudspanner-leaderboard leaderboard 730
คุณควรเห็นคำตอบที่มีผู้เล่น "10 อันดับแรก" ของเดือน เช่น คำตอบต่อไปนี้
PlayerId : 541473117 PlayerName : Player 22 Score : 991,368 Timestamp : 2018-04-30
PlayerId : 61891198 PlayerName : Player 19 Score : 921,251 Timestamp : 2018-05-01
PlayerId : 1002199735 PlayerName : Player 35 Score : 864,758 Timestamp : 2018-04-24
PlayerId : 1228490432 PlayerName : Player 11 Score : 682,033 Timestamp : 2018-04-26
PlayerId : 648239230 PlayerName : Player 92 Score : 653,895 Timestamp : 2018-05-02
PlayerId : 70762849 PlayerName : Player 77 Score : 598,074 Timestamp : 2018-04-22
PlayerId : 1671215342 PlayerName : Player 62 Score : 506,770 Timestamp : 2018-04-28
PlayerId : 1208850523 PlayerName : Player 21 Score : 216,008 Timestamp : 2018-04-30
PlayerId : 1587692674 PlayerName : Player 63 Score : 188,157 Timestamp : 2018-04-25
PlayerId : 992391797 PlayerName : Player 37 Score : 167,175 Timestamp : 2018-04-30
ตอนนี้มาเรียกใช้คำสั่ง query เพื่อค้นหาผู้เล่น "10 อันดับแรก" ของสัปดาห์โดยระบุ "timespan" เท่ากับจำนวนชั่วโมงใน 1 สัปดาห์ ซึ่งก็คือ 168 ตรวจสอบว่าคุณได้แทนที่ PROJECT_ID ด้วยรหัสโปรเจ็กต์ที่สร้างไว้ตอนต้นของโค้ดแล็บนี้
dotnet run query PROJECT_ID cloudspanner-leaderboard leaderboard 168
คุณควรเห็นคำตอบที่มีผู้เล่น "10 อันดับแรก" ของสัปดาห์ เช่น คำตอบต่อไปนี้
PlayerId : 541473117 PlayerName : Player 22 Score : 991,368 Timestamp : 2018-04-30
PlayerId : 61891198 PlayerName : Player 19 Score : 921,251 Timestamp : 2018-05-01
PlayerId : 228469898 PlayerName : Player 82 Score : 853,602 Timestamp : 2018-04-28
PlayerId : 1131343000 PlayerName : Player 26 Score : 695,318 Timestamp : 2018-04-30
PlayerId : 1228490432 PlayerName : Player 11 Score : 682,033 Timestamp : 2018-04-26
PlayerId : 1408782275 PlayerName : Player 27 Score : 671,827 Timestamp : 2018-04-27
PlayerId : 648239230 PlayerName : Player 92 Score : 653,895 Timestamp : 2018-05-02
PlayerId : 816861444 PlayerName : Player 83 Score : 622,277 Timestamp : 2018-04-27
PlayerId : 162043954 PlayerName : Player 75 Score : 572,634 Timestamp : 2018-05-02
PlayerId : 1671215342 PlayerName : Player 62 Score : 506,770 Timestamp : 2018-04-28
เยี่ยมมาก
ตอนนี้เมื่อคุณเพิ่มระเบียน Spanner จะปรับขนาดฐานข้อมูลให้มีขนาดเท่าที่คุณต้องการ
ไม่ว่าฐานข้อมูลจะเติบโตมากเพียงใด ลีดเดอร์บอร์ดของเกมก็ยังคงปรับขนาดได้อย่างแม่นยำด้วย Spanner และเทคโนโลยี Truetime
7. ล้างข้อมูล
หลังจากสนุกกับการเล่น Spanner แล้ว เราต้องทำความสะอาดสนามเด็กเล่นเพื่อประหยัดทรัพยากรและเงินอันมีค่า โชคดีที่ขั้นตอนนี้ทำได้ง่าย เพียงไปที่ Developer Console แล้วลบอินสแตนซ์ที่เราสร้างในขั้นตอน Codelab ที่ชื่อ "ตั้งค่าอินสแตนซ์ Cloud Spanner"
8. ยินดีด้วย
สิ่งที่เราได้พูดถึง
- อินสแตนซ์ ฐานข้อมูล และสคีมาตารางของ Google Cloud Spanner สำหรับลีดเดอร์บอร์ด
- วิธีสร้างแอปพลิเคชันคอนโซล .NET Core C#
- วิธีสร้างฐานข้อมูลและตาราง Spanner โดยใช้ไลบรารีของไคลเอ็นต์ C#
- วิธีโหลดข้อมูลลงในฐานข้อมูล Spanner โดยใช้ไลบรารีของไคลเอ็นต์ C#
- วิธีค้นหาผลลัพธ์ "10 อันดับแรก" จากข้อมูลโดยใช้การประทับเวลาการคอมมิตของ Spanner และไลบรารีไคลเอ็นต์ C#
ขั้นตอนถัดไป:
- อ่านเอกสารประกอบเกี่ยวกับ CAP ของ Spanner
- ดูข้อมูลเกี่ยวกับการออกแบบสคีมาและแนวทางปฏิบัติแนะนำในการค้นหา
- ดูข้อมูลเพิ่มเติมเกี่ยวกับการประทับเวลาการคอมมิตของ Cloud Spanner
แสดงความคิดเห็น
- โปรดสละเวลาสักครู่เพื่อทำแบบสำรวจสั้นๆ ของเรา