Membandingkan DML dan Mutasi

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

Apa yang dimaksud dengan Bahasa Pengolahan 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, konsolGoogle 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 yang dipartisi - dirancang untuk update dan penghapusan massal seperti dalam contoh berikut.

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

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

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

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

Apa itu mutasi?

Mutasi merepresentasikan urutan penyisipan, pembaruan, dan penghapusan yang diterapkan Spanner secara atomik ke baris dan tabel yang berbeda 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 untuk 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
Penerapan batas mutasi (termasuk indeks) Per pernyataan (direset setelah eksekusi) Per commit (kumulatif)

DML dan mutasi berbeda dalam dukungan untuk fitur berikut:

  • Baca Penulisan Anda: Membaca hasil yang belum di-commit dalam transaksi aktif. Perubahan yang Anda buat menggunakan pernyataan DML dapat dilihat oleh pernyataan berikutnya dalam transaksi yang sama. Hal ini berbeda dengan penggunaan mutasi, di mana 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.

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

  • Penerapan Batas Mutasi: Untuk DML, batas mutasi 80.000 (termasuk indeks) diterapkan per pernyataan dan direset setelah pernyataan dijalankan. Dengan demikian,satu transaksi dapat menjalankan beberapa pernyataan DML yang secara kolektif melebihi 80.000 mutasi, selama tidak ada satu pun pernyataan yang melebihi batas. Untuk Mutation API, yang hanya dapat digunakan sebagai bagian dari operasi commit, batas 80.000 mutasi (termasuk indeks) bersifat kumulatif di semua mutasi dalam commit. Kedua metode tunduk pada batas ukuran transaksi 100 MiB.

  • 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. Untuk menghindari 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 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 hanya boleh melakukan penulisan yang di-buffer di akhir transaksi.

Apa langkah selanjutnya?