Membandingkan DML dan Mutasi

Bahasa Pengolahan Data (DML) dan Mutasi adalah dua API di Spanner yang dapat Anda gunakan untuk mengubah data. Masing-masing menawarkan fitur manipulasi data yang serupa. Halaman ini membandingkan kedua pendekatan tersebut.

Apa yang dimaksud dengan Bahasa Manipulasi Data (DML)?

Bahasa Pengolahan Data (DML) di Spanner memungkinkan Anda memanipulasi data dalam tabel database menggunakan pernyataan INSERT, UPDATE, dan DELETE. Anda dapat menjalankan pernyataan DML menggunakan library klien, Konsol Google Cloud, dan gcloud spanner.

Spanner menawarkan dua implementasi eksekusi DML berikut, masing-masing dengan properti yang berbeda.

  • DML Standar - cocok untuk workload Pemrosesan Transaksi Online (OLTP) standar.

    Untuk informasi selengkapnya, termasuk contoh kode, lihat Menggunakan DML

  • DML yang dipartisi - dirancang untuk pembaruan dan penghapusan massal seperti dalam contoh berikut.

    • Pembersihan berkala dan pembersihan sampah memori. Contohnya adalah menghapus baris lama atau menetapkan kolom ke NULL.

    • Mengisi ulang kolom baru dengan nilai default. Contohnya adalah menggunakan pernyataan UPDATE untuk menetapkan nilai kolom baru ke False jika nilainya NULL.

    Untuk mengetahui informasi selengkapnya, termasuk contoh kode, lihat Menggunakan DML yang Dipartisi.

    Anda dapat menggunakan penulisan batch untuk operasi tulis dalam jumlah besar tanpa operasi baca yang tidak memerlukan transaksi atomik. Untuk mengetahui informasi selengkapnya, lihat Mengubah data menggunakan operasi tulis batch.

Apa yang dimaksud dengan mutasi?

Mutasi mewakili urutan penyisipan, pembaruan, dan penghapusan yang diterapkan Spanner secara atomik ke berbagai baris dan tabel dalam database. Anda dapat menyertakan operasi yang berlaku untuk baris yang berbeda, atau tabel yang berbeda, dalam mutasi. Setelah menentukan satu atau beberapa mutasi yang berisi satu atau beberapa penulisan, Anda harus menerapkan mutasi untuk melakukan penulisan. Setiap perubahan diterapkan dalam urutan penambahannya ke mutasi.

Untuk mengetahui informasi selengkapnya, termasuk contoh kode, lihat Menyisipkan, memperbarui, dan menghapus data menggunakan mutasi.

Perbandingan fitur antara DML dan mutasi

Tabel berikut meringkas dukungan DML dan mutasi dari operasi dan fitur database umum.

Operasi DML Mutasi
Menyisipkan Data Didukung Didukung
Hapus Data Didukung Didukung
Mengupdate Data Didukung Didukung
Menyisipkan atau Mengabaikan Data Didukung Tidak Didukung
Read Your Writes (RYW) Didukung Tidak Didukung
Menyisipkan atau Memperbarui Data (Upsert) Didukung Didukung
Sintaksis SQL Didukung Tidak Didukung
Pemeriksaan batasan Setelah setiap pernyataan Pada waktu commit

DML dan mutasi berbeda dalam dukungannya untuk fitur berikut:

  • Read Your Writes: Membaca hasil yang belum di-commit dalam transaksi aktif. Perubahan yang Anda buat menggunakan pernyataan DML akan terlihat oleh pernyataan berikutnya dalam transaksi yang sama. Hal ini berbeda dengan menggunakan mutasi, yang perubahannya tidak terlihat dalam pembacaan apa pun (termasuk pembacaan yang dilakukan dalam transaksi yang sama) hingga transaksi di-commit. Hal ini karena mutasi dalam transaksi di-buffer sisi klien (secara lokal) dan dikirim ke server sebagai bagian dari operasi commit. Akibatnya, mutasi dalam permintaan commit tidak terlihat oleh pernyataan SQL atau DML dalam transaksi yang sama.

  • Pemeriksaan Batasan: Spanner memeriksa batasan setelah setiap pernyataan DML. Hal ini berbeda dengan penggunaan mutasi, saat Spanner menyimpan mutasi dalam klien hingga commit dan memeriksa batasan pada waktu commit. Mengevaluasi batasan setelah setiap pernyataan DML memungkinkan Spanner untuk menjamin bahwa data yang ditampilkan oleh kueri berikutnya dalam transaksi yang sama menampilkan data yang konsisten dengan skema.

  • Sintaksis SQL: DML menyediakan cara konvensional untuk memanipulasi data. Anda dapat menggunakan kembali keterampilan SQL untuk mengubah data menggunakan DML API.

Praktik terbaik - hindari mencampur DML dan mutasi dalam transaksi yang sama

Jika transaksi berisi pernyataan DML dan mutasi dalam permintaan commit, Spanner akan mengeksekusi pernyataan DML sebelum mutasi. Agar tidak harus memperhitungkan urutan eksekusi dalam kode library klien, Anda harus menggunakan pernyataan DML atau mutasi dalam satu transaksi, tetapi tidak keduanya.

Contoh Java berikut menggambarkan perilaku yang berpotensi mengejutkan. Kode ini menyisipkan dua baris ke dalam Album menggunakan Mutation API. Cuplikan tersebut kemudian memanggil executeUpdate() untuk memperbarui baris yang baru disisipkan dan memanggil executeQuery() untuk membaca album yang diperbarui.

static void updateMarketingBudget(DatabaseClient dbClient) {
  dbClient
      .readWriteTransaction()
      .run(
          new TransactionCallable<Void>() {
            @Override
            public Void run(TransactionContext transaction) throws Exception {
               transaction.buffer(
                    Mutation.newInsertBuilder("Albums")
                        .set("SingerId")
                        .to(1)
                        .set("AlbumId")
                        .to(1)
                        .set("AlbumTitle")
                        .to("Total Junk")
                        .set("MarketingBudget")
                        .to(800)
                        .build());
               transaction.buffer(
                    Mutation.newInsertBuilder("Albums")
                        .set("SingerId")
                        .to(1)
                        .set("AlbumId")
                        .to(2)
                        .set("AlbumTitle")
                        .to("Go Go Go")
                        .set("MarketingBudget")
                        .to(200)
                        .build());

                // This UPDATE will not include the Albums inserted above.
                String sql =
                  "UPDATE Albums SET MarketingBudget = MarketingBudget * 2"
                      + " WHERE SingerId = 1";
                long rowCount = transaction.executeUpdate(Statement.of(sql));
                System.out.printf("%d records updated.\n", rowCount);

                // Read a newly updated record.
                sql =
                  "SELECT SingerId, AlbumId, AlbumTitle FROM Albums"
                      + " WHERE SingerId = 1 AND MarketingBudget < 1000";
                ResultSet resultSet =
                                 transaction.executeQuery(Statement.of(sql));
                while (resultSet.next()) {
                   System.out.printf(
                        "%s %s\n",
                        resultSet.getString("FirstName"),
                        resultSet.getString("LastName"));
                }
                return null;
              }
            });
}

Jika Anda menjalankan kode ini, Anda akan melihat 0 data diperbarui. Mengapa? Hal ini terjadi karena perubahan yang kita buat menggunakan Mutasi tidak terlihat oleh pernyataan berikutnya hingga transaksi di-commit. Idealnya, kita harus memiliki penulisan buffering hanya di bagian akhir transaksi.

Apa langkah selanjutnya?