GoogleSQL untuk Bigtable ringkasan

Anda dapat menggunakan pernyataan GoogleSQL untuk melakukan kueri Data Bigtable. GoogleSQL adalah layanan yang mematuhi ANSI SQL (structured query language, SQL) yang juga diterapkan untuk seperti BigQuery dan Spanner.

Dokumen ini memberikan gambaran umum GoogleSQL untuk Bigtable. Bacaan ini menyediakan contoh-contoh kueri SQL yang dapat Anda gunakan dengan Bigtable dan menjelaskan hubungannya dengan Skema tabel Bigtable. Sebelum membaca dokumen ini, Anda harus pelajari penyimpanan Bigtable model dan desain skema konsep yang baru.

Anda dapat membuat dan menjalankan kueri di Bigtable Studio di Konsol Google Cloud, atau Anda dapat menjalankannya secara terprogram menggunakan klien Bigtable library untuk Java. Untuk informasi selengkapnya, lihat Menggunakan SQL dengan library klien Bigtable.

Kasus penggunaan

GoogleSQL untuk Bigtable optimal untuk latensi rendah pengembangan aplikasi. Selain itu, menjalankan kueri SQL di Konsol Google Cloud dapat berguna untuk mendapatkan representasi visual dengan cepat skema tabel, memverifikasi bahwa data tertentu telah ditulis, atau melakukan {i>debugging<i} potensi masalah data.

Rilis GoogleSQL untuk Bigtable saat ini tidak mendukung konstruksi SQL umum, termasuk, tetapi tidak terbatas pada, berikut ini:

  • Pernyataan Bahasa Manipulasi Data (DML) di luar SELECT, seperti INSERT, UPDATE, atau DELETE
  • Pernyataan Bahasa Definisi Data (DDL) seperti CREATE, ALTER, atau DROP
  • Pernyataan Kontrol Akses Data
  • Sintaksis kueri untuk subkueri, JOIN, UNION, GROUP BY, UNNEST, dan CTEs

Untuk informasi selengkapnya, termasuk fungsi yang didukung, operator, jenis data, dan sintaks kueri, lihat GoogleSQL untuk Bigtable referensi dokumentasi kami.

Konsep utama

Bagian ini membahas konsep-konsep penting yang perlu diketahui saat Anda menggunakan GoogleSQL untuk membuat kueri data Bigtable Anda.

Grup kolom dalam respons SQL

Di Bigtable, sebuah tabel berisi satu atau beberapa grup kolom, yang digunakan untuk mengelompokkan kolom. Saat Anda membuat kueri tabel Bigtable dengan GoogleSQL, skema untuk tabel terdiri dari hal berikut:

  • Kolom khusus bernama _key yang sesuai dengan kunci baris di kueri meja
  • Satu kolom untuk setiap grup kolom Bigtable dalam tabel, yang berisi data keluarga kolom di baris tersebut

Jenis data peta

GoogleSQL untuk Bigtable mencakup jenis data MAP<key, value>, yang dirancang khusus untuk mengakomodasi grup kolom.

Secara default, setiap baris dalam kolom peta berisi pasangan nilai kunci, dengan kuncinya penentu kolom Bigtable dalam tabel yang dikueri, dan nilainya adalah nilai terbaru untuk kolom tersebut.

Berikut ini adalah contoh kueri SQL yang mengembalikan tabel dengan nilai kunci baris dan nilai penentu terbaru dari peta bernama columnFamily.

  SELECT _key, columnFamily['qualifier'] FROM myTable

Jika skema Bigtable Anda melibatkan penyimpanan beberapa sel, atau data - dalam kolom, Anda dapat menambahkan filter, seperti with_history, ke pernyataan SQL Anda.

Dalam hal ini, peta yang mewakili grup kolom disarangkan dan ditampilkan sebagai . Dalam array, setiap kunci itu sendiri adalah peta yang terdiri dari stempel waktu sebagai data dari kunci dan sel sebagai nilai. Formatnya adalah MAP<key, ARRAY<STRUCT<timestamp, value>>>.

Contoh berikut menampilkan semua sel dalam kolom 'info' grup kolom 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 kolom penentu. Setiap pasangan nilai stempel waktu (STRUCT) dalam array mewakili sel dalam kolom-kolom itu di baris itu, dan mereka diurutkan berdasarkan stempel waktu menurun.

/*----------+------------------------------------------------------------------+
 |   _key   |                              info                                |
 +----------+------------------------------------------------------------------+
 | user_123 | {"city":{<t5>:"Brooklyn", <t0>:"New York"}, "state":{<t0>:"NY"}} |
 +----------+------------------------------------------------------------------*/

Tabel sparse

Fitur utama Bigtable adalah model datanya yang fleksibel. Di Tabel Bigtable, jika kolom tidak digunakan dalam baris, tidak ada data yang akan disimpan untuk kolom. Baris mungkin memiliki satu kolom dan baris berikutnya mungkin memiliki 100 seperti baris dan kolom. Sebaliknya, dalam tabel {i>database<i} relasional, semua baris berisi semua kolom, dan nilai NULL biasanya disimpan di kolom baris yang tidak memiliki data untuk kolom tersebut.

Saat Anda membuat kueri tabel Bigtable dengan GoogleSQL, akan tetapi, kolom yang tidak terpakai ditunjukkan dengan peta kosong dan dikembalikan sebagai Nilai NULL. Nilai NULL ini dapat digunakan sebagai predikat kueri. Sebagai contoh, predikat seperti WHERE family['column1'] IS NOT NULL dapat digunakan untuk menampilkan baris hanya jika column1 digunakan dalam baris.

Byte

Saat Anda menyediakan string, GoogleSQL secara default akan melakukan transmisi dari nilai STRING menjadi nilai BYTES. Ini berarti, misalnya, Anda dapat berikan string 'qualifier', bukan urutan byte b'qualifier'.

Karena Bigtable secara default memperlakukan semua data sebagai byte, Kolom Bigtable tidak berisi informasi jenis. Namun, dengan Di GoogleSQL, Anda dapat menentukan skema pada waktu baca dengan kode CAST fungsi tersebut. Untuk informasi selengkapnya tentang transmisi, lihat Konversi fungsi.

Filter sementara

Tabel berikut mencantumkan argumen yang dapat Anda gunakan saat mengakses elemen temporal tabel. Argumen dicantumkan sesuai urutan 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 lebih sedikit dari atau sama dengan stempel waktu yang diberikan.
with_history Boolean. Mengontrol apakah akan menampilkan nilai terbaru sebagai nilai skalar atau stempel 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 dengan stempel waktu yang akan ditampilkan per kolom penentu (tombol peta). Harus lebih besar dari atau sama dengan 1. Memerlukan with_history => TRUE.

Untuk contoh lainnya, lihat Kueri lanjutan yang sama.

Kueri dasar

Bagian ini menjelaskan dan menunjukkan contoh Bigtable SQL dasar kueri dan cara kerjanya. Untuk contoh kueri tambahan, lihat Pola kueri GoogleSQL untuk Bigtable contoh.

Mengambil versi terbaru

Meskipun Bigtable memungkinkan Anda menyimpan beberapa versi data dalam setiap kolom, GoogleSQL untuk Bigtable secara default menampilkan versi terbaru – sel terbaru – dari data untuk setiap baris.

Pertimbangkan contoh set data berikut, yang menunjukkan bahwa user1 pindah dua kali di negara bagian NY dan sekali di kota Brooklyn. Dalam contoh ini, address adalah kelompok kolom, dan penentu kolom adalah street, city, dan state. Sel-sel dalam kolom dipisahkan oleh baris kosong.

alamat
_key jalan kota dengan status tersembunyi akhir
pengguna1 2023/01/10-14:10:01.000:
'Jalan Xyz 113'

2021/12/20-09:44:31.010:
'76 Xyz Street'

2005/03/01-11:12:15.112:
'Jalan Abc 123'
2021/12/20-09:44:31.010:
'Brooklyn'

2005/03/01-11:12:15.112:
'Ratu'
2005/03/01-11:12:15.112:
'NY'

Untuk mengambil versi terbaru dari setiap kolom untuk user1, Anda dapat menggunakan Pernyataan SELECT seperti berikut.

   SELECT * FROM myTable WHERE _key = 'user1'

Respons akan berisi alamat saat ini, yang merupakan kombinasi dari nilai jalan, kota, dan negara bagian terkini (ditulis pada waktu yang berbeda) yang dicetak sebagai JSON. Stempel waktu tidak disertakan dalam respons.

_key alamat
pengguna1 {street:'113 Xyz Street', city:'Brooklyn', negara bagian: :'NY'}

Ambil semua versi

Untuk mengambil versi lama (sel) data, gunakan tanda with_history. Anda juga bisa alias kolom dan ekspresi, seperti yang diilustrasikan pada contoh berikut.

  SELECT _key, columnFamily['qualifier'] AS col1
  FROM myTable(with_history => TRUE)

Untuk lebih memahami peristiwa yang mengarah ke status baris saat ini, Anda dapat mengambil stempel waktu untuk setiap nilai dengan mengambil histori lengkap. Sebagai contoh, untuk memahami kapan user1 pindah ke alamatnya saat ini dan lokasi sebelumnya, 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, responsnya adalah ditampilkan sebagai MAP<key, ARRAY<STRUCT<timestamp, value>>>. Setiap item dalam array adalah nilai yang telah diberi stempel waktu untuk baris, kelompok kolom, dan kolom yang ditentukan. Stempel waktu diurutkan dalam urutan kronologis terbalik, sehingga data terbaru ditampilkan selalu item pertama dikembalikan.

Respons kueri adalah sebagai berikut.

moved_to moved_from moved_on
Jalan 113 Xyz Jalan 76 Xyz 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 tertentu

Menggunakan filter as_of memungkinkan Anda mengambil status baris seperti sebelumnya di waktu tertentu. Contohnya, jika Anda ingin tahu alamat user sebagai mulai 10 Januari 2022 pukul 13.14, 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 13:14, yang merupakan kombinasi dari jalan dan kota dari 2021/12/20-09:44:31.010 update dan status dari 2005/03/01-11:12:15.112.

alamat
{street:'76 Xyz Street', city:'Brooklyn', negara bagian: :'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 {i>dataset<i} berikut, yang menunjukkan status asap dan alarm karbon monoksida. Kelompok kolom adalah alarmType dan kolom penentunya adalah smoke dan carbonMonoxide. Sel di setiap kolom dipisahkan dengan baris kosong.


alarmType
_key asap carbonMonoxide
gedung1#bagian1 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'
gedung1#bagian2 2021/03/11-07:15:04.000:
'nonaktif'

2021/03/11-07:00:25.000:
'aktif'

Anda dapat menemukan bagian dari building1 yang alarm asapnya aktif pada pukul 09.00 pada hari April 1 tahun 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:

lokasi CO_sensor
gedung1#bagian1 'aktif'

Membuat kueri data deret waktu

Kasus penggunaan umum untuk Bigtable adalah penyimpanan data deret waktu. Pertimbangkan {i>dataset<i} sampel berikut, yang menunjukkan suhu dan kelembapan pembacaan sensor cuaca. ID kelompok kolom adalah metrics dan kolom penentunya adalah temperature dan humidity. Sel-sel dalam kolom dipisahkan oleh baris kosong, dan setiap sel mewakili pembacaan sensor yang telah dilakukan.


metrik
_key suhu 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 tersebut menampilkan data dalam format ini:

temp_versioned
{timestamp: &#39;2023/01/05-01:00:00.000&#39;, value:56}
{timestamp: &#39;2023/01/05-00:00:00.000&#39;, value: 55}
{timestamp: &#39;2023/01/04-23:00:00.000&#39;, value:56}

Kueri JSON

Fungsi JSON memungkinkan Anda memanipulasi JSON yang disimpan sebagai nilai Bigtable untuk workload operasional.

Misalnya, Anda dapat mengambil nilai untuk elemen JSON abc dari elemen sel terbaru di grup kolom session bersama dengan row key dengan menggunakan kueri berikut.

  SELECT _key, JSON_VALUE(session['payload'],'$.abc') AS abc FROM analytics

Escape karakter khusus dan kata khusus untuk sistem

Bigtable menawarkan fleksibilitas tinggi dalam penamaan tabel dan kolom. Akibatnya, dalam kueri SQL Anda, nama tabel Anda mungkin perlu di-escape karena menjadi karakter khusus atau kata yang sudah digunakan sistem.

Misalnya, kueri berikut ini tidak valid dalam SQL karena periode dalam tabel nama.

  -- ERROR: Table name format not supported

  SELECT * FROM my.table WHERE _key = 'r1'

Namun, Anda dapat mengatasi masalah ini dengan mengapit item dengan {i>backtick<i} (`).

  SELECT * FROM `my.table` WHERE _key = 'r1'

Jika kata kunci yang dicadangkan SQL digunakan sebagai pengidentifikasi, kata kunci ini juga dapat di-escape.

  SELECT * FROM `select` WHERE _key = 'r1'

Menggunakan SQL dengan library klien Bigtable

Library klien Bigtable untuk mendukung kueri Java dan Python 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. Sebagai informasi selengkapnya tentang penggunaan, lihat executeQuery, Pernyataan, 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"])

Langkah selanjutnya