Membandingkan DML dan Mutasi

Bahasa Manipulasi 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 itu Bahasa Manipulasi Data (DML)?

Bahasa Manipulasi Data (DML) di Spanner memungkinkan Anda memanipulasi data di 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 mengetahui informasi selengkapnya, termasuk contoh kode, lihat Menggunakan DML

  • DML Terpartisi - dirancang untuk update dan penghapusan massal seperti pada 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 dengan nilai NULL.

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

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

Apa itu 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 diterapkan ke 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 tersebut untuk meng-commit penulisan. Setiap perubahan diterapkan sesuai 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 merangkum DML dan dukungan mutasi untuk operasi dan fitur database umum.

Operasi DML Mutasi
Sisipkan Data Didukung Didukung
Menghapus Data Didukung Didukung
Mengupdate Data Didukung Didukung
Menyisipkan atau Abaikan Data Didukung Tidak Didukung
Bacakan Tulisan Anda (RYW) Didukung Tidak Didukung
Menyisipkan atau Memperbarui Data (Pembaruan) Didukung Didukung
Sintaksis SQL Didukung Tidak Didukung
Pemeriksaan batasan Setelah setiap pernyataan Pada waktu commit

DML dan mutasi berbeda dalam dukungannya untuk fitur berikut:

  • Membaca Tulisan Anda: Membaca hasil yang tidak 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 penggunaan mutasi, saat perubahan 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 di 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.

  • Constraint Check: Spanner memeriksa batasan setelah setiap pernyataan DML. Hal ini berbeda dengan menggunakan mutasi, di mana Spanner men-buffer mutasi di klien hingga melakukan commit dan memeriksa batasan pada waktu commit. Dengan mengevaluasi batasan setelah setiap pernyataan DML, Spanner dapat menjamin bahwa data yang ditampilkan oleh kueri berikutnya dalam transaksi yang sama akan menampilkan data yang konsisten dengan skema.

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

Praktik terbaik - hindari pencampuran 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 perlu memperhitungkan urutan eksekusi dalam kode library klien, Anda harus menggunakan pernyataan DML atau mutasi dalam satu transaksi, tetapi tidak keduanya.

Contoh Java berikut mengilustrasikan perilaku yang berpotensi mengejutkan. Kode menyisipkan dua baris ke dalam Album menggunakan Mutation API. Cuplikan, lalu 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 mengeksekusi kode ini, Anda akan melihat 0 data diperbarui. Mengapa demikian? Hal ini terjadi karena perubahan yang kita buat menggunakan Mutasi tidak terlihat oleh pernyataan berikutnya hingga transaksi di-commit. Idealnya, kita harus memiliki operasi tulis yang di-buffer hanya di akhir transaksi.

Apa langkah selanjutnya?