1. Genel Bakış
Google Cloud Spanner, performanstan ve yüksek kullanılabilirlikten ödün vermeden ACID işlemleri ve SQL semantiği sağlayan, tümüyle yönetilen, yatay olarak ölçeklenebilir, küresel olarak dağıtılmış bir ilişkisel veritabanı hizmetidir.
Bu laboratuvarda, Cloud Spanner örneği oluşturmayı öğreneceksiniz. Oyun skor tablosu için kullanılabilecek bir veritabanı ve şema oluşturma adımlarını inceleyeceksiniz. Oyuncu bilgilerini saklamak için bir Oyuncular tablosu, oyuncu skorlarını saklamak için bir Skor tablosu oluşturarak başlayın.
Ardından tabloları örnek verilerle dolduracaksınız. Ardından, kaynakları boşa çıkarmak için en iyi on örnek sorguyu çalıştırarak ve son olarak da örneği silerek laboratuvarı tamamlayacaksınız.
Neler öğreneceksiniz?
- Cloud Spanner örneği oluşturma.
- Veritabanı ve tablo oluşturma
- Kaydetme zaman damgası sütunu nasıl kullanılır?
- Cloud Spanner veritabanı tablonuza zaman damgalarıyla veri yükleme.
- Cloud Spanner veritabanınızı sorgulama.
- Cloud Spanner örneğinizi silme.
İhtiyacınız olanlar
Bu eğiticiden nasıl yararlanacaksınız?
Google Cloud Platform deneyiminizi nasıl değerlendirirsiniz?
2. Kurulum ve Gereksinimler
Kendi hızınızda ortam kurulumu
Google Hesabınız (Gmail veya Google Apps) yoksa bir hesap oluşturmanız gerekir. Google Cloud Platform konsolunda ( console.cloud.google.com) oturum açın ve yeni bir proje oluşturun.
Zaten bir projeniz varsa konsolun sol üst köşesindeki proje seçimi açılan menüsünü tıklayın:
Sonra ‘YENİ PROJE’yi tıklayın. düğmesini tıklayın:
Henüz projeniz yoksa ilk projenizi oluşturmak için şuna benzer bir iletişim kutusu görmeniz gerekir:
Sonraki proje oluşturma iletişim kutusu yeni projenizin ayrıntılarını girmenize olanak tanır:
Tüm Google Cloud projeleri için benzersiz bir ad olan proje kimliğini unutmayın (yukarıdaki ad daha önce alınmış ve size uygun olmayacaktır!). Bu kod laboratuvarın ilerleyen bölümlerinde PROJECT_ID
olarak adlandırılacaktır.
Ardından, henüz yapmadıysanız Developers Console'da faturalandırmayı etkinleştirmeniz ve Google Cloud kaynaklarını kullanmanız ve Cloud Spanner API'yi etkinleştirmeniz gerekir.
Bu codelab'i çalıştırmanın maliyeti birkaç dolardan fazla değildir. Ancak daha fazla kaynak kullanmaya karar verirseniz veya bu kaynakları çalışır durumda bırakırsanız daha yüksek ücret ödemeniz gerekebilir (bu belgenin sonundaki "temizlik" bölümüne bakın). Google Cloud Spanner fiyatlandırması burada açıklanmıştır.
Yeni Google Cloud Platform kullanıcıları, bu codelab'i tamamen ücretsiz hale getirecek 300 ABD doları değerindeki ücretsiz denemeden yararlanabilir.
Google Cloud Shell Kurulumu
Google Cloud ve Spanner, dizüstü bilgisayarınızdan uzaktan çalıştırılabilse de bu codelab'de, Cloud'da çalışan bir komut satırı ortamı olan Google Cloud Shell'i kullanacağız.
Bu Debian tabanlı sanal makine, ihtiyacınız olan tüm geliştirme araçlarıyla yüklüdür. 5 GB boyutunda kalıcı bir ana dizin sunar ve Google Cloud'da çalışarak ağ performansını ve kimlik doğrulamasını büyük ölçüde iyileştirir. Yani bu codelab'de ihtiyacınız olan tek şey bir tarayıcıdır (evet, Chromebook'ta çalışır).
- Cloud Shell'i Cloud Console'dan etkinleştirmek için Cloud Shell'i etkinleştir simgesini tıklamanız yeterlidir (sağlanması ve ortama bağlanması yalnızca birkaç dakika sürer).
Cloud Shell'e bağlandıktan sonra kimliğinizin doğrulandığını ve projenin PROJECT_ID
olarak ayarlanmış olduğunu göreceksiniz.
gcloud auth list
Komut çıkışı
Credentialed accounts: - <myaccount>@<mydomain>.com (active)
gcloud config list project
Komut çıkışı
[core] project = <PROJECT_ID>
Herhangi bir nedenle proje ayarlanmamışsa şu komutu vermeniz yeterlidir:
gcloud config set project <PROJECT_ID>
PROJECT_ID
cihazınızı mı arıyorsunuz? Kurulum adımlarında kullandığınız kimliği kontrol edin veya Cloud Console kontrol panelinden arayın:
Cloud Shell bazı ortam değişkenlerini de varsayılan olarak ayarlar. Bu değişkenler, gelecekte komut çalıştırdığınızda işinize yarayabilir.
echo $GOOGLE_CLOUD_PROJECT
Komut çıkışı
<PROJECT_ID>
- Son olarak, varsayılan alt bölgeyi ve proje yapılandırmasını ayarlayın.
gcloud config set compute/zone us-central1-f
Çeşitli farklı alt bölgeler seçebilirsiniz. Daha fazla bilgi için Bölgeler ve Bölgeler.
Özet
Bu adımda ortamınızı ayarlarsınız.
Sonraki bölüm
Şimdi bir Cloud Spanner örneği kuracaksınız.
3. Cloud Spanner Örneği Oluşturma
Bu adımda, bu codelab için Cloud Spanner örneğimizi oluşturduk. Soldaki Hamburger Menüsünde Spanner girişini veya "/" tuşuna basarak Spanner girişini arayın ve "Spanner" yazın.
Ardından düğmesini tıklayın ve örneğiniz için cloudspanner-leaderboard örnek adını girip bir yapılandırma seçip (bölgesel bir örnek seçin) ve düğüm sayısını ayarlayın. Bu codelab için yalnızca 1 düğüme ihtiyacımız olacaktır. Üretim örnekleri için ve Cloud Spanner HDS'si (Hizmet Düzeyi Sözleşmesi) şartlarına uygun olmak üzere, Cloud Spanner örneğinizde en az 3 düğüm çalıştırmanız gerekir.
Son olarak, "Oluştur"u tıklayın. ve birkaç saniye içinde Cloud Spanner örneğiniz olur.
Sonraki adımda yeni örneğimizde veritabanı ve şema oluşturmak için C# istemci kitaplığını kullanacağız.
4. Veritabanı ve şema oluşturma
Bu adımda örnek veritabanımızı ve şemamızı oluşturacağız.
Şimdi, C# istemci kitaplığını kullanarak iki tablo oluşturalım; Oyuncu bilgileri için Oyuncular tablosu, oyuncu skorlarını kaydetmek için de Skorlar tablosu. Bunu yapmak için Cloud Shell'de C# konsolu uygulaması oluşturma adımlarını inceleyeceğiz.
Öncelikle Cloud Shell'de aşağıdaki komutu yazarak GitHub'dan bu codelab için örnek kodu klonlayın:
git clone https://github.com/GoogleCloudPlatform/dotnet-docs-samples.git
Ardından dizini "applications" (uygulamalar) olarak değiştirin uygulamanızı oluşturacağınız dizindir.
cd dotnet-docs-samples/applications/
Bu codelab'de gerekli olan tüm kodlar, codelab'de ilerlerken referans olarak kullanılmak üzere Leaderboard
adlı çalıştırılabilir bir C# uygulaması olarak mevcut dotnet-docs-samples/applications/leaderboard
dizininde bulunmaktadır. Yeni bir dizin oluşturup Skor Tablosu uygulamasının bir kopyasını aşamalı olarak hazırlayacağız.
"codelab" adlı yeni bir dizin oluşturun dokunun ve aşağıdaki komutla dizini değiştirin:
mkdir codelab && cd $_
"Leaderboard" adlı yeni bir .NET C# konsol uygulaması oluşturun kullanabilirsiniz:
dotnet new console -n Leaderboard
Bu komut, iki birincil dosyadan (Leaderboard.csproj
proje dosyası ve Program.cs
program dosyası) oluşan basit bir konsol uygulaması oluşturur.
Haydi çalıştıralım. Dizini, uygulamanın yer aldığı yeni oluşturulan Leaderboard diziniyle değiştirin:
cd Leaderboard
Ardından dosyayı çalıştırmak için aşağıdaki komutu girin.
dotnet run
"Hello World!" uygulama çıkışını görürsünüz.
Şimdi Program.cs
tablosunu C# Spanner istemci kitaplığını kullanarak iki tablo Oyuncu ve Skorlardan oluşan bir leaderboard oluşturmak için düzenlenecek şekilde düzenleyerek konsol uygulamamızı güncelleyelim. Bu işlemi doğrudan Cloud Shell Düzenleyici'de yapabilirsiniz:
Aşağıda vurgulanan simgeyi tıklayarak Cloud Shell Düzenleyici'yi açın:
Ardından, Cloud Shell Düzenleyici'de Program.cs
dosyasını açın ve aşağıdaki C# uygulaması kodunu Program.cs
dosyasına yapıştırarak leaderboard
veritabanını, Players
ve Scores
tablolarını oluşturmak için gereken kodla dosyanın mevcut kodunu değiştirin:
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 kodunu daha net bir şekilde açıklamak için aşağıda Program’ın ana bileşenlerinin etiketlenmiş bir diyagramına yer verilmiştir:
create
komutunu etkinleştirme kodu eklendikten sonra Program.cs
dosyanızın nasıl görünmesi gerektiğine dair bir örnek görmek için dotnet-docs-samples/applications/leaderboard/step4
dizinindeki Program.cs
dosyasını kullanabilirsiniz.
Ardından, Cloud Shell Düzenleyici'yi kullanarak Leaderboard.csproj
programının proje dosyasını açıp düzenleyin ve aşağıdaki koda benzer şekilde güncelleyin. "Dosya"yı kullanarak tüm değişikliklerinizi kaydettiğinizden emin olun menüsünü kullanabilirsiniz.
<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>
Bu değişiklik, Cloud Spanner API ile etkileşim kurmamız gereken Google.Cloud.Spanner.Data
C# Spanner Nuget paketine bir referans ekledi. Bu değişiklik, noktanet-doc-samples GitHub deposunun bir parçası olan ve kullanışlı bir "verbmap" sağlayan CommandLineUtil
projesine bir referans da ekler CommandLineParser
açık kaynak uzantısı; Konsol uygulamalarındaki komut satırı girişlerini yönetmek için kullanışlı bir kitaplıktır.
create
komutunu etkinleştirme kodu eklendikten sonra Leaderboard.csproj
dosyanızın nasıl görünmesi gerektiğine dair bir örnek görmek için dotnet-docs-samples/applications/leaderboard/step4
dizinindeki Leaderboard.csproj
dosyasını kullanabilirsiniz.
Artık güncellenmiş örneğinizi çalıştırmaya hazırsınız. Güncellenen uygulamanızın varsayılan yanıtını görmek için aşağıdakileri yazın:
dotnet run
Şuna benzer bir çıkış alırsınız:
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.
Bu yanıttan bu uygulamanın, olası üç komuttan biriyle çalıştırılabilecek Leaderboard
uygulaması olduğunu görüyoruz: create
, help
ve version
.
Spanner veritabanı ve tabloları oluşturmak için create
komutunu deneyelim. Komutun beklenen bağımsız değişkenlerini görmek için komutu bağımsız değişken olmadan çalıştırın.
dotnet run create
Aşağıdaki gibi bir yanıt görürsünüz:
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.
Burada create
komutunun beklenen bağımsız değişkenlerinin Proje Kimliği, Örnek Kimliği ve Veritabanı Kimliği olduğunu görebiliriz.
Şimdi aşağıdaki komutu çalıştırın. PROJECT_ID
yerine bu codelab'in başında oluşturduğunuz proje kimliğini emin olun.
dotnet run create PROJECT_ID cloudspanner-leaderboard leaderboard
Birkaç saniye sonra, aşağıdaki gibi bir yanıt görürsünüz:
Waiting for operation to complete... Operation status: RanToCompletion Created sample database leaderboard on instance cloudspanner-leaderboard
Cloud Console'un Cloud Spanner bölümünde, soldaki menüde yeni veritabanınızı ve tablolarınızı göreceksiniz.
Sonraki adımda, yeni veritabanınıza bazı veriler yüklemek için uygulamamızı güncelleyeceğiz.
5. Verileri Yükle
Artık leaderboard
adında iki tablo içeren bir veritabanımız var; Players
ve Scores
. Şimdi Players
tablomuzu oyuncularla, Scores
tablomuzu da her oyuncu için rastgele skorlarla doldurmak için C# istemci kitaplığını kullanalım.
Aşağıda vurgulanan simgeyi tıklayarak Cloud Shell Düzenleyici'yi açın:
Ardından, Players
tablosuna 100 oyuncu eklemek üzere veya Players
tablosundaki her oyuncu için Scores
tablosuna 4 rastgele puan eklemek üzere kullanılabilecek bir insert
komutu eklemek için Cloud Shell Düzenleyici'de Program.cs
dosyasını düzenleyin.
Önce "Verbmap" (Yazım eşlemesi) içine yeni bir insert
komut bloğu ekleyin (Program’ın üst kısmındaki mevcut create
komut bloğunun altında):
[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; }
}
Daha sonra, mevcut CreateAsync
yönteminin altına aşağıdaki Insert
, InsertPlayersAsync
ve InsertScoresAsync
yöntemlerini ekleyin:
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..."
);
}
}
});
}
}
Ardından, insert
komutunu çalıştırmak için Program'ınızın "Main" (Ana) komutuna aşağıdaki kodu ekleyin yöntem:
.Add((InsertOptions opts) => Insert(
opts.projectId, opts.instanceId, opts.databaseId, opts.insertType))
insert
komutunu etkinleştirme kodu eklendikten sonra Program.cs
dosyanızın nasıl görünmesi gerektiğine dair bir örnek görmek için dotnet-docs-samples/applications/leaderboard/step5
dizinindeki Program.cs
dosyasını kullanabilirsiniz.
Şimdi yeni insert
komutunun programın olası komutlar listesine eklendiğini onaylamak için programı çalıştıralım. Aşağıdaki komutu çalıştırın:
dotnet run
insert
komutunun artık programın varsayılan çıkışına dahil olduğunu göreceksiniz:
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.
Şimdi giriş bağımsız değişkenlerini görmek için insert
komutunu çalıştıralım. Aşağıdaki komutu girin.
dotnet run insert
Bu işlem aşağıdaki yanıtı döndürür:
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'.
Yanıttan; Proje Kimliği, Örnek Kimliği ve Veritabanı Kimliği'ne ek olarak, value pos. 3
tarafından "ek türü" türünde başka bir bağımsız değişkenin beklendiğini görebilirsiniz. yardımcı olur. Bu bağımsız değişkenin değeri "oyuncular" olabilir kullanabilirsiniz.
Şimdi insert
komutunu, create
komutunu çağırdığımızda kullandığımız bağımsız değişken değerleriyle çalıştırıp "oynatıcılar" ifadesini ekleyerek çalıştıralım ek "ek türü" olarak bağımsız değişkeninin önüne geçer. PROJECT_ID
yerine bu codelab'in başında oluşturduğunuz proje kimliğini emin olun.
dotnet run insert PROJECT_ID cloudspanner-leaderboard leaderboard players
Birkaç saniye sonra, aşağıdaki gibi bir yanıt görürsünüz:
Waiting for insert players operation to complete... Done inserting player records... Operation status: RanToCompletion Inserted players into sample database leaderboard on instance cloudspanner-leaderboard
Şimdi Scores
tablomuzu Players
tablosundaki her oyuncu için zaman damgalarıyla birlikte dört rastgele puanla doldurmak üzere C# istemci kitaplığını kullanalım.
Scores
tablosunun Timestamp
sütunu, "taahhüt zaman damgası" olarak tanımlandı sütununu kontrol edin: daha önce create
komutunu çalıştırdığımızda yürütülen aşağıdaki SQL deyimi:
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)
özelliğine dikkat edin. Bu durumda Timestamp
, "taahhüt zaman damgası" haline gelir. sütununu görüntüler ve belirli bir tablo satırındaki INSERT ve UPDATE işlemleri için tam işlem zaman damgasıyla otomatik olarak doldurulmasını sağlar.
Ayrıca, bir "kaydetme zaman damgası"na kendi zaman damgası değerlerinizi de ekleyebilirsiniz. geçmiş bir değere sahip bir zaman damgası eklemeniz gerekir. Bu codelab'in amacı budur.
Şimdi insert
komutunu, "scores" ekleyerek create
komutunu çağırdığımızda kullandığımız bağımsız değişken değerleriyle çalıştıralım. ek "ek türü" olarak bağımsız değişkeninin önüne geçer. PROJECT_ID
yerine bu codelab'in başında oluşturduğunuz proje kimliğini emin olun.
dotnet run insert PROJECT_ID cloudspanner-leaderboard leaderboard scores
Birkaç saniye sonra, aşağıdaki gibi bir yanıt görürsünüz:
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
, "type of insert" (ekleme türü) ile çalıştırılıyor belirtilen scores
yöntemi, rastgele oluşturulmuş bir zaman damgası (tarih/saat geçmişte olmak üzere) eklemek için aşağıdaki kod snippet'lerini kullanan InsertScoresAsync
yöntemini çağırır:
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
sütununun tam olarak "Insert" öğesinin zaman damgasıyla otomatik olarak doldurulması için işlemi gerçekleşirse bunun yerine aşağıdaki kod snippet'indeki gibi C# sabitini SpannerParameter.CommitTimestamp
ekleyebilirsiniz:
cmd.Parameters["Timestamp"].Value = SpannerParameter.CommitTimestamp;
Veri yüklemeyi tamamladığımıza göre artık yeni tablolarımıza yazdığımız değerleri doğrulayalım. Öncelikle leaderboard
veritabanını ve ardından Players
tablosunu seçin. Data
sekmesini tıklayın. Tablonun PlayerId
ve PlayerName
sütunlarında veri bulunduğunu göreceksiniz.
Şimdi de Scores
tablosunu tıklayıp Data
sekmesini seçerek Puanlar tablosunun veri içerdiğini doğrulayalım. Tablonun PlayerId
, Timestamp
ve Score
sütunlarında verileriniz olduğunu göreceksiniz.
Tebrikler! Oyun skor tablosu oluşturmak için kullanabileceğimiz bazı sorgular çalıştırmak üzere Programımızı güncelleyelim.
6. Skor tablosu sorgularını çalıştırma
Veritabanımızı kurup bilgileri tablolarımıza yüklediğimize göre şimdi bu verileri kullanarak bir skor tablosu oluşturalım. Bunu yapmak için aşağıdaki dört soruyu cevaplamamız gerekiyor:
- "En İyi On" Oyuncular var mı?
- "En İyi On" Oyuncular ne durumda?
- "En İyi On" Oyuncular hakkında bilgi edindiniz?
- "En İyi On" Oyuncular merak ediyor musunuz?
Şimdi Programımızı, bu soruları cevaplayacak SQL sorgularını çalıştıracak şekilde güncelleyelim.
Skor tablosu için gereken bilgileri üretecek soruları yanıtlamak üzere, sorguların çalıştırılmasını sağlayacak bir query
komutu ekleyeceğiz.
Program'ı query
komutu ekleyerek güncellemek için Cloud Shell Düzenleyici'de Program.cs
dosyasını düzenleyin.
Önce "Verbmap" (Yazım eşlemesi) içine yeni bir query
komut bloğu ekleyin (Program’ın üst kısmındaki mevcut insert
komut bloğunun altında):
[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; }
}
Daha sonra, mevcut InsertScoresAsync
yönteminin altına aşağıdaki Query
ve QueryAsync
yöntemlerini ekleyin:
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));
}
}
}
}
Ardından, query
komutunu çalıştırmak için Program'ınızın "Main" (Ana) komutuna aşağıdaki kodu ekleyin yöntem:
.Add((QueryOptions opts) => Query(
opts.projectId, opts.instanceId, opts.databaseId, opts.timespan))
query
komutunu etkinleştirme kodu eklendikten sonra Program.cs
dosyanızın nasıl görünmesi gerektiğine dair bir örnek görmek için dotnet-docs-samples/applications/leaderboard/step6
dizinindeki Program.cs
dosyasını kullanabilirsiniz.
Şimdi yeni query
komutunun programın olası komutlar listesine eklendiğini onaylamak için programı çalıştıralım. Aşağıdaki komutu çalıştırın:
dotnet run
query
komutunun artık yeni bir komut seçeneği olarak programın varsayılan çıkışına dahil olduğunu göreceksiniz:
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.
Şimdi giriş bağımsız değişkenlerini görmek için query
komutunu çalıştıralım. Şu komutu girin:
dotnet run query
Bu işlem, aşağıdaki yanıtı döndürür:
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.
Yanıttan; Proje Kimliği, Örnek Kimliği ve Veritabanı Kimliği'ne ek olarak, value pos. 3
adlı başka bir bağımsız değişkenin daha bulunduğunu görebilirsiniz. Bu bağımsız değişken, kayıtları Scores
tablosunun Timestamp
sütunundaki değerlerine göre filtrelemek için kullanılacak saat cinsinden bir zaman aralığı belirtmemize olanak tanır. Bu bağımsız değişkenin varsayılan değeri 0 olup hiçbir kayıt zaman damgalarına göre filtrelenmez. Böylece query
komutunu "zaman aralığı" olmadan kullanabiliriz. "En İyi On" listemizi almak için "En İyi On" değerini tüm zamanların en iyi oyuncuları.
query
komutunu, create
komutunu çalıştırdığımızda kullandığımız bağımsız değişken değerlerini kullanarak, bir "zaman aralığı" belirtmeden çalıştıralım. PROJECT_ID
yerine bu codelab'in başında oluşturduğunuz proje kimliğini emin olun.
dotnet run query PROJECT_ID cloudspanner-leaderboard leaderboard
"İlk On" bilgisini içeren bir yanıt göreceksiniz oyuncuları beğenmişsinizdir:
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
Şimdi "İlk On"u sorgulamak için gerekli bağımsız değişkenlerle birlikte query
komutunu çalıştıralım. yılın oyuncuları için bir "zaman aralığı" 8.760 olan bir yıldaki saat sayısına eşittir. PROJECT_ID
yerine bu codelab'in başında oluşturduğunuz proje kimliğini emin olun.
dotnet run query PROJECT_ID cloudspanner-leaderboard leaderboard 8760
"İlk On" bilgisini içeren bir yanıt göreceksiniz en iyi performans gösteren oyuncuları şunlar:
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
Şimdi "İlk On"u sorgulamak için query
komutunu çalıştıralım bir "zaman aralığı" belirleyerek ayın oyuncuları bir aydaki saat sayısına (730) eşittir. PROJECT_ID
yerine bu codelab'in başında oluşturduğunuz proje kimliğini emin olun.
dotnet run query PROJECT_ID cloudspanner-leaderboard leaderboard 730
"İlk On" bilgisini içeren bir yanıt göreceksiniz şunlar gibi ayın oyuncuları:
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
Şimdi "İlk On"u sorgulamak için query
komutunu çalıştıralım "zaman aralığı" belirleyerek haftanın oyuncuları bir haftadaki 168 saat olan saat sayısına eşittir. PROJECT_ID
yerine bu codelab'in başında oluşturduğunuz proje kimliğini emin olun.
dotnet run query PROJECT_ID cloudspanner-leaderboard leaderboard 168
"İlk On" bilgisini içeren bir yanıt göreceksiniz şunlar gibi haftanın oyuncuları:
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
Harika!
Artık siz kayıtları ekledikçe Spanner, veritabanınızı sizin ihtiyaç duyduğunuz büyüklükte ölçeklendirir.
Veritabanınız ne kadar büyürse gelişsin, oyununuzun skor tablosu Spanner ve Truetime teknolojisi ile doğrulukla ölçeklenmeye devam edebilir.
7. Temizleme
Spanner ile oynadığımız eğlencenin ardından, oyun alanını temizleyerek değerli kaynaklardan ve paradan tasarruf etmemiz gerekiyor. Neyse ki bu kolay bir adımdır. Bunun için geliştirici Konsolu'na gidip "Cloud Spanner Örneği Oluşturma" adlı codelab adımında oluşturduğumuz örneği silmeniz yeterlidir.
8. Tebrikler!
İşlediğimiz konular:
- Leaderboard için Google Cloud Spanner Örnekleri, Veritabanları ve Tablo Şeması
- .NET Core C# konsol uygulaması oluşturma
- C# istemci kitaplığını kullanarak Spanner Veritabanı ve Tabloları oluşturma
- C# istemci kitaplığını kullanarak Spanner Veritabanına veri yükleme
- "İlk On"u sorgulama Spanner kaydetme zaman damgalarını ve C# istemci kitaplığını kullanarak verilerinizden sonuçlar
Sonraki Adımlar:
- Spanner CAP Teknik Belgesi'ni okuyun
- Şema Tasarımı ve Sorgu en iyi uygulamaları hakkında bilgi edinin.
- Cloud Spanner kaydetme zaman damgaları hakkında daha fazla bilgi
Geri bildiriminizi paylaşın
- Lütfen çok kısa bir süre ayırarak anketimizi doldurun.