Mendesain untuk kueri
Solusi layanan Table dapat dibaca secara intensif, ditulis secara intensif, atau gabungan keduanya. Artikel ini berfokus pada hal-hal yang perlu diingat ketika Anda merancang layanan Table Anda, untuk mendukung operasi baca secara efisien. Biasanya, desain yang mendukung operasi baca secara efisien juga efisien untuk operasi tulis. Namun, ada pertimbangan tambahan yang perlu diingat ketika merancang untuk mendukung operasi tulis, dibahas dalam artikel Desain untuk modifikasi data.
Titik awal yang baik untuk merancang solusi layanan Table Anda untuk memungkinkan Anda membaca data secara efisien adalah bertanya "Kueri apa yang perlu dijalankan aplikasi saya untuk mengambil data yang dibutuhkan dari layanan Table?"
Catatan
Dengan layanan Table, penting untuk memperbaiki desain di awal karena sulit dan mahal untuk mengubahnya nanti. Misalnya, dalam database hubungan sering dimungkinkan untuk mengatasi masalah kinerja hanya dengan menambahkan indeks ke database yang ada: ini bukan opsi terkait layanan Table.
Bagian ini berfokus pada masalah utama yang harus Anda tangani saat mendesain tabel untuk pembuatan kueri. Topik yang dibahas di bagian ini meliputi:
- Bagaimana pilihan PartitionKey dan RowKey Anda memengaruhi performa kueri
- Memilih PartitionKey yang sesuai
- Mengoptimalkan kueri untuk layanan Table
- Mengurutkan data dalam layanan Table
Bagaimana pilihan PartitionKey dan RowKey Anda memengaruhi performa kueri
Contoh berikut mengasumsikan layanan tabel menyimpan entitas karyawan dengan struktur berikut (sebagian besar contoh menghilangkan properti Timestamp untuk kejelasan):
Nama kolom | Jenis data |
---|---|
PartitionKey (Nama Departemen) | String |
RowKey (ID Karyawan) | String |
NamaDepan | String |
NamaBelakang | String |
Usia | Bilangan bulat |
AlamatEmail | String |
Artikel Ikhtisar penyimpanan Azure Table menjelaskan beberapa fitur utama layanan Azure Table yang memiliki pengaruh langsung pada desain untuk kueri. Hasil ini dapat dilihat dalam panduan umum berikut untuk mendesain kueri layanan Table. Perhatikan bahwa sintaks filter yang digunakan dalam contoh di bawah ini adalah dari layanan Table REST API, untuk informasi selengkapnya, lihat Entitas Kueri.
- Point Query adalah pencarian paling efisien untuk digunakan dan direkomendasikan untuk digunakan untuk pencarian volume tinggi atau pencarian yang membutuhkan latensi terendah. Kueri seperti itu dapat menggunakan indeks untuk menemukan entitas individu dengan sangat efisien dengan menetapkan nilai PartitionKey dan RowKey. Misalnya: $filter=(PartitionKey eq 'Sales') dan (RowKey eq '2')
- Terbaik kedua adalah Range Query yang menggunakan PartitionKey dan memfilter pada rentang nilai RowKey untuk mengembalikan lebih dari satu entitas. Nilai PartitionKey mengidentifikasi partisi tertentu, dan nilai RowKey mengidentifikasi subset entitas dalam partisi tersebut. Misalnya: $filter=PartitionKey eq 'Sales' and RowKey ge 'S' dan RowKey lt 'T'
- Terbaik ketiga adalah Partition Scan yang menggunakan PartitionKey dan memfilter pada properti non-kunci lain dan yang dapat mengembalikan lebih dari satu entitas. Nilai PartitionKey mengidentifikasi partisi tertentu, dan nilai properti memilih subset dari entitas di partisi tersebut. Misalnya: $filter=PartitionKey eq 'Sales' dan LastName eq 'Smith'
- Table Scan tidak mencakup PartitionKey dan sangat tidak efisien karena akan mencari semua partisi yang membentuk tabel Anda secara bergantian untuk entitas yang cocok. Ini akan melakukan pemindaian tabel terlepas dari apakah filter Anda menggunakan RowKey. Misalnya: $filter=LastName eq 'Jones'
- Kueri yang mengembalikan beberapa entitas, mengembalikannya diurutkan dalam urutan PartitionKey dan RowKey. Untuk menghindari penggunaan entitas di klien, pilih RowKey yang menentukan susunan urutan yang paling umum.
Perhatikan bahwa menggunakan "atau" untuk menentukan filter berdasarkan nilai RowKey menghasilkan pemindaian partisi dan tidak diperlakukan sebagai kueri rentang. Oleh karena itu, Anda harus menghindari kueri yang menggunakan filter seperti: $filter=PartitionKey eq 'Sales' dan (RowKey eq '121' atau RowKey eq '322')
Untuk contoh kode di sisi klien yang menggunakan Storage Client Library untuk menjalankan kueri yang efisien, lihat:
- Menjalankan kueri titik menggunakan Storage Client Library
- Mengambil beberapa entitas menggunakan LINQ
- Proyeksi di sisi server
Misalnya, kode sisi klien yang dapat menangani beberapa jenis entitas yang disimpan dalam tabel yang sama, lihat:
Memilih PartitionKey yang sesuai
Pilihan PartitionKey Anda harus menyeimbangkan kebutuhan untuk memungkinkan penggunaan transaksi grup entitas (untuk memastikan konsistensi) terhadap persyaratan untuk mendistribusikan entitas Anda di beberapa partisi (untuk memastikan solusi yang dapat diskalakan).
Pada satu kondisi ekstrem, Anda dapat menyimpan semua entitas Anda dalam satu partisi, tetapi ini dapat membatasi skalabilitas solusi Anda, dan akan mencegah layanan tabel dalam menyeimbangkan beban permintaan. Pada kondisi ekstrem lainnya, Anda dapat menyimpan satu entitas per partisi, yang akan sangat dapat diskalakan, dan memungkinkan layanan tabel untuk menyeimbangkan beban permintaan, tetapi yang akan mencegah Anda dari menggunakan transaksi grup entitas.
PartitionKey yang ideal adalah yang memungkinkan Anda menggunakan kueri yang efisien dan memiliki partisi yang cukup untuk memastikan solusi Anda dapat diskalakan. Biasanya, Anda akan menemukan bahwa entitas Anda akan memiliki properti yang cocok, yang mendistribusikan entitas Anda di seluruh partisi yang memadai.
Catatan
Misalnya, dalam sistem yang menyimpan informasi tentang pengguna atau karyawan, UserID mungkin merupakan PartitionKey yang baik. Anda mungkin memiliki beberapa entitas yang menggunakan UserID tertentu sebagai kunci partisi. Setiap entitas yang menyimpan data tentang pengguna dikelompokkan ke dalam satu partisi, sehingga entitas ini dapat diakses melalui transaksi grup entitas, sementara masih sangat terukur.
Ada pertimbangan tambahan dalam pilihan PartitionKey Anda dengan bagaimana Anda akan menyisipkan, memperbarui, dan menghapus entitas. Untuk informasi selengkapnya, lihat Mendesain tabel untuk modifikasi data.
Mengoptimalkan kueri untuk layanan Table
Layanan Table secara otomatis mengindeks entitas Anda menggunakan nilai PartitionKey dan RowKey dalam satu indeks terkluster, karenanya alasan kueri titik adalah yang paling efisien untuk digunakan. Namun, tidak ada indeks selain itu pada indeks terkluster pada PartitionKey dan RowKey.
Banyak desain yang harus memenuhi persyaratan untuk mengaktifkan pencarian entitas berdasarkan beberapa kriteria. Misalnya, menemukan entitas karyawan berdasarkan email, ID karyawan, atau nama belakang. Pola yang dijelaskan dalam Pola Desain Table membahas jenis persyaratan ini, dan menjelaskan cara mengatasi fakta bahwa layanan Table tidak menyediakan indeks sekunder:
- Pola indeks sekunder intra-partisi - Simpan beberapa salinan setiap entitas menggunakan nilai RowKey yang berbeda (dalam partisi yang sama), untuk memungkinkan pencarian yang cepat dan efisien dan urutan pengurutan alternatif dengan menggunakan nilai RowKey yang berbeda.
- Pola indeks sekunder inter-partisi - Simpan beberapa salinan setiap entitas menggunakan nilai RowKey yang berbeda dalam partisi berbeda atau tabel berbeda, untuk memungkinkan pencarian yang cepat dan efisien dan urutan pengurutan alternatif dengan menggunakan nilai RowKey yang berbeda.
- Pola Entitas Indeks - Memelihara entitas indeks untuk memungkinkan pencarian efisien yang mengembalikan daftar entitas.
Mengurutkan data dalam layanan Table
Layanan Tabel mengembalikan entitas yang diurutkan dalam urutan naik berdasarkan PartitionKey lalu dengan RowKey. Kunci ini adalah nilai string dan untuk memastikan bahwa nilai numerik diurutkan dengan benar, Anda harus mengonversinya ke panjang tetap dan mengalihkannya dengan nol. Misalnya, jika nilai ID karyawan yang Anda gunakan sebagai RowKey adalah nilai bilangan bulat, Anda harus mengonversi ID karyawan 123 menjadi 00000123.
Banyak aplikasi memiliki persyaratan untuk menggunakan data yang diurutkan dalam pesanan yang berbeda: misalnya, mengurutkan karyawan berdasarkan nama, atau dengan menggabungkan tanggal. Pola berikut ini membahas cara mengubah urutan pesanan untuk entitas Anda:
- Pola indeks sekunder intra-partisi - Simpan beberapa salinan setiap entitas menggunakan nilai RowKey yang berbeda (dalam partisi yang sama), untuk memungkinkan pencarian yang cepat dan efisien dan urutan pengurutan alternatif dengan menggunakan nilai RowKey yang berbeda.
- Pola indeks sekunder inter-partisi - Simpan beberapa salinan setiap entitas menggunakan nilai RowKey yang berbeda dalam partisi berbeda atau tabel berbeda, untuk memungkinkan pencarian yang cepat dan efisien dan urutan pengurutan alternatif dengan menggunakan nilai RowKey yang berbeda.
- Pola ekor log - Ambil entitas n yang terakhir ditambahkan ke partisi dengan menggunakan nilai RowKey yang mengurutkan dalam urutan tanggal dan waktu terbalik.