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 ทั้งหมด (ระบบใช้ชื่อด้านบนนี้ไปแล้ว และจะใช้ไม่ได้ ขออภัย) และจะมีการอ้างอิงใน Codelab ว่า PROJECT_ID
ในภายหลัง
ขั้นตอนถัดไป คุณจะต้องเปิดใช้การเรียกเก็บเงินใน 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 ซึ่งจะช่วยเพิ่มประสิทธิภาพของเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก ซึ่งหมายความว่าสิ่งที่คุณต้องมีสำหรับ Codelab นี้คือเบราว์เซอร์ (ใช่แล้ว ทั้งหมดนี้ทำงานได้บน 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 โดยกด "/" และพิมพ์ "SPANer"
ถัดไป ให้คลิก และกรอกแบบฟอร์มโดยป้อนชื่ออินสแตนซ์ cloudspanner-leaderboard สำหรับอินสแตนซ์ เลือกการกำหนดค่า (เลือกอินสแตนซ์ระดับภูมิภาค) และกำหนดจำนวนโหนด สำหรับ Codelab นี้ เราต้องการเพียง 1 โหนดเท่านั้น สำหรับอินสแตนซ์ที่ใช้งานจริงและเพื่อให้มีคุณสมบัติสำหรับ SLA ของ Cloud Spanner คุณจะต้องเรียกใช้โหนดอย่างน้อย 3 รายการในอินสแตนซ์ Cloud Spanner
สุดท้ายแต่ไม่ท้ายสุด ให้คลิก "สร้าง" และคุณก็มีอินสแตนซ์ Cloud Spanner อยู่แล้วภายในไม่กี่วินาที
ในขั้นตอนถัดไป เราจะใช้ไลบรารีของไคลเอ็นต์ Java เพื่อสร้างฐานข้อมูลและสคีมาในอินสแตนซ์ใหม่ของเรา
4. สร้างฐานข้อมูลและสคีมา
ในขั้นตอนนี้ เราจะสร้างฐานข้อมูลและสคีมาตัวอย่าง
ลองใช้ไลบรารีไคลเอ็นต์ Java เพื่อสร้างตาราง 2 ตาราง ตารางผู้เล่นสำหรับข้อมูลผู้เล่นและตารางคะแนนสำหรับจัดเก็บคะแนนผู้เล่น ซึ่งเราจะแนะนำขั้นตอนการสร้างแอปพลิเคชันคอนโซล Java ใน Cloud Shell
ก่อนอื่น ให้โคลนโค้ดตัวอย่างสำหรับ Codelab นี้จาก GitHub โดยพิมพ์คำสั่งต่อไปนี้ใน Cloud Shell
git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git
จากนั้นเปลี่ยนไดเรกทอรีเป็น "แอปพลิเคชัน" ไดเรกทอรีที่คุณจะใช้สร้างแอปพลิเคชัน
cd java-docs-samples/spanner/leaderboard
โค้ดทั้งหมดที่จำเป็นสำหรับ Codelab นี้จะอยู่ในไดเรกทอรี java-docs-samples/spanner/leaderboard/complete
ที่มีอยู่ โดยเป็นแอปพลิเคชัน C# ที่เรียกใช้ได้ชื่อ Leaderboard
เพื่อใช้อ้างอิงขณะดำเนินการใน Codelab เราจะสร้างไดเรกทอรีใหม่และสำเนาของแอปพลิเคชันลีดเดอร์บอร์ดเป็นขั้นตอน
สร้างไดเรกทอรีใหม่ชื่อ "codelab" สำหรับแอปพลิเคชันและเปลี่ยนไดเรกทอรีลงในไดเรกทอรีด้วยคำสั่งต่อไปนี้
mkdir codelab && cd $_
สร้างแอปพลิเคชัน Java พื้นฐานใหม่ชื่อ "Leaderboard" โดยใช้คำสั่ง Maven (mvn) ต่อไปนี้
mvn -B archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DgroupId=com.google.codelabs -DartifactId=leaderboard -DarchetypeVersion=1.4
คำสั่งนี้จะสร้างแอปพลิเคชันคอนโซลแบบง่ายที่ประกอบด้วยไฟล์หลัก 2 ไฟล์ ได้แก่ ไฟล์การกำหนดค่าแอป Maven pom.xml
และไฟล์แอป Java App.java
จากนั้น เปลี่ยนไดเรกทอรีเป็นไดเรกทอรีลีดเดอร์บอร์ดที่เพิ่งสร้างขึ้นและแสดงเนื้อหา ดังนี้
cd leaderboard && ls
คุณควรเห็นไฟล์ pom.xml
และไดเรกทอรี src
แสดงอยู่
pom.xml src
ตอนนี้เรามาอัปเดตแอปคอนโซลนี้โดยแก้ไข App.java
เพื่อใช้ไลบรารีไคลเอ็นต์ Java Spanner เพื่อสร้างลีดเดอร์บอร์ดที่ประกอบด้วย 2 ตาราง ผู้เล่นและคะแนน โดยทำใน Cloud Shell Editor เลย ดังนี้
เปิด Cloud Shell Editor โดยคลิกไอคอนที่ไฮไลต์ด้านล่าง
เปิด pom.xml ภายใต้โฟลเดอร์ลีดเดอร์บอร์ด เปิดไฟล์ pom.xml ที่อยู่ในโฟลเดอร์ java-docs-samples\ spanner\leaderboard\codelab\leaderboard
ไฟล์นี้กำหนดค่าระบบบิลด์ Maven เพื่อสร้างแอปพลิเคชันของเราลงใน jar รวมถึงทรัพยากร Dependency ทั้งหมดของเรา
เพิ่มส่วนการจัดการทรัพยากร Dependency ใหม่ 1 ส่วนต่อไปนี้ใน </properties> ที่มีอยู่ องค์ประกอบ:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-bom</artifactId>
<version>0.83.0-alpha</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
เพิ่มทรัพยากร Dependency ใหม่ 1 รายการใน <dependencies> ที่มีอยู่ด้วย ซึ่งจะเพิ่มไลบรารีของไคลเอ็นต์ Cloud Spanner Java ลงในแอปพลิเคชัน
<dependency>
<!-- Version auto-managed by BOM -->
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-spanner</artifactId>
</dependency>
จากนั้นแทนที่ <build> ที่มีอยู่ของไฟล์ pom.xml
ที่มี <build> ต่อไปนี้ ส่วน:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<finalName>leaderboard</finalName>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.google.codelabs.App</mainClass>
</manifest>
</archive>
<appendAssemblyId>false</appendAssemblyId>
<attach>false</attach>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
</plugins>
</build>
บันทึกการเปลี่ยนแปลงที่คุณทำในไฟล์ pom.xml โดยเลือก "บันทึก" ในส่วน "ไฟล์" ของ Cloud Shell Editor เมนูหรือกด "Ctrl" และ "S" บนแป้นพิมพ์พร้อมกัน
จากนั้นเปิดไฟล์ App.java
ใน Cloud Shell Editor ที่อยู่ในโฟลเดอร์ src/main/java/com/google/codelabs/
แทนที่โค้ดที่มีอยู่ของไฟล์ด้วยโค้ดที่ต้องใช้ในการสร้างฐานข้อมูล leaderboard
และตาราง Players
และ Scores
โดยวางโค้ด Java ต่อไปนี้ลงในไฟล์ App.java
package com.google.codelabs;
import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.spanner.Database;
import com.google.cloud.spanner.DatabaseAdminClient;
import com.google.cloud.spanner.DatabaseClient;
import com.google.cloud.spanner.DatabaseId;
import com.google.cloud.spanner.Spanner;
import com.google.cloud.spanner.SpannerException;
import com.google.cloud.spanner.SpannerExceptionFactory;
import com.google.cloud.spanner.SpannerOptions;
import com.google.spanner.admin.database.v1.CreateDatabaseMetadata;
import java.util.Arrays;
import java.util.concurrent.ExecutionException;
/**
* Example code for using the Cloud Spanner API with the Google Cloud Java client library
* to create a simple leaderboard.
*
* This example demonstrates:
*
* <p>
*
* <ul>
* <li>Creating a Cloud Spanner database.
* </ul>
*/
public class App {
static void create(DatabaseAdminClient dbAdminClient, DatabaseId db) {
OperationFuture<Database, CreateDatabaseMetadata> op =
dbAdminClient.createDatabase(
db.getInstanceId().getInstance(),
db.getDatabase(),
Arrays.asList(
"CREATE TABLE Players(\n"
+ " PlayerId INT64 NOT NULL,\n"
+ " PlayerName STRING(2048) NOT NULL\n"
+ ") PRIMARY KEY(PlayerId)",
"CREATE TABLE Scores(\n"
+ " PlayerId INT64 NOT NULL,\n"
+ " Score INT64 NOT NULL,\n"
+ " Timestamp TIMESTAMP NOT NULL\n"
+ " OPTIONS(allow_commit_timestamp=true)\n"
+ ") PRIMARY KEY(PlayerId, Timestamp),\n"
+ "INTERLEAVE IN PARENT Players ON DELETE NO ACTION"));
try {
// Initiate the request which returns an OperationFuture.
Database dbOperation = op.get();
System.out.println("Created database [" + dbOperation.getId() + "]");
} catch (ExecutionException e) {
// If the operation failed during execution, expose the cause.
throw (SpannerException) e.getCause();
} catch (InterruptedException e) {
// Throw when a thread is waiting, sleeping, or otherwise occupied,
// and the thread is interrupted, either before or during the activity.
throw SpannerExceptionFactory.propagateInterrupt(e);
}
}
static void printUsageAndExit() {
System.out.println("Leaderboard 1.0.0");
System.out.println("Usage:");
System.out.println(" java -jar leaderboard.jar "
+ "<command> <instance_id> <database_id> [command_option]");
System.out.println("");
System.out.println("Examples:");
System.out.println(" java -jar leaderboard.jar create my-instance example-db");
System.out.println(" - Create a sample Cloud Spanner database along with "
+ "sample tables in your project.\n");
System.exit(1);
}
public static void main(String[] args) throws Exception {
if (!(args.length == 3 || args.length == 4)) {
printUsageAndExit();
}
SpannerOptions options = SpannerOptions.newBuilder().build();
Spanner spanner = options.getService();
try {
String command = args[0];
DatabaseId db = DatabaseId.of(options.getProjectId(), args[1], args[2]);
DatabaseClient dbClient = spanner.getDatabaseClient(db);
DatabaseAdminClient dbAdminClient = spanner.getDatabaseAdminClient();
switch (command) {
case "create":
create(dbAdminClient, db);
break;
default:
printUsageAndExit();
}
} finally {
spanner.close();
}
System.out.println("Closed client");
}
}
บันทึกการเปลี่ยนแปลงที่คุณทำในไฟล์ App.java
โดยเลือก "บันทึก" ในส่วน "ไฟล์" ของ Cloud Shell Editor เมนู
คุณสามารถใช้ไฟล์ App.java
ในไดเรกทอรี java-docs-samples/spanner/leaderboard/step4/src
เพื่อดูตัวอย่างว่าไฟล์ App.java
ควรมีลักษณะอย่างไรหลังจากเพิ่มโค้ดเพื่อเปิดใช้คำสั่ง create
วิธีสร้างแพ็กเกจ mvn ของแอปจากไดเรกทอรีที่มี pom.xml
อยู่
mvn package
เมื่อสร้างไฟล์ Java jar สำเร็จแล้ว ให้เรียกใช้แอปพลิเคชันที่ได้ใน Cloud Shell โดยป้อนคำสั่งต่อไปนี้
java -jar target/leaderboard.jar
คุณควรเห็นผลลัพธ์ดังต่อไปนี้
Leaderboard 1.0.0 Usage: java -jar leaderboard.jar <command> <instance_id> <database_id> [command_option] Examples: java -jar leaderboard.jar create my-instance example-db - Create a sample Cloud Spanner database along with sample tables in your project.
จากคำตอบนี้ เราจะเห็นว่านี่คือแอปพลิเคชัน Leaderboard
ซึ่งปัจจุบันมีคำสั่งที่เป็นไปได้ 1 รายการคือ create
เราจะเห็นว่าอาร์กิวเมนต์ที่คาดไว้ของคำสั่ง create
คือรหัสอินสแตนซ์และรหัสฐานข้อมูล
จากนั้นเรียกใช้คำสั่งต่อไปนี้
java -jar target/leaderboard.jar create cloudspanner-leaderboard leaderboard
หลังจากผ่านไป 2-3 วินาที คุณควรเห็นคำตอบดังนี้
Created database [projects/your-project/instances/cloudspanner-leaderboard/databases/leaderboard]
ในส่วน Cloud Spanner ของ Cloud Console คุณควรจะเห็นฐานข้อมูลและตารางใหม่แสดงในเมนูด้านซ้ายมือ
ในขั้นตอนถัดไป เราจะอัปเดตแอปพลิเคชันให้โหลดข้อมูลบางอย่างลงในฐานข้อมูลใหม่
5. โหลดข้อมูล
ตอนนี้เรามีฐานข้อมูลชื่อ leaderboard
ที่มี 2 ตารางแล้ว Players
และ Scores
ต่อไปเราจะใช้ไลบรารีของไคลเอ็นต์ Java เพื่อเติมข้อมูลผู้เล่นในตาราง Players
และตาราง Scores
ด้วยคะแนนแบบสุ่มสำหรับผู้เล่นแต่ละคน
หากยังไม่ได้เปิดอยู่ ให้เปิด Cloud Shell Editor โดยคลิกไอคอนที่ไฮไลต์ด้านล่าง
จากนั้นแก้ไขไฟล์ App.java
ใน Cloud Shell Editor เพื่อเพิ่มคำสั่ง insert
ที่สามารถใช้แทรกผู้เล่น 100 คนในตาราง Players
หรือใช้เพื่อแทรกคะแนนแบบสุ่ม 4 รายการในตาราง Scores
สำหรับผู้เล่นแต่ละคนในตาราง Players
ก่อนอื่นให้อัปเดตส่วน imports
ที่ด้านบนของไฟล์แอป โดยแทนที่ส่วนที่มีอยู่ในปัจจุบัน เพื่อให้เมื่อดำเนินการเสร็จ ควรจะมีลักษณะดังต่อไปนี้
package com.google.codelabs;
import static com.google.cloud.spanner.TransactionRunner.TransactionCallable;
import com.google.api.gax.longrunning.OperationFuture;
import com.google.cloud.spanner.Database;
import com.google.cloud.spanner.DatabaseAdminClient;
import com.google.cloud.spanner.DatabaseClient;
import com.google.cloud.spanner.DatabaseId;
import com.google.cloud.spanner.Mutation;
import com.google.cloud.spanner.ResultSet;
import com.google.cloud.spanner.Spanner;
import com.google.cloud.spanner.SpannerException;
import com.google.cloud.spanner.SpannerExceptionFactory;
import com.google.cloud.spanner.SpannerOptions;
import com.google.cloud.spanner.Statement;
import com.google.cloud.spanner.TransactionContext;
import com.google.spanner.admin.database.v1.CreateDatabaseMetadata;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadLocalRandom;
จากนั้นเพิ่มเมธอด Insert, insertPlayers และ insertScores ต่อไปนี้ไว้ใต้เมธอด create()
ที่มีอยู่และเหนือเมธอด printUsageAndExit()
ที่มีอยู่
static void insert(DatabaseClient dbClient, String insertType) {
try {
insertType = insertType.toLowerCase();
} catch (Exception e) {
// Invalid input received, set insertType to empty string.
insertType = "";
}
if (insertType.equals("players")) {
// Insert players.
insertPlayers(dbClient);
} else if (insertType.equals("scores")) {
// Insert scores.
insertScores(dbClient);
} else {
// Invalid input.
System.out.println("Invalid value for 'type of insert'. "
+ "Specify a valid value: 'players' or 'scores'.");
System.exit(1);
}
}
static void insertPlayers(DatabaseClient dbClient) {
dbClient
.readWriteTransaction()
.run(
new TransactionCallable<Void>() {
@Override
public Void run(TransactionContext transaction) throws Exception {
// Get the number of players.
String sql = "SELECT Count(PlayerId) as PlayerCount FROM Players";
ResultSet resultSet = transaction.executeQuery(Statement.of(sql));
long numberOfPlayers = 0;
if (resultSet.next()) {
numberOfPlayers = resultSet.getLong("PlayerCount");
}
// Insert 100 player records into the Players table.
List<Statement> stmts = new ArrayList<Statement>();
long randomId;
for (int x = 1; x <= 100; x++) {
numberOfPlayers++;
randomId = (long) Math.floor(Math.random() * 9_000_000_000L) + 1_000_000_000L;
Statement statement =
Statement
.newBuilder(
"INSERT INTO Players (PlayerId, PlayerName) "
+ "VALUES (@PlayerId, @PlayerName) ")
.bind("PlayerId")
.to(randomId)
.bind("PlayerName")
.to("Player " + numberOfPlayers)
.build();
stmts.add(statement);
}
transaction.batchUpdate(stmts);
return null;
}
});
System.out.println("Done inserting player records...");
}
static void insertScores(DatabaseClient dbClient) {
boolean playerRecordsFound = false;
ResultSet resultSet =
dbClient
.singleUse()
.executeQuery(Statement.of("SELECT * FROM Players"));
while (resultSet.next()) {
playerRecordsFound = true;
final long playerId = resultSet.getLong("PlayerId");
dbClient
.readWriteTransaction()
.run(
new TransactionCallable<Void>() {
@Override
public Void run(TransactionContext transaction) throws Exception {
// Initialize objects for random Score and random Timestamp.
LocalDate endDate = LocalDate.now();
long end = endDate.toEpochDay();
int startYear = endDate.getYear() - 2;
int startMonth = endDate.getMonthValue();
int startDay = endDate.getDayOfMonth();
LocalDate startDate = LocalDate.of(startYear, startMonth, startDay);
long start = startDate.toEpochDay();
Random r = new Random();
List<Statement> stmts = new ArrayList<Statement>();
// Insert 4 score records into the Scores table
// for each player in the Players table.
for (int x = 1; x <= 4; x++) {
// Generate random score between 1,000,000 and 1,000
long randomScore = r.nextInt(1000000 - 1000) + 1000;
// Get random day within the past two years.
long randomDay = ThreadLocalRandom.current().nextLong(start, end);
LocalDate randomDayDate = LocalDate.ofEpochDay(randomDay);
LocalTime randomTime = LocalTime.of(
r.nextInt(23), r.nextInt(59), r.nextInt(59), r.nextInt(9999));
LocalDateTime randomDate = LocalDateTime.of(randomDayDate, randomTime);
Instant randomInstant = randomDate.toInstant(ZoneOffset.UTC);
Statement statement =
Statement
.newBuilder(
"INSERT INTO Scores (PlayerId, Score, Timestamp) "
+ "VALUES (@PlayerId, @Score, @Timestamp) ")
.bind("PlayerId")
.to(playerId)
.bind("Score")
.to(randomScore)
.bind("Timestamp")
.to(randomInstant.toString())
.build();
stmts.add(statement);
}
transaction.batchUpdate(stmts);
return null;
}
});
}
if (!playerRecordsFound) {
System.out.println("Parameter 'scores' is invalid since "
+ "no player records currently exist. First insert players "
+ "then insert scores.");
System.exit(1);
} else {
System.out.println("Done inserting score records...");
}
}
จากนั้นหากต้องการทำให้คำสั่ง insert
ทำงานได้ ให้เพิ่มโค้ดต่อไปนี้ลงใน "main" ของแอป ภายในคำสั่ง switch (command)
:
case "insert":
String insertType;
try {
insertType = args[3];
} catch (ArrayIndexOutOfBoundsException exception) {
insertType = "";
}
insert(dbClient, insertType);
break;
เมื่อเสร็จแล้ว คำสั่ง switch (command)
ควรมีลักษณะดังต่อไปนี้
switch (command) {
case "create":
create(dbAdminClient, db);
break;
case "insert":
String insertType;
try {
insertType = args[3];
} catch (ArrayIndexOutOfBoundsException exception) {
insertType = "";
}
insert(dbClient, insertType);
break;
default:
printUsageAndExit();
}
ขั้นตอนสุดท้ายในการเพิ่ม "insert" ให้เสร็จสมบูรณ์ ฟังก์ชันให้กับแอปของคุณคือการเพิ่มข้อความช่วยเหลือสำหรับปุ่ม "insert" ลงในเมธอด printUsageAndExit()
เพิ่มบรรทัดโค้ดต่อไปนี้ในเมธอด printUsageAndExit()
เพื่อใส่ข้อความช่วยเหลือสำหรับคำสั่งแทรก
System.out.println(" java -jar leaderboard.jar insert my-instance example-db players");
System.out.println(" - Insert 100 sample Player records into the database.\n");
System.out.println(" java -jar leaderboard.jar insert my-instance example-db scores");
System.out.println(" - Insert sample score data into Scores sample Cloud Spanner "
+ "database table.\n");
บันทึกการเปลี่ยนแปลงที่คุณทำในไฟล์ App.java
โดยเลือก "บันทึก" ในส่วน "ไฟล์" ของ Cloud Shell Editor เมนู
คุณสามารถใช้ไฟล์ App.java
ในไดเรกทอรี java-docs-samples/spanner/leaderboard/step5/src
เพื่อดูตัวอย่างว่าไฟล์ App.java
ควรมีลักษณะอย่างไรหลังจากเพิ่มโค้ดเพื่อเปิดใช้คำสั่ง insert
ตอนนี้ให้สร้างและเรียกใช้แอปอีกครั้งเพื่อยืนยันว่าคำสั่ง insert
ใหม่รวมอยู่ในรายการคำสั่งที่เป็นไปได้ของแอป
หากต้องการสร้างแอป ให้เรียกใช้ mvn package
จากไดเรกทอรีที่ pom.xml ของคุณอยู่ ให้ทำดังนี้
mvn package
เมื่อสร้างไฟล์ Java jar สำเร็จแล้ว ให้เรียกใช้คำสั่งต่อไปนี้
java -jar target/leaderboard.jar
ตอนนี้คุณควรเห็นคำสั่ง insert
รวมอยู่ในเอาต์พุตเริ่มต้นของแอปแล้ว
Leaderboard 1.0.0 Usage: java -jar leaderboard.jar <command> <instance_id> <database_id> [command_option] Examples: java -jar leaderboard.jar create my-instance example-db - Create a sample Cloud Spanner database along with sample tables in your project. java -jar leaderboard.jar insert my-instance example-db players - Insert 100 sample Player records into the database. java -jar leaderboard.jar insert my-instance example-db scores - Insert sample score data into Scores sample Cloud Spanner database table.
ดูจากการตอบกลับว่านอกจากรหัสอินสแตนซ์และรหัสฐานข้อมูลแล้ว ยังมีอาร์กิวเมนต์อื่นที่สามารถมีค่าเป็น "players" ได้ หรือ "คะแนน"
ตอนนี้ เราจะมาเรียกใช้คำสั่ง insert
ด้วยค่าอาร์กิวเมนต์เหมือนกับที่เราใช้เมื่อเรียกใช้คำสั่ง create
โดยเพิ่ม "players" เป็น "ประเภทการแทรก" เพิ่มเติม อาร์กิวเมนต์
java -jar target/leaderboard.jar insert cloudspanner-leaderboard leaderboard players
หลังจากผ่านไป 2-3 วินาที คุณควรเห็นคำตอบดังนี้
Done inserting player records...
ต่อไปเราจะใช้ไลบรารีของไคลเอ็นต์ Java เพื่อป้อนข้อมูลในตาราง 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" เป็น "ประเภทการแทรก" เพิ่มเติม อาร์กิวเมนต์
java -jar target/leaderboard.jar insert cloudspanner-leaderboard leaderboard scores
หลังจากผ่านไป 2-3 วินาที คุณควรเห็นคำตอบดังนี้
Done inserting score records...
การเรียกใช้ insert
ด้วย "ประเภทการแทรก" ที่ระบุเป็น scores
จะเรียกเมธอด insertScores
ซึ่งใช้ข้อมูลโค้ดต่อไปนี้เพื่อแทรกการประทับเวลาที่สร้างขึ้นแบบสุ่มที่มีวันที่และเวลาที่เกิดขึ้นในอดีต
LocalDate endDate = LocalDate.now();
long end = endDate.toEpochDay();
int startYear = endDate.getYear() - 2;
int startMonth = endDate.getMonthValue();
int startDay = endDate.getDayOfMonth();
LocalDate startDate = LocalDate.of(startYear, startMonth, startDay);
long start = startDate.toEpochDay();
...
long randomDay = ThreadLocalRandom.current().nextLong(start, end);
LocalDate randomDayDate = LocalDate.ofEpochDay(randomDay);
LocalTime randomTime = LocalTime.of(
r.nextInt(23), r.nextInt(59), r.nextInt(59), r.nextInt(9999));
LocalDateTime randomDate = LocalDateTime.of(randomDayDate, randomTime);
Instant randomInstant = randomDate.toInstant(ZoneOffset.UTC);
...
.bind("Timestamp")
.to(randomInstant.toString())
ป้อนข้อมูลในคอลัมน์ Timestamp
โดยอัตโนมัติด้วยการประทับเวลา "แทรก" เกิดขึ้น คุณสามารถแทรกค่าคงที่ของ Java Value.COMMIT_TIMESTAMP
ได้ดังเช่นในข้อมูลโค้ดต่อไปนี้
.bind("Timestamp")
.to(Value.COMMIT_TIMESTAMP)
ตอนนี้เราโหลดข้อมูลเสร็จแล้ว เรามาตรวจสอบค่าที่เราเพิ่งเขียนในตารางใหม่กัน ก่อนอื่น ให้เลือกฐานข้อมูล leaderboard
แล้วเลือกตาราง Players
คลิกแท็บ Data
คุณควรเห็นข้อมูลในคอลัมน์ PlayerId
และ PlayerName
ของตาราง
ถัดไป มายืนยันว่าตารางคะแนนมีข้อมูลโดยคลิกตาราง Scores
แล้วเลือกแท็บ Data
กัน คุณควรเห็นข้อมูลในคอลัมน์ PlayerId
, Timestamp
และ Score
ของตาราง
เยี่ยมมาก! มาอัปเดตแอปเพื่อเรียกใช้คำค้นหาที่เราสามารถใช้สร้างลีดเดอร์บอร์ดสำหรับการเล่นเกมได้
6. เรียกใช้การค้นหาลีดเดอร์บอร์ด
เมื่อเราตั้งค่าฐานข้อมูลและโหลดข้อมูลลงในตารางแล้ว ลองสร้างลีดเดอร์บอร์ดโดยใช้ข้อมูลนี้กัน ด้วยเหตุนี้ เราจึงต้องตอบคำถาม 4 ข้อต่อไปนี้
- ผู้เล่นคนใดบ้างที่อยู่ใน "สิบอันดับแรก" ของช่วงเวลาทั้งหมด
- ผู้เล่นคนใดบ้างที่อยู่ใน "สิบอันดับแรก" ของปีนี้คืออะไร
- ผู้เล่นคนใดบ้างที่อยู่ใน "สิบอันดับแรก" ของเดือนนี้
- ผู้เล่นคนใดบ้างที่อยู่ใน "สิบอันดับแรก" ของสัปดาห์นี้กัน
มาอัปเดตแอปให้เรียกใช้การค้นหา SQL ที่จะตอบคำถามเหล่านี้กัน
เราจะเพิ่มคำสั่ง query
ที่ให้วิธีการเรียกใช้คำค้นหาเพื่อตอบคำถามที่จะสร้างข้อมูลที่จำเป็นสำหรับลีดเดอร์บอร์ดของเรา
แก้ไขไฟล์ App.java
ใน Cloud Shell Editor เพื่ออัปเดตแอปเพื่อเพิ่มคำสั่ง query
คำสั่ง query
ประกอบด้วยเมธอด query
2 วิธี ซึ่งวิธีหนึ่งจะใช้อาร์กิวเมนต์ DatabaseClient
เท่านั้น และอีกคำสั่งหนึ่งใช้อาร์กิวเมนต์ timespan
เพิ่มเติมเพื่ออำนวยความสะดวกในการกรองผลลัพธ์ตามช่วงเวลาที่ระบุเป็นชั่วโมง
เพิ่มเมธอด query
2 รายการด้านล่างเมธอด insertScores()
ที่มีอยู่ และเหนือเมธอด printUsageAndExit()
ที่มีอยู่
static void query(DatabaseClient dbClient) {
String scoreDate;
String score;
ResultSet resultSet =
dbClient
.singleUse()
.executeQuery(
Statement.of(
"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"));
while (resultSet.next()) {
scoreDate = String.valueOf(resultSet.getTimestamp("Timestamp"));
score = String.format("%,d", resultSet.getLong("Score"));
System.out.printf(
"PlayerId: %d PlayerName: %s Score: %s Timestamp: %s\n",
resultSet.getLong("PlayerId"), resultSet.getString("PlayerName"), score,
scoreDate.substring(0,10));
}
}
static void query(DatabaseClient dbClient, int timespan) {
String scoreDate;
String score;
Statement statement =
Statement
.newBuilder(
"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 HOUR) "
+ "ORDER BY s.Score DESC LIMIT 10")
.bind("Timespan")
.to(timespan)
.build();
ResultSet resultSet =
dbClient
.singleUse()
.executeQuery(statement);
while (resultSet.next()) {
scoreDate = String.valueOf(resultSet.getTimestamp("Timestamp"));
score = String.format("%,d", resultSet.getLong("Score"));
System.out.printf(
"PlayerId: %d PlayerName: %s Score: %s Timestamp: %s\n",
resultSet.getLong("PlayerId"), resultSet.getString("PlayerName"), score,
scoreDate.substring(0,10));
}
}
จากนั้นหากต้องการทำให้คำสั่ง query
ทำงานได้ ให้เพิ่มโค้ดต่อไปนี้ลงในคำสั่ง switch(command)
ใน "main" ของแอป วิธีการ:
case "query":
if (args.length == 4) {
int timespan = 0;
try {
timespan = Integer.parseInt(args[3]);
} catch (NumberFormatException e) {
System.err.println("query command's 'timespan' parameter must be a valid integer.");
System.exit(1);
}
query(dbClient, timespan);
} else {
query(dbClient);
}
break;
ขั้นตอนสุดท้ายในการเพิ่ม "คำค้นหา" ให้เสร็จสมบูรณ์ ฟังก์ชันให้กับแอปของคุณคือการเพิ่มข้อความช่วยเหลือสำหรับ "คำค้นหา" ลงในเมธอด printUsageAndExit()
เพิ่มบรรทัดโค้ดต่อไปนี้ลงในเมธอด printUsageAndExit()
เพื่อรวมข้อความช่วยเหลือสำหรับ "query" คำสั่ง:
System.out.println(" java -jar leaderboard.jar query my-instance example-db");
System.out.println(" - Query players with top ten scores of all time.\n");
System.out.println(" java -jar leaderboard.jar query my-instance example-db 168");
System.out.println(" - Query players with top ten scores within a timespan "
+ "specified in hours.\n");
บันทึกการเปลี่ยนแปลงที่คุณทำในไฟล์ App.java
โดยเลือก "บันทึก" ในส่วน "ไฟล์" ของ Cloud Shell Editor เมนู
คุณสามารถใช้ไฟล์ App.java
ในไดเรกทอรี dotnet-docs-samples/applications/leaderboard/step6/src
เพื่อดูตัวอย่างว่าไฟล์ App.java
ควรมีลักษณะอย่างไรหลังจากเพิ่มโค้ดเพื่อเปิดใช้คำสั่ง query
หากต้องการสร้างแอป ให้เรียกใช้ mvn package
จากไดเรกทอรีที่ pom.xml ของคุณอยู่ ให้ทำดังนี้
mvn package
ตอนนี้มาเรียกใช้แอปเพื่อยืนยันว่าคำสั่ง query
ใหม่รวมอยู่ในรายการคำสั่งที่เป็นไปได้ของแอปแล้ว เรียกใช้คำสั่งต่อไปนี้
java -jar target/leaderboard.jar
คุณควรเห็นคำสั่ง query
รวมอยู่ในเอาต์พุตเริ่มต้นของแอปเป็นตัวเลือกคำสั่งใหม่ดังนี้
Leaderboard 1.0.0 Usage: java -jar leaderboard.jar <command> <instance_id> <database_id> [command_option] Examples: java -jar leaderboard.jar create my-instance example-db - Create a sample Cloud Spanner database along with sample tables in your project. java -jar leaderboard.jar insert my-instance example-db players - Insert 100 sample Player records into the database. java -jar leaderboard.jar insert my-instance example-db scores - Insert sample score data into Scores sample Cloud Spanner database table. java -jar leaderboard.jar query my-instance example-db - Query players with top ten scores of all time. java -jar leaderboard.jar query my-instance example-db 168 - Query players with top ten scores within a timespan specified in hours.
ดูจากการตอบกลับได้ว่านอกเหนือจากอาร์กิวเมนต์รหัสอินสแตนซ์และรหัสฐานข้อมูลแล้ว คำสั่ง query
ยังช่วยให้เราสามารถระบุช่วงเวลาที่ไม่บังคับเป็นจำนวนชั่วโมงเพื่อใช้ในการกรองระเบียนโดยอิงตามค่าในคอลัมน์ Timestamp
ของตาราง Scores
เนื่องจากอาร์กิวเมนต์ timespan เป็นตัวเลือก หมายความว่าหากไม่ได้รวมอาร์กิวเมนต์ timespan ไว้ จะไม่มีการกรองบันทึกตามการประทับเวลา เราจึงใช้คำสั่ง query
ได้โดยไม่ต้องมี "timespan" เพื่อรับรายการ "ท็อป 10" ของเรา ผู้เล่นตลอดกาล
มาเรียกใช้คำสั่ง query
โดยไม่ระบุ "timespan" โดยใช้ค่าอาร์กิวเมนต์เดียวกันกับที่เราใช้เมื่อเรียกใช้คำสั่ง create
java -jar target/leaderboard.jar query cloudspanner-leaderboard leaderboard
คุณควรจะเห็นการตอบกลับที่มี "สูงสุด 10 อันดับแรก" ของผู้เล่นตลอดกาลในลักษณะต่อไปนี้
PlayerId: 4018687297 PlayerName: Player 83 Score: 999,618 Timestamp: 2017-07-01
PlayerId: 4018687297 PlayerName: Player 83 Score: 998,956 Timestamp: 2017-09-02
PlayerId: 4285713246 PlayerName: Player 51 Score: 998,648 Timestamp: 2017-12-01
PlayerId: 5267931774 PlayerName: Player 49 Score: 997,733 Timestamp: 2017-11-09
PlayerId: 1981654448 PlayerName: Player 35 Score: 997,480 Timestamp: 2018-12-06
PlayerId: 4953940705 PlayerName: Player 87 Score: 995,184 Timestamp: 2018-09-14
PlayerId: 2456736905 PlayerName: Player 84 Score: 992,881 Timestamp: 2017-04-14
PlayerId: 8234617611 PlayerName: Player 19 Score: 992,399 Timestamp: 2017-12-27
PlayerId: 1788051688 PlayerName: Player 76 Score: 992,265 Timestamp: 2018-11-22
PlayerId: 7127686505 PlayerName: Player 97 Score: 992,038 Timestamp: 2017-12-02
ตอนนี้เราจะเรียกใช้คำสั่ง query
ที่มีอาร์กิวเมนต์ที่จำเป็นเพื่อค้นหา "Top Ten" ผู้เล่นแห่งปีด้วยการระบุ "ช่วงเวลา" เท่ากับจำนวนชั่วโมงใน 1 ปีซึ่งเท่ากับ 8760
java -jar target/leaderboard.jar query cloudspanner-leaderboard leaderboard 8760
คุณควรจะเห็นการตอบกลับที่มี "สูงสุด 10 อันดับแรก" ผู้เล่นแห่งปีดังต่อไปนี้
PlayerId: 1981654448 PlayerName: Player 35 Score: 997,480 Timestamp: 2018-12-06
PlayerId: 4953940705 PlayerName: Player 87 Score: 995,184 Timestamp: 2018-09-14
PlayerId: 1788051688 PlayerName: Player 76 Score: 992,265 Timestamp: 2018-11-22
PlayerId: 6862349579 PlayerName: Player 30 Score: 990,877 Timestamp: 2018-09-14
PlayerId: 5529627211 PlayerName: Player 16 Score: 989,142 Timestamp: 2018-03-30
PlayerId: 9743904155 PlayerName: Player 1 Score: 988,765 Timestamp: 2018-05-30
PlayerId: 6809119884 PlayerName: Player 7 Score: 986,673 Timestamp: 2018-05-16
PlayerId: 2132710638 PlayerName: Player 54 Score: 983,108 Timestamp: 2018-09-11
PlayerId: 2320093590 PlayerName: Player 79 Score: 981,373 Timestamp: 2018-05-07
PlayerId: 9554181430 PlayerName: Player 80 Score: 981,087 Timestamp: 2018-06-21
คราวนี้ลองเรียกใช้คำสั่ง query
เพื่อค้นหา "ท็อป 10" กัน ผู้เล่นของเดือนโดยระบุ "ช่วงเวลา" เท่ากับจำนวนชั่วโมงในหนึ่งเดือน ซึ่งก็คือ 730
java -jar target/leaderboard.jar query cloudspanner-leaderboard leaderboard 730
คุณควรจะเห็นการตอบกลับที่มี "สูงสุด 10 อันดับแรก" ผู้เล่นประจำเดือนดังต่อไปนี้
PlayerId: 3869829195 PlayerName: Player 69 Score: 949,686 Timestamp: 2019-02-19
PlayerId: 7448359883 PlayerName: Player 20 Score: 938,998 Timestamp: 2019-02-07
PlayerId: 1981654448 PlayerName: Player 35 Score: 929,003 Timestamp: 2019-02-22
PlayerId: 9336678658 PlayerName: Player 44 Score: 914,106 Timestamp: 2019-01-27
PlayerId: 6968576389 PlayerName: Player 40 Score: 898,041 Timestamp: 2019-02-21
PlayerId: 5529627211 PlayerName: Player 16 Score: 896,433 Timestamp: 2019-01-29
PlayerId: 9395039625 PlayerName: Player 59 Score: 879,495 Timestamp: 2019-02-09
PlayerId: 2094604854 PlayerName: Player 39 Score: 860,434 Timestamp: 2019-02-01
PlayerId: 9395039625 PlayerName: Player 59 Score: 849,955 Timestamp: 2019-02-21
PlayerId: 4285713246 PlayerName: Player 51 Score: 805,654 Timestamp: 2019-02-02
คราวนี้ลองเรียกใช้คำสั่ง query
เพื่อค้นหา "ท็อป 10" กัน ผู้เล่นประจำสัปดาห์โดยการระบุ "ช่วงเวลา" เท่ากับจำนวนชั่วโมงใน 1 สัปดาห์ ซึ่งก็คือ 168 ชั่วโมง
java -jar target/leaderboard.jar query cloudspanner-leaderboard leaderboard 168
คุณควรจะเห็นการตอบกลับที่มี "สูงสุด 10 อันดับแรก" ผู้เล่นประจำสัปดาห์ดังต่อไปนี้
PlayerId: 3869829195 PlayerName: Player 69 Score: 949,686 Timestamp: 2019-02-19
PlayerId: 1981654448 PlayerName: Player 35 Score: 929,003 Timestamp: 2019-02-22
PlayerId: 6968576389 PlayerName: Player 40 Score: 898,041 Timestamp: 2019-02-21
PlayerId: 9395039625 PlayerName: Player 59 Score: 849,955 Timestamp: 2019-02-21
PlayerId: 5954045812 PlayerName: Player 8 Score: 795,639 Timestamp: 2019-02-22
PlayerId: 3889939638 PlayerName: Player 71 Score: 775,252 Timestamp: 2019-02-21
PlayerId: 5529627211 PlayerName: Player 16 Score: 604,695 Timestamp: 2019-02-19
PlayerId: 9006728426 PlayerName: Player 3 Score: 457,208 Timestamp: 2019-02-22
PlayerId: 8289497066 PlayerName: Player 58 Score: 227,697 Timestamp: 2019-02-20
PlayerId: 8065482904 PlayerName: Player 99 Score: 198,429 Timestamp: 2019-02-24
เยี่ยมมาก
ตอนนี้เมื่อคุณเพิ่มระเบียน Cloud Spanner จะปรับขนาดฐานข้อมูลเป็นขนาดที่คุณต้องการ ไม่ว่าฐานข้อมูลของคุณจะเติบโตมากเพียงใด ลีดเดอร์บอร์ดของเกมก็ปรับขนาดได้ด้วย Cloud Spanner และเทคโนโลยี Truetime
7. ล้างข้อมูล
หลังจากสนุกไปกับการเล่น Spanner แล้ว เราจำเป็นต้องทำความสะอาดสนามเด็กเล่นของเรา ซึ่งช่วยประหยัดทรัพยากรและเงินอันมีค่า โชคดีที่ขั้นตอนนี้เป็นขั้นตอนที่ง่ายดาย เพียงไปที่ส่วน Cloud Spanner ของ Cloud Console แล้วลบอินสแตนซ์ที่เราสร้างในขั้นตอน Codelab ที่ชื่อว่า "Setup a Cloud Spannerอินสแตนซ์"
8. ยินดีด้วย
หัวข้อที่ครอบคลุมมีดังนี้
- อินสแตนซ์ ฐานข้อมูล และสคีมาตารางของ Google Cloud Spanner สำหรับลีดเดอร์บอร์ด
- วิธีสร้างแอปพลิเคชันคอนโซล Java
- วิธีสร้างฐานข้อมูลและตาราง Spanner โดยใช้ไลบรารีของไคลเอ็นต์ Java
- วิธีโหลดข้อมูลลงในฐานข้อมูล Spanner โดยใช้ไลบรารีของไคลเอ็นต์ Java
- วิธีค้นหา "10 อันดับแรก" ผลลัพธ์จากข้อมูลของคุณโดยใช้การประทับเวลาการคอมมิต Spanner และไลบรารีของไคลเอ็นต์ Java
ขั้นตอนถัดไป:
- อ่านสมุดปกขาว CAP ของตัวกรอง
- เรียนรู้เกี่ยวกับการออกแบบสคีมาและแนวทางปฏิบัติแนะนำสำหรับการค้นหา
- ดูข้อมูลเพิ่มเติมเกี่ยวกับการประทับเวลาคอมมิตของ Cloud Spanner
แสดงความคิดเห็น
- โปรดสละเวลาสักครู่เพื่อทำแบบสำรวจสั้นๆ ของเรา