Ringkasan GoogleSQL untuk Bigtable
Anda dapat menggunakan pernyataan GoogleSQL untuk membuat kueri data Bigtable. GoogleSQL adalah Structured Query Language (SQL) sesuai ANSI yang juga diterapkan untuk layanan Google Cloud lainnya seperti BigQuery dan Spanner.
Dokumen ini memberikan ringkasan tentang GoogleSQL untuk Bigtable. Panduan ini memberikan contoh kueri SQL yang dapat Anda gunakan dengan Bigtable dan menjelaskan hubungannya dengan skema tabel Bigtable. Sebelum membaca dokumen ini, Anda harus memahami model penyimpanan Bigtable dan konsep desain skema.
Anda dapat membuat dan menjalankan kueri di Bigtable Studio di konsol Google Cloud, atau menjalankannya secara terprogram menggunakan library klien Bigtable untuk Java. Untuk informasi selengkapnya, lihat Menggunakan SQL dengan library klien Bigtable.
Kueri SQL ditangani oleh node cluster dengan cara yang sama seperti permintaan data NoSQL. Oleh karena itu, praktik terbaik yang sama berlaku saat membuat kueri SQL untuk dijalankan terhadap data Bigtable Anda, seperti menghindari pemindaian tabel penuh atau filter yang kompleks. Untuk informasi selengkapnya, lihat Pembacaan dan performa.
Anda tidak dapat menggunakan Data Boost dengan GoogleSQL untuk Bigtable.
Kasus penggunaan
GoogleSQL untuk Bigtable optimal untuk pengembangan aplikasi berlatensi rendah. Selain itu, menjalankan kueri SQL di konsol Google Cloud dapat berguna untuk mendapatkan representasi visual skema tabel dengan cepat, memverifikasi bahwa data tertentu telah ditulis, atau men-debug kemungkinan masalah data.
Rilis GoogleSQL saat ini untuk Bigtable tidak mendukung beberapa konstruksi SQL umum, termasuk, tetapi tidak terbatas pada, hal berikut:
- Pernyataan Bahasa Manipulasi Data (DML) di luar
SELECT
, sepertiINSERT
,UPDATE
, atauDELETE
- Pernyataan Bahasa Definisi Data (DDL) seperti
CREATE
,ALTER
, atauDROP
- Pernyataan Kontrol Akses Data
- Sintaksis kueri untuk subkueri,
JOIN
,UNION
,GROUP BY
,UNNEST
, danCTEs
Untuk mengetahui informasi selengkapnya, termasuk fungsi, operator, jenis data, dan sintaksis kueri yang didukung, lihat dokumentasi referensi GoogleSQL untuk Bigtable.
Konsep utama
Bagian ini membahas konsep utama yang perlu diketahui saat Anda menggunakan GoogleSQL untuk membuat kueri data Bigtable.
Grup kolom dalam respons SQL
Di Bigtable, tabel berisi satu atau beberapa grup kolom, yang digunakan untuk mengelompokkan kolom. Saat Anda membuat kueri tabel Bigtable dengan GoogleSQL, skema untuk tabel tersebut terdiri dari hal berikut:
- Kolom khusus bernama
_key
yang sesuai dengan kunci baris dalam tabel yang dikueri - Satu kolom untuk setiap grup kolom Bigtable dalam tabel, yang berisi data grup kolom di baris tersebut
Jenis data peta
GoogleSQL untuk Bigtable menyertakan jenis data
MAP<key, value>
,
yang dirancang khusus untuk mengakomodasi keluarga kolom.
Secara default, setiap baris dalam kolom peta berisi pasangan nilai kunci, dengan kunci adalah penentu kolom Bigtable dalam tabel yang dikueri, dan nilainya adalah nilai terbaru untuk kolom tersebut.
Berikut adalah contoh kueri SQL yang menampilkan tabel dengan
nilai kunci baris dan nilai terbaru penentu dari peta bernama
columnFamily
.
SELECT _key, columnFamily['qualifier'] FROM myTable
Jika skema Bigtable Anda melibatkan penyimpanan beberapa sel – atau
versi data – dalam kolom, Anda dapat menambahkan filter
temporal, seperti with_history
, ke pernyataan SQL.
Dalam hal ini, peta yang mewakili keluarga kolom disusun bertingkat dan ditampilkan sebagai array. Dalam array, setiap kunci adalah peta yang terdiri dari stempel waktu sebagai
kunci dan data sel sebagai nilai. Formatnya adalah
MAP<key, ARRAY<STRUCT<timestamp, value>>>
.
Contoh berikut menampilkan semua sel dalam grup kolom 'info' untuk satu baris.
SELECT _key, info FROM users(with_history => TRUE) WHERE _key = 'user_123';
Peta yang ditampilkan akan terlihat seperti berikut. Dalam tabel yang dikueri, info
adalah
grup kolom, user_123
adalah kunci baris, dan city
serta state
adalah penentu
kolom. Setiap pasangan nilai stempel waktu (STRUCT
) dalam array mewakili sel di
kolom tersebut dalam baris tersebut, dan diurutkan berdasarkan stempel waktu menurun.
/*----------+------------------------------------------------------------------+
| _key | info |
+----------+------------------------------------------------------------------+
| user_123 | {"city":{<t5>:"Brooklyn", <t0>:"New York"}, "state":{<t0>:"NY"}} |
+----------+------------------------------------------------------------------*/
Tabel jarang
Fitur utama Bigtable adalah model datanya yang fleksibel. Dalam
tabel Bigtable, jika kolom tidak digunakan dalam baris, tidak ada data yang disimpan
untuk kolom tersebut. Baris mungkin memiliki satu kolom dan baris berikutnya mungkin memiliki 100 kolom. Sebaliknya, dalam tabel database relasional, semua baris berisi semua
kolom, dan nilai NULL
biasanya disimpan di kolom baris yang tidak memiliki
data untuk kolom tersebut.
Namun, saat Anda membuat kueri tabel Bigtable dengan GoogleSQL, kolom yang tidak digunakan akan direpresentasikan dengan peta kosong dan ditampilkan sebagai nilai NULL
. Nilai NULL
ini dapat digunakan sebagai predikat kueri. Misalnya, prediket seperti WHERE family['column1'] IS NOT NULL
dapat digunakan untuk menampilkan baris hanya jika column1
digunakan dalam baris.
Byte
Saat Anda memberikan string, GoogleSQL secara default secara implisit melakukan transmisi
dari nilai STRING
ke nilai BYTES
. Artinya, misalnya, Anda dapat
memberikan string 'qualifier'
, bukan urutan byte b'qualifier'
.
Karena Bigtable secara default memperlakukan semua data sebagai byte, sebagian besar kolom Bigtable tidak berisi informasi jenis. Namun, dengan
GoogleSQL, Anda dapat menentukan skema pada waktu pembacaan dengan fungsi
CAST
. Untuk mengetahui informasi selengkapnya tentang transmisi, lihat Fungsi
konversi.
Filter temporal
Tabel berikut mencantumkan argumen yang dapat Anda gunakan saat mengakses
elemen temporal tabel. Argumen dicantumkan sesuai urutan
yang difilter. Misalnya, with_history
diterapkan sebelum latest_n
. Anda harus
memberikan stempel waktu yang valid.
Argumen | Deskripsi |
---|---|
as_of |
Timestamp. Menampilkan nilai terbaru dengan stempel waktu kurang dari atau sama dengan stempel waktu yang diberikan. |
with_history |
Boolean. Mengontrol apakah akan menampilkan nilai terbaru sebagai nilai skalar atau berstempel waktu sebagai STRUCT . |
after_or_equal |
Timestamp. Nilai dengan stempel waktu setelah input,
inklusif. Memerlukan with_history => TRUE |
before |
Timestamp. Nilai dengan stempel waktu sebelum input,
eksklusif. Memerlukan with_history => TRUE |
latest_n |
Bilangan bulat. Jumlah nilai stempel waktu yang akan ditampilkan per penentu kolom (kunci peta). Harus lebih besar dari atau sama dengan 1. Memerlukan
with_history => TRUE . |
Untuk contoh lainnya, lihat Pola kueri lanjutan.
Kueri dasar
Bagian ini menjelaskan dan menunjukkan contoh kueri SQL Bigtable dasar dan cara kerjanya. Untuk contoh kueri tambahan, lihat contoh pola kueri GoogleSQL untuk Bigtable.
Mengambil versi terbaru
Meskipun Bigtable memungkinkan Anda menyimpan beberapa versi data di setiap kolom, GoogleSQL untuk Bigtable secara default menampilkan versi terbaru – sel terbaru – data untuk setiap baris.
Pertimbangkan set data contoh berikut, yang menunjukkan bahwa user1
berpindah dua kali di negara bagian New York dan sekali di kota Brooklyn. Dalam contoh ini,
address
adalah grup kolom, dan penentu kolomnya adalah street
, city
,
dan state
. Sel dalam kolom dipisahkan oleh baris kosong.
address | |||
---|---|---|---|
_key | street | city | dengan status tersembunyi akhir |
pengguna1 | 2023/01/10-14:10:01.000: '113 Xyz Street' 2021/12/20-09:44:31.010: '76 Xyz Street' 2005/03/01-11:12:15.112: '123 Abc Street' |
2021/12/20-09:44:31.010: 'Brooklyn' 2005/03/01-11:12:15.112: 'Queens' |
2005/03/01-11:12:15.112: 'NY' |
Untuk mengambil versi terbaru setiap kolom untuk user1
, Anda dapat menggunakan
pernyataan SELECT
seperti berikut.
SELECT * FROM myTable WHERE _key = 'user1'
Responsnya berisi alamat saat ini, yang merupakan kombinasi dari nilai jalan, kota, dan negara bagian terbaru (ditulis pada waktu yang berbeda) yang dicetak sebagai JSON. Stempel waktu tidak disertakan dalam respons.
_key | address | ||
---|---|---|---|
pengguna1 | {street:'113 Xyz Street', city:'Brooklyn', state: :'NY'} |
Mengambil semua versi
Untuk mengambil versi (sel) data yang lebih lama, gunakan flag with_history
. Anda
juga dapat membuat alias kolom dan ekspresi, seperti yang diilustrasikan dalam contoh berikut.
SELECT _key, columnFamily['qualifier'] AS col1
FROM myTable(with_history => TRUE)
Untuk lebih memahami peristiwa yang menyebabkan status baris saat ini, Anda dapat
mengambil stempel waktu untuk setiap nilai dengan mengambil histori lengkap. Misalnya, untuk memahami kapan user1
pindah ke alamatnya saat ini dan tempat
asalnya, Anda dapat menjalankan kueri berikut:
SELECT
address['street'][0].value AS moved_to,
address['street'][1].value AS moved_from,
FORMAT_TIMESTAMP('%Y-%m-%d', address['street'][0].timestamp) AS moved_on,
FROM myTable(with_history => TRUE)
WHERE _key = 'user1'
Saat Anda menggunakan flag with_history
dalam kueri SQL, respons akan
ditampilkan sebagai MAP<key, ARRAY<STRUCT<timestamp, value>>>
. Setiap item dalam array
adalah nilai stempel waktu untuk baris, grup kolom, dan kolom yang ditentukan.
Stempel waktu diurutkan dalam urutan kronologis terbalik, sehingga data terbaru
selalu menjadi item pertama yang ditampilkan.
Respons kueri adalah sebagai berikut.
moved_to | moved_from | moved_on | ||
---|---|---|---|---|
113 Xyz Street | 76 Xyz Street | 10/01/2023 |
Anda juga dapat mengambil jumlah versi di setiap baris menggunakan fungsi array seperti yang ditunjukkan dalam kueri berikut:
SELECT _key, ARRAY_LENGTH(MAP_ENTRIES(address)) AS version_count
FROM myTable(with_history => TRUE)
Mengambil data dari waktu yang ditentukan
Dengan menggunakan filter as_of
, Anda dapat mengambil status baris seperti pada
titik waktu tertentu. Misalnya, jika ingin mengetahui alamat user
pada pukul 13.14 tanggal 10 Januari 2022, Anda dapat menjalankan kueri berikut.
SELECT address
FROM myTable(as_of => TIMESTAMP('2022/01/10-13:14:00'))
WHERE _key = 'user1'
Hasilnya menunjukkan alamat terakhir yang diketahui pada 10 Januari 2022 pukul 13.14, yang merupakan kombinasi jalan dan kota dari update 2021/12/20-09:44:31.010 dan negara bagian dari 2005/03/01-11:12:15.112.
address | ||
---|---|---|
{street:'76 Xyz Street', city:'Brooklyn', state: :'NY'} |
Hasil yang sama juga dapat dicapai menggunakan stempel waktu Unix.
SELECT address
FROM myTable(as_of => TIMESTAMP_FROM_UNIX_MILLIS(1641820440000))
WHERE _key = 'user1'
Pertimbangkan set data berikut, yang menunjukkan status aktif atau nonaktif alarm asap dan
karbon monoksida. Grup kolom adalah alarmType
dan penentu kolom adalah smoke
dan carbonMonoxide
. Sel di setiap kolom dipisahkan
oleh baris kosong.
alarmType |
||
---|---|---|
_key | asap | carbonMonoxide |
building1#section1 | 2023/04/01-09:10:15.000: 'nonaktif' 2023/04/01-08:41:40.000: 'aktif' 2020/07/03-06:25:31.000: 'nonaktif' 2020/07/03-06:02:04.000: 'aktif' |
2023/04/01-09:22:08.000: 'nonaktif' 2023/04/01-08:53:12.000: 'aktif' |
building1#section2 | 2021/03/11-07:15:04.000: 'nonaktif' 2021/03/11-07:00:25.000: 'aktif' |
Anda dapat menemukan bagian building1
tempat alarm asap aktif pada pukul 09.00 pada 1 April
2023 dan status alarm karbon monoksida pada saat itu menggunakan
kueri berikut.
SELECT _key AS location, sensorType['carbonMonoxide'] AS CO_sensor
FROM alarms(as_of => TIMESTAMP('2023/04/01-09:00:00.000'))
WHERE _key LIKE 'building1%' and sensorType['smoke'] = 'on'
Hasilnya adalah sebagai berikut:
location | CO_sensor |
---|---|
building1#section1 | 'on' |
Membuat kueri data deret waktu
Kasus penggunaan umum untuk Bigtable adalah penyimpanan
data deret waktu.
Pertimbangkan set data contoh berikut, yang menunjukkan pembacaan suhu dan kelembapan untuk sensor cuaca. ID grup kolom adalah metrics
dan penentu
kolom adalah temperature
dan humidity
. Sel dalam kolom dipisahkan oleh
baris kosong, dan setiap sel mewakili pembacaan sensor dengan stempel waktu.
metrics |
||
---|---|---|
_key | temperature | kelembapan |
sensorA#20230105 | 2023/01/05-02:00:00.000: 54 2023/01/05-01:00:00.000: 56 2023/01/05-00:00:00.000: 55 |
2023/01/05-02:00:00.000: 0,89 2023/01/05-01:00:00.000: 0,9 2023/01/05-00:00:00.000: 0,91 |
sensorA#20230104 | 2023/01/04-23:00:00.000: 56 2023/01/04-22:00:00.000: 57 |
2023/01/04-23:00:00.000: 0,9 2023/01/04-22:00:00.000: 0,91 |
Anda dapat mengambil rentang nilai stempel waktu tertentu menggunakan filter temporal
after
, before
, atau after_or_equal
. Contoh berikut menggunakan after
:
SELECT metrics['temperature'] AS temp_versioned
FROM
sensorReadings(after => TIMESTAMP('2023/01/04-23:00:00'),
before => TIMESTAMP('2023/01/05-01:00:00'))
WHERE _key LIKE 'sensorA%'
Kueri menampilkan data dalam format ini:
temp_versioned |
---|
{timestamp: '2023/01/05-01:00:00.000', value:56} {timestamp: '2023/01/05-00:00:00.000', value: 55} |
{timestamp: '2023/01/04-23:00:00.000', value:56} |
Membuat kueri JSON
Fungsi JSON memungkinkan Anda memanipulasi JSON yang disimpan sebagai nilai Bigtable untuk beban kerja operasional.
Misalnya, Anda dapat mengambil nilai untuk elemen JSON abc
dari
sel terbaru dalam keluarga kolom session
beserta kunci baris menggunakan
kueri berikut.
SELECT _key, JSON_VALUE(session['payload'],'$.abc') AS abc FROM analytics
Meng-escape karakter khusus dan kata yang direservasi
Bigtable menawarkan fleksibilitas tinggi dalam penamaan tabel dan kolom. Akibatnya, dalam kueri SQL, nama tabel Anda mungkin perlu di-escape karena karakter khusus atau kata yang dicadangkan.
Misalnya, kueri berikut bukan SQL yang valid karena adanya titik dalam nama tabel.
-- ERROR: Table name format not supported
SELECT * FROM my.table WHERE _key = 'r1'
Namun, Anda dapat mengatasi masalah ini dengan mengapit item dengan karakter backtick (`).
SELECT * FROM `my.table` WHERE _key = 'r1'
Jika kata kunci yang dicadangkan SQL digunakan sebagai ID, kata kunci tersebut juga dapat di-escape.
SELECT * FROM `select` WHERE _key = 'r1'
Menggunakan SQL dengan library klien Bigtable
Library klien Bigtable untuk Java dan Python mendukung kueri data dengan SQL menggunakan executeQuery
API. Contoh berikut menunjukkan cara
mengeluarkan kueri dan mengakses data:
Java
Untuk menggunakan fitur ini, Anda harus menggunakan java-bigtable
versi 2.41.0 atau yang lebih baru. Untuk
mengetahui informasi selengkapnya tentang penggunaan, lihat
executeQuery,
Statement,
dan
ResultSet
di Javadoc.
static void query(BigtableDataClient client) {
try (ResultSet resultSet =
client.executeQuery(
Statement.of(
"SELECT cf1['bytesCol'] AS bytesCol, CAST(cf2['stringCol'] AS STRING) AS stringCol, cf3 FROM myTable WHERE _key='mykey'"))) {
while (resultSet.next()) {
ByteString byteValue = resultSet.getBytes("bytesCol");
String stringValue = resultSet.getString("stringCol");
Map<ByteString, ByteString> cf3Value =
resultSet.getMap("cf3", SqlType.mapOf(SqlType.bytes(), SqlType.bytes()));
// Do something with the data
}
}
}
Asyncio Python
Untuk menggunakan fitur ini, Anda harus menggunakan python-bigtable
versi 2.26.0 atau yang lebih baru.
from google.cloud.bigtable.data import BigtableDataClientAsync
async def execute_query(project_id, instance_id, table_id):
async with BigtableDataClientAsync(project=project_id) as client:
query = (
"SELECT cf1['bytesCol'] AS bytesCol, CAST(cf2['stringCol'] AS STRING) AS stringCol,"
" cf3 FROM {table_id} WHERE _key='mykey'"
)
async for row in await client.execute_query(query, instance_id):
print(row["_key"], row["bytesCol"], row["stringCol"], row["cf3"])