Saya mencari untuk menyimpan daftar yang diurutkan di dalam database. Saya ingin melakukan operasi berikut secara efisien.
- Sisipkan (x) - Sisipkan catatan x ke dalam tabel
- Delete (x) - Hapus record x dari tabel
- Sebelum (x, n) - Mengembalikan catatan 'n' sebelum catatan x dalam daftar yang diurutkan.
- After (x, n) - Mengembalikan catatan 'n' yang menggantikan catatan x dalam daftar yang diurutkan.
- First (n) - Mengembalikan catatan 'n' pertama dari daftar yang diurutkan.
- Terakhir (n) - Mengembalikan catatan 'n' terakhir dari daftar yang diurutkan.
- Bandingkan (x, y) - Diberikan dua catatan x dan y dari tabel, cari apakah x> y.
Metode sederhana yang bisa saya pikirkan adalah untuk menyimpan semacam atribut 'peringkat' dalam tabel dan permintaan dengan mengurutkan atribut tersebut. Tetapi dalam metode ini memasukkan / memodifikasi catatan dengan peringkat menjadi operasi yang mahal. Apakah ada metode yang lebih baik?
Secara khusus, saya ingin mengimplementasikan tabel menggunakan SimpleDB Amazon. Tetapi jawaban umum untuk database relasional juga harus membantu.
Perbarui profil yang dimuat:
Karena saya merencanakan ini untuk aplikasi web, itu tergantung pada jumlah pengguna yang menggunakan aplikasi.
Jika ada 100k pengguna aktif (super optimisme: P), maka perkiraan saya yang sangat per hari akan menjadi
500k memilih, 100k menyisipkan dan menghapus, pembaruan 500k
Saya berharap meja tumbuh total hingga 500 ribu.
Saya mencari untuk mengoptimalkan pada pembaruan, masukkan dan operasi Bandingkan. Peringkat item akan terus berubah dan saya harus terus memperbarui tabel.
sumber
Jawaban:
Jika peringkat tidak sepenuhnya arbitrer tetapi dapat diturunkan dari beberapa properti lain (mis. Nama, skor pemain, dll.) Maka perhatikan baik-baik jawaban Joel .
Jika itu adalah properti sewenang-wenang dari data Anda, maka itu harus disimpan sebagai kolom di tabel catatan Anda. Dengan asumsi SimpleDB Amazon mirip dengan RDBMS biasa, Anda kemudian dapat mengindeks kolom ini dan dengan cepat memenuhi semua pertanyaan Anda di atas dengan strategi pengindeksan yang sesuai. Ini normal untuk RDBMS.
Mengingat Anda mengharapkan aktivitas memasukkan dan memperbarui yang tinggi, tetapi juga aktivitas membaca yang relatif tinggi, saya sarankan melakukan hal berikut:
INCLUDE
-ing peringkat, atau hanya merekam jika Anda sudah mengelompokkan pada peringkat) akan memenuhi permintaan 7.FILLFACTOR
dalam SQL Server). Ini sangat penting jika Anda mengelompokkan berdasarkan peringkat.Jika Anda mengharapkan 100K + membaca tabel berukuran 100K + saya tidak merekomendasikan menggunakan pendekatan daftar tertaut. Itu tidak akan skala dengan baik untuk ukuran-ukuran itu.
sumber
FILLFACTOR
Anda akan melihatnya pada dasarnya dimaksudkan untuk membuat ruang ekstra untuk catatan dalam indeks, sama seperti kesenjangan peringkat yang saya jelaskan membuat ruang untuk perubahan dan penyisipan peringkat.Saya biasanya menggunakan metode "peringkat" yang Anda jelaskan. Daripada main-main dengan memperbarui baris ketika item perlu dipesan ulang saya sering bisa lolos dengan menghapus semua catatan dalam daftar dan memasukkan kembali item baru dalam urutan yang tepat. Metode ini jelas dioptimalkan untuk pengambilan.
Pendekatan alternatif adalah memodelkan catatan sebagai daftar tertaut dengan menggunakan kolom kunci asing refleksif "pendahulu" pada tabel:
Anda dapat dengan mudah mengambil daftar dan menambah dan menghapus item dengan sedikit overhead, tetapi mengeluarkan catatan dalam urutan yang tepat akan sulit. Mungkin ada cara cerdas untuk melakukannya dalam satu permintaan, mungkin dengan banyak gabungan tabel alias.
Saya menggunakan pendekatan terakhir ini sering ketika saya memodelkan hubungan gaya pohon (kategori, folder, set dan himpunan bagian). Saya biasanya memiliki fungsi rekursif semacam untuk merekonstruksi pohon lengkap dalam aplikasi saya.
sumber
Saya akan berpikir hal yang harus dilakukan adalah menyimpan properti atau properti yang digunakan untuk menghitung peringkat dan kemudian membangun indeks di atasnya. Daripada mencoba memaksa database untuk secara fisik menyimpan data dalam urutan peringkat atau menggunakan daftar tertaut yang dikelola secara manual, mengapa tidak membiarkan mesin database melakukan apa yang dirancang untuk dilakukan?
sumber
Ini adalah keterbatasan non-RDBMS seperti simpleDB. Fitur yang Anda butuhkan tidak dapat diimplementasikan pada sisi DB di simpleDB, mereka harus diimplementasikan dari sisi pemrograman / aplikasi.
Untuk RDBMS seperti
SQL server
, fitur yang Anda butuhkan belum sempurna untuk indeks berkerumun.Sebelum (x, n) - Mengembalikan catatan 'n' sebelum catatan x dalam daftar yang diurutkan. > Pilih n atas hasil di mana x kurang dari nilai dan urutan dengan klausa.
After (x, n) - Mengembalikan catatan 'n' yang menggantikan catatan x dalam daftar yang diurutkan. > Pilih n atas hasil di mana x lebih besar dari nilai dan urutan dengan klausa.
First (n) - Mengembalikan catatan 'n' pertama dari daftar yang diurutkan. > Pilih n hasil atas.
Terakhir (n) - Mengembalikan catatan 'n' terakhir dari daftar yang diurutkan. > Pilih n atas hasil setelah pesanan oleh desc.
sumber
Inilah yang saya gunakan untuk memberi peringkat ulang tabel Postgres saya setelah setiap sisipan:
Untuk kasus penggunaan saya, kinerja bukan masalah, tetapi keyakinan bahwa itu tidak akan pernah rusak atau bertindak aneh adalah penting.
sumber