Algoritma untuk menentukan transaksi di antara seri data mingguan?


9

Saya mencoba mengembangkan alat pelaporan kecil (dengan backlite sqlite). Saya bisa menggambarkan alat ini sebagai buku besar "transaksi". Apa yang saya coba lakukan adalah melacak "transaksi" dari ekstrak data mingguan:

  • "baru" (atau tambahkan) - sumber daya baru untuk aplikasi saya karena aplikasi saya mungkin belum melacak sumber ini sebelumnya karena belum terlihat melalui ekstrak.
  • "perbarui" (atau klik) - ada penggunaan sumber daya itu baru-baru ini, perbarui periode penyimpanan seminggu lagi.
  • "delete" (atau drop) - item ini tidak digunakan sejak laporan terakhir (opsional, tetapi akan menyenangkan untuk membuat grafik perubahan permintaan dari minggu ke minggu untuk sumber daya).

Yang saya dapatkan hanyalah ekstrak data mingguan (flat-delimited file flat) yang berasal dari sistem pengarsipan / manajemen catatan lama yang tidak dapat saya kendalikan.

Setiap baris dapat didistilasi pada dasarnya ini:
resource_id | resource info | customer_id | customer_info

Contoh data:

10| Title X       | 1 | Bob
11| Another title | 1 | Bob
10| Title X       | 2 | Alice

Tujuannya adalah memudahkan untuk melaporkan sumber daya yang belum terlihat digunakan selama X-bulan (berdasarkan hit terakhir). Ada periode retensi di mana sumber daya disimpan untuk memudahkan akses jika populer. Sumber daya yang tidak terlihat digunakan selama 18 bulan ditandai untuk arsip jangka panjang di tempat lain.

Ini pasti masalah umum. Ingin tahu apakah ada algoritma tujuan umum untuk menentukan apa yang baru / sama / dihapus antara set data (db vs ekstrak terbaru)?

Jawaban:


1

Jawaban Anda adalah ... Ya. Ada algoritma sederhana yang dapat Anda terapkan yang tidak memerlukan hal-hal lain itu. Ini adalah algoritma net present value. Sangat mudah untuk diimplementasikan dan yang dibutuhkan di DB adalah Anda memberi cap tanggal pada data mingguan dan menulis satu query sederhana dan satu fungsi rekursif kecil atau untuk loop, atau Anda bisa melakukan salah satu solusi lain.

NPV = PV- (PV (CP / T) atau Nilai Present Baru sama dengan Nilai Sekarang dikali Periode Saat Ini (bulan sejak entri terakhir) dibagi dengan istilah (misalnya 18 bulan) ketika nilai sumber daya turun ke 0 itu nilai bersih sekarang dikeluarkan.

Jika Anda memberi saya bahasa yang Anda inginkan di saya akan memposting kode di sini di edit


Bahasa tidak begitu penting. Ruby atau C ++ jika saya harus memilih. Jika Anda dapat menulis algoritma dalam HTML 4.0 Strict Anda akan menjadi pahlawan saya. Bercanda tentang bagian terakhir :)
Swartz

Akan tertarik melihat kodenya. Ruby atau C ++. Terima kasih.
Swartz

0

Jika Anda tetap menyimpan pembaruan dalam backend SQLite, Anda bisa mengubah pembaruan mingguan menjadi tabel baru dan membandingkannya dengan data yang diarsipkan dengan kueri, sebelum menggabungkannya.

Contoh menggunakan SQL untuk menemukan tambahan baru ke tabel: /programming/2077807/sql-query-to-return-differences-between-two-tables

Jika bidang di DB Anda menyimpan tanggal transaksi, Anda bisa menanyakan semua pengguna yang telah melakukan transaksi dalam 18 bulan terakhir. Maka arsipnya hanyalah DB penuh. Atau, Anda dapat meminta semua pengguna yang belum, mengekstrak datanya, lalu menjatuhkannya. Pembaruan hanyalah setiap baris waktu yang dicentang minggu ini.


Lebih baik, ini adalah solusi data-sentris setidaknya, tapi masih berlebihan
J-Boss

Saya menggunakan sqlite untuk sementara karena mudah untuk memulainya. Bisa dengan mudah beralih ke MySQL (atau PostgreSQL). Jika menggunakan backend no-SQL akan menghasilkan apa saja untuk membuat pekerjaan ini lebih baik, saya dengar.
Swartz

Nah, pemikiran saya terutama bahwa Anda mengubahnya menjadi baris dalam database pula . Jika Anda tidak perlu menjalankannya dari beberapa proses secara bersamaan, saya tidak berpikir Anda ingin beralih ke sesuatu yang lebih berat daripada SQLite.
Davislor

Tidak perlu untuk pemrosesan bersamaan. Tapi saya perlu menyimpan data tentang sumber daya di suatu tempat. SQL db sepertinya pilihan yang baik, Namun, tidak ada yang mencegah saya memuat data ke dalam jenis data apa pun untuk memproses delta. Yang saya inginkan pada akhir setiap ekstrak dijalankan adalah untuk mencari tahu apa yang baru, apa yang tetap sama, dan apa yang telah hilang. Saya bisa mencari cara memperbarui catatan yang diperlukan dari info ini.
Swartz

Setelah Anda mengurai data dan memasukkannya ke dalam basis data, mungkin lebih mudah untuk menulis kueri daripada mengimplementasikan algoritma. Yang mengatakan, jika Anda ingin kode itu, algoritma yang Anda inginkan adalah perbedaan set dan ada implementasi di C ++ STL yang dapat Anda gunakan untuk melakukannya dalam satu baris setelah Anda memasukkan kedua set data ke dalam wadah pilihan Anda, mungkin a Vector.
Davislor

0

Ide alternatif:

  1. Parsing daftar transaksi Anda ke dalam beberapa jenis struktur data, seperti sebuah array. (Dalam C ++, pikirkan Vector, dan di Jawa ArrayList,.)

  2. Lakukan kueri pada SQL backend Anda seperti SELECT DISTINCT customer_id FROM Transactions ORDER BY customer_iddan kemas ID pelanggan berbeda yang diurutkan ke dalam satu set old,. Jika Anda melakukan hal yang sama persis dengan WHEREklausa yang memisahkan transaksi lama dan baru, Anda dapat melewati langkah 3.

  3. Dapatkan ID pelanggan unik dari pembaruan baru ke dalam struktur data yang terpisah, dalam urutan diurutkan. Ada beberapa struktur data yang bisa Anda gunakan untuk masuk ke dalam struktur data new,. Urutan penyisipan ke dalam daftar ditautkan ganda sangat sederhana, tetapi menggunakan hashtable antara akan berjalan mendekati waktu linier, atau jika Anda tetap menyortir larik asli, mendapatkan seperangkat yang mudah.

  4. Ambil perbedaan set new- oldmenggunakan perpustakaan standar bahasa favorit Anda. Bahasa favorit Anda memang memiliki algoritma ini di perpustakaan standarnya?

Hal-hal lain yang ingin Anda lakukan adalah pertanyaan SQL setelah Anda memperbarui basis data transaksi Anda.

Catatan pada langkah 3: Pertimbangkan sifat data Anda. Misalkan file teks Anda mencantumkan pesanan secara kronologis, dan dalam minggu-minggu biasa, ada banyak pelanggan baru yang diberi pesanan baru customer_iddalam urutan menaik. Misalkan sebagian besar pesanan lainnya berasal dari sejumlah kecil pelanggan setia, dengan yang lebih rendah customer_id. Maka input Anda sudah sebagian besar diurutkan. Jenis penyisipan di mana Anda mencoba memasukkan rendah customer_iddi depan daftar ditautkan ganda dan tinggi customer_iddi belakang akan, dalam situasi itu, berkinerja baik dalam praktek.


1
Aku lebih tertarik pada baru / sama / diupdate sumber daripada pelanggan. Tapi ya, idenya akan sama.
Swartz

0

Seperti yang saya mengerti dari pertanyaan Anda, Anda sebenarnya memiliki resource_id (+ info) dan "daftar" pelanggan (id + info).

Jadi Anda dapat dengan mudah menyimpan Daftar pelanggan per sumber daya dan memeriksa simpul terakhir di setiap daftar pada sumber daya (untuk mengetahui waktu operasi terakhir; Anda hanya perlu menambahkan bidang tanggal ke pelanggan Anda dalam kode)

Saya tidak terbiasa dengan SQL, oleh karena itu saya memberikan contoh saya dengan HashMapdan Daftar tapi saya yakin itu ide yang sama:, HashMap <Resource, List<Customer>>kapan Resourceharus mengandung resourceID sebagai kunci dan Customerharus berisi ID pelanggan, info dan tanggal operasi.

Dengan ide ini Anda dapat dengan mudah mengetahui waktu pengoperasian terakhir dan dapat memodifikasi sumber daya apa pun (tambahkan \ hapus sumber daya \ pelanggan).


0

Jika Anda menggunakan database SqLite, jika Anda menambahkan tanggal batch juga sebagai kolom tabel,

10| Title X       | 1 | Bob    | 2015-03-01
11| Another title | 1 | Bob    | 2015-03-01
...............................
10| Title X       | 1 | Alice  | 2015-03-05

akan sangat mudah untuk menggunakan SQL untuk mendapatkan sumber daya yang tidak digunakan dalam X hari terakhir

Select distinct r.ResourceID from Resources r
where not exists (SELECT julianday('now') - julianday(r.DateUpdated)) < X

Saya belum menguji SQL tetapi harus memberi Anda ide


0

Dari posting asli, kedengarannya seperti data yang dicerna tidak memiliki bidang untuk menunjukkan tanggal / waktu transaksi, dan saya kira file tersebut dicerna secara berkala berdasarkan jadwal seperti harian, jam, dll.

Saya akan menangani ini dengan menambahkan kolom timestamp SQL yang dapat dibuat secara otomatis pada tingkat basis data, atau dengan kode yang mengekstrak data dan memasukkan ke dalam DB. Kemudian Anda meletakkan indeks pada kolom cap waktu itu dan selesai dengan itu. Biarkan mesin DB melakukan tugasnya agar efisien untuk menjawab pertanyaan "berapa banyak transaksi yang belum terjadi sejak saat ini", atau "berapa banyak antara waktu ini dan waktu itu".

Kemudian Anda menjadwalkan pekerjaan untuk meminta dan menghitung perbedaan yang ingin Anda laporkan. Transaksi yang "baru" adalah transaksi yang tidak memiliki catatan dalam DB sebelum tanggal Anda menanyakan "baru sejak". Catatan lama adalah catatan yang tidak memiliki transaksi sejak tanggal cut-off.


-2

Bukankah ini untuk apa HashTables? Jika semua yang ingin Anda lakukan adalah menyimpan catatan sumber daya mana yang telah digunakan dalam beberapa bulan terakhir dan menghapus sumber daya yang belum diakses dalam 18 bulan terakhir maka Anda dapat menggunakan HashTable di mana Kuncinya adalah resource_id dan nilainya adalah tanggal akses terakhir.

Untuk pengarsipan catatan> 18 bulan, Anda bisa menelusuri semua catatan di tabel hash dan hanya menghapus (atau memindahkan) catatan spesifik tersebut. (Anda dapat melakukan ini setiap minggu saat laporan masuk)


Mengapa perlunya HashTable jika saya menyimpan barang di database? Saya dapat melakukan pembaruan pada catatan db. Saya lebih tertarik pada suatu kasus: ambil dua set data, cari tahu perbedaannya (apa yang ditambahkan, tetap sama, dihapus) antara dua set. Bagaimana teknik HashTable membantu dalam menemukan catatan baru dan "dihapus"?
Swartz

Jika tabel diindeks dalam database maka mereka pada dasarnya juga HashTables di belakang layar. Jika Anda memiliki 2 tabel, masing-masing mewakili kumpulan data maka Anda bisa mendapatkan catatan baru dan yang dihapus dengan melakukan beberapa gabungan luar. Lihat ini untuk referensi: i.stack.imgur.com/pxUO3.png . Pastikan Anda memiliki indeks pada kolom resource_id dan itu harus cukup cepat. Jika Anda harus menerapkan ini dari awal maka saya pikir HashTables masih akan menjadi cara untuk pergi karena Anda dapat melakukan pencarian / penyisipan / penghapusan dalam O (1) waktu diamortisasi. Tidak dapat memikirkan cara yang lebih efisien untuk melakukan ini.
Adrian Buzea

3
Ada struktur data yang lebih baik yang menangani penuaan tanpa langkah-langkah tambahan menjejalkan ini ke tabel hash.

Mau menyebutkan beberapa?
Adrian Buzea

@Snowman - Saya berharap saya bisa menilai itu beberapa kali lagi, saya hanya akan dengan tegas setuju dalam komentar ini
J-Boss
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.