Last Updated: 2022-04-06
YugabyteDBはPostgresSQLのクエリ層を再利用することで、PostgreSQLとの高い互換性を提供しています。このPostgreSQL互換のAPIが、Yugabyte Structured Query Language (YSQL) です。
YSQLを使用して作成されたテーブルなどのオブジェクトは、Postgres用に開発された様々なツールやドライバーを活用したり、既存のアプリケーションで使用されているSQLを編集せずにそのまま使用したりすることができます。
このハンズオンではYugabyteDB Managedに作成したNorthwindサンプルデータベースを使用して、様々なYSQLのクエリや関数、ストアードプロシージャを使います。YugabyteDB Managedのアカウントや無料枠のクラスターを未作成の場合は、先に 『YugabyteDB Managed入門』のハンズオンを実施してください。
以下の内容を実施します:
Northwind データベースは、もともと Microsoft 社が作成し、数十年にわたってさまざまなデータベース製品のチュートリアルに使用されてきたサンプルデータベースです。Northwind データベースには、世界中の特殊食品を輸出入している「Northwind Traders」という架空の会社の売上データが格納されています。Northwind データベースには、顧客、注文、在庫、購買、仕入、出荷、従業員など、以下のER図にある14のテーブルとテーブル間のリレーションシップが定義されています。

このセクションでは、YugabyteDB ManagedにCloud Shell(Webブラウザ上のCLI)を使用してアクセスし、Northwindデータベースを作成します。
既に、 YugabyteDB Managedの基礎を実施してNorthwindデータベースを作成済みの場合は、次のステップに進んでください。

CREATE DATABASE northwind; と入力します。CREATE DATABASEのメッセージが返ってくることを確認してください。
\c northwind と入力して作成したばかりのNorthwindデータベースに接続します。
\d と入力し、14個のテーブルが作成されたことを確認してください。
select count(*) from <table_name>; をいくつかのテーブルに対して実行して、データが挿入されていることを確認してください。
以上で、Northwindデータベースの作成は完了です。
YSQLは、PostgreSQL互換のAPIを提供します。SQLの中でも、最も標準的な(SQL方言のない)SQLステートメントを使用して、様々なデータベース操作を行うことができます。ここでは、以下のSQL表現を使用してデータの操作を行います。
select
e.employee_id,
e.first_name,
t.territory_description,
r.region_description from employees e
join employee_territories et on e.employee_id=et.employee_id
join territories t on et.territory_id=t.territory_id
join region r on t.region_id=r.region_id;

select
e.employee_id,
e.first_name,
count(t.territory_description) as num_of_territories
from employees e
join employee_territories et on e.employee_id=et.employee_id
join territories t on et.territory_id=t.territory_id
group by e.employee_id
order by num_of_territories desc;

prepare emp_territories(int) as select e.first_name,
t.territory_description from employees e
join employee_territories et on e.employee_id=et.employee_id
join territories t on et.territory_id=t.territory_id
where e.employee_id=$1;
execute emp_territories(3); のようにパラメータに1から9 の従業員番号を入れて実行してみてください。
deallocate emp_territories; と入力して作成したステートメントを削除してください。
ALTER TABLE employees add column test_name text; と入力してください。
UPDATE employees set test_name=first_name; と入力してください。
with recursive report_structure as (
SELECT employee_id, first_name, test_name as path
FROM employees WHERE employee_id = 2
UNION ALL
SELECT e.employee_id, e.first_name,
rs.path || ' manages ' || e.first_name
FROM employees e INNER JOIN report_structure rs
ON e.reports_to=rs.employee_id
)
SELECT * from report_structure;
再帰SQLとは、前の処理の結果を使って処理の繰り返し(ループ)を行なう場合に使われます。今回は、従業員テーブルのreports_toとemployee_idをキーにテーブル結合を行うことで、pathという列にレポートラインを表示する再帰処理を行なっています。

以上で、このセクションは完了です。
PostgreSQLは様々な組み込み関数を提供しています。このセクションでは、代表的な関数をいくつか使用して、Northwindデータベースのデータを様々な形で利用する方法を学習します。
ALTER TABLE employees add column test_email text; と入力してください。UPDATE employees
set test_email=CONCAT (first_name,'.', last_name, '@northwindtraders.com');
select employee_id, first_name, last_name, test_email from employees; と入力して確認してください。
select
customer_id,
company_name,
country,
postal_code
from customers
where postal_code ~ '.*-.*';
.*は、どんな文字でも、何文字でも良いことを表します。上記の正規表現では、ハイフンの前後はどんな文字列でも構わないという条件で文字列を検索しています。

select order_id, order_date from orders where customer_id='FAMIA' order by order_id; と入力してください。
SELECT
order_id,
AGE(shipped_date, order_date) AS time_to_fill_order
FROM orders
WHERE customer_id = 'FAMIA'
ORDER BY order_id;

SELECT
product_id,
unit_price,
category_id,
AVG (unit_price) OVER (
PARTITION BY category_id ) avg_unit_price_for_category
FROM products
WHERE category_id between 1 and 2;
商品カテゴリ1の平均単価と、商品カテゴリ2の平均単価が、各商品のIDと単価と共に表示されます。

以下のSQLをコピーして、Cloud Shellから入力してください。
select category_id,avg(unit_price)
from products
group by category_id
order by category_id;

SELECT product_id, unit_price, category_id,
RANK() OVER (
PARTITION BY category_id
ORDER BY unit_price DESC ) unit_price_rank
FROM
products
WHERE category_id BETWEEN 1 AND 2;
商品カテゴリ1の中での単価ランキングと、商品カテゴリ2の中での単価ランキングがリストされます。

SELECT product_id, unit_price, category_id,
RANK() OVER (
ORDER BY unit_price DESC ) unit_price_rank
FROM
products
WHERE category_id BETWEEN 1 AND 2;

以上で、このセクションは完了です。
YSQLは、標準的な(方言の少ない)SQLをサポートしているだけでなく、様々な 高度な機能を提供しています。
また、PostgresSQLコミュニティから提供される様々な 拡張機能をプラグインして使用することができます。あらかじめバンドルされているPostgreSQL Extensionは、YugabyteDBのインストールディレクトリ ~/postgres/share extensionに含まれています。
ここでは、YSQLでサポートされるいくつかの機能を紹介します。また分散ストレージに対するクエリ実行を効率化する、パフォーマンス分析についても触れています。
CREATE EXTENSION pgcrypto; と入力してください。SELECT crypt('new-password', gen_salt('bf', 8)); と入力してください。

SELECT crypt('new-password', gen_salt('md5')); と入力してください。先ほどのBlowfish (bf) アルゴリズムとは異なる結果が返ります。
pg_stat_statementsは、パフォーマンス分析のための統計情報を取得するPostgreSQLの拡張機能です。CREATE EXTENSIONステートメントを使用しなくても、最初から使用可能になっています。
\d+ pg_stat_statements と入力してください。
select pg_stat_statements_reset();
create table demo (i bigint primary key, t text, d date not null, b boolean);
select * from demo where i=42 and t='x' and d is not null and b;
select query, calls, total_time from pg_stat_statements; と入力してください。
実行されたクエリは、値が変数 ($1, $2) に変わっています。where句での条件の形式が一緒であれば、数値が違っても同じクエリとして集計されます。
コロケーションとは、YugabyteDBのデフォルトである自動シャーディングと分散配置を行わず、1つのタブレットにテーブル全体を配置する機能です。比較的小さくデータが増加しないテーブルが多数あるような場合、分散による同期的なコンセンサスがネットワークの負荷を大きくしたり、細分化されたタブレットがクエリ実行のパフォーマンスに影響したりすることがあります。
CREATE DATABASE col_db WITH colocation = true; と入力してください。\c col_db と入力して、作成したcol-dbに接続します。CREATE TABLE tbl1 (k int primary key, v int);
CREATE TABLE tbl2 (k int primary key, v int);
CREATE TABLE tbl3 (k int primary key, v int) with (colocation=false);
CREATE TABLE tbl4 (k int primary key, v int) with (colocation=false);
insert into tbl1 select i, i%10 from generate_series(1,100000) as i;
insert into tbl2 select i, i%10 from generate_series(1,100000) as i;
insert into tbl3 select i, i%10 from generate_series(1,100000) as i;
insert into tbl4 select i, i%10 from generate_series(1,100000) as i;
\timing と入力します。create index on tbl1 (v);
create index on tbl3 (v);
これで、コロケーション有無とセカンダリ・インデックス有無が異なる4つのテーブルが作成されました。
explain (analyze, costs off) select * from tbl1 where v=6;
explain (analyze, costs off) select * from tbl3 where v=6;

explain (analyze, costs off) select * from tbl1, tbl2 where tbl1.k=tbl2.k and tbl1.v=6;
explain (analyze, costs off) select * from tbl3, tbl4 where tbl3.k=tbl4.k and tbl3.v=6;

set yb_bnl_batch_size=1024; と入力して、Batched Nested Loopを有効化してください。
以上で、このセクションは完了です。
お疲れ様でした。YSQLハンズオンは、これで終了です。
YugabyteDB Managedは、データベースを導入するハードウェアやOSを準備しなくても、数ステップの操作で使い始められるマネージドのデータベース・サービスです。
YugabyteDB Managedでは、CLIやGUIのツールを使って、使い慣れたSQLで操作できることを確認できたと思います。
以下のハンズオンも実施してみてください。