Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

Lagi dan lagi! Mengelola Peristiwa Berulang Dalam Model Data

Peristiwa berulang, menurut definisi, adalah peristiwa yang berulang pada suatu interval; itu juga disebut peristiwa periodik. Ada banyak aplikasi yang memungkinkan penggunanya untuk mengatur acara berulang. Bagaimana sistem database mengelola acara yang berulang? Dalam artikel ini, kita akan mengeksplorasi satu cara penanganannya.

Pengulangan tidak mudah untuk aplikasi untuk menangani. Ini bisa menjadi tugas yang sulit, terutama jika harus mencakup setiap kemungkinan skenario berulang – termasuk membuat acara dua mingguan atau tiga bulanan atau mengizinkan penjadwalan ulang semua kejadian di masa mendatang.

Dua Cara untuk Mengelola Acara Berulang

Saya dapat memikirkan setidaknya dua cara untuk menangani tugas periodik dalam model data. Sebelum kita membahasnya, mari kita cepat membahas persyaratan tugas ini. Singkatnya, manajemen yang efektif berarti:

  • Pengguna diizinkan untuk membuat acara reguler dan berulang.
  • Acara harian, mingguan, dua mingguan, bulanan, triwulanan, dua tahunan, dan tahunan dapat dibuat tanpa batasan tanggal akhir.
  • Pengguna dapat menjadwal ulang atau membatalkan acara atau semua acara di masa mendatang.

Mempertimbangkan parameter ini, muncul dua cara untuk mengelola peristiwa berulang dalam model data. Kami akan menyebut mereka cara naif dan cara ahli.

Cara Naif: Menyimpan semua kemungkinan kejadian berulang dari suatu peristiwa sebagai baris terpisah dalam tabel. Dalam solusi ini, kami hanya membutuhkan satu tabel, yaitu event . Tabel ini memiliki kolom seperti event_title , start_date , end_date , is_full_day_event , dll. start_date dan end_date kolom adalah tipe data timestamp; dengan cara ini mereka dapat mengakomodasi acara yang tidak berlangsung sepanjang hari.

Pro: Ini adalah pendekatan yang cukup mudah dan paling sederhana untuk diterapkan.

Kekurangannya: Cara naif memiliki beberapa kelemahan yang signifikan, termasuk:

  • Kebutuhan untuk menyimpan semua kemungkinan kejadian dari suatu peristiwa. Jika Anda mempertimbangkan kebutuhan basis pengguna yang besar, maka diperlukan ruang yang besar. Namun, ruangnya cukup murah, jadi poin ini tidak berdampak besar.
  • Proses pembaruan yang sangat berantakan. Misalkan suatu acara dijadwal ulang. Dalam hal ini, seseorang harus memperbarui semua contoh itu. Sejumlah besar operasi DML perlu dilakukan saat menjadwal ulang, yang menciptakan dampak negatif pada kinerja aplikasi.
  • Penanganan pengecualian. Semua pengecualian harus ditangani dengan anggun, terutama jika Anda harus kembali dan mengedit janji asli setelah membuat pengecualian. Misalnya, Anda memindahkan kejadian ketiga dari acara berulang ke depan satu hari. Bagaimana jika Anda kemudian mengedit waktu acara asli? Apakah Anda memasukkan kembali acara lain pada hari asli dan meninggalkan yang Anda bawa ke depan? Batalkan tautan pengecualian? Coba ubah dengan tepat?
  • Cara Pakar: Menyimpan pola berulang dan menghasilkan kejadian masa lalu dan masa depan secara terprogram. Solusi ini membahas kelemahan dari solusi naif. Kami akan menjelaskan solusi ahli secara mendetail dalam artikel ini.

    Model yang Diusulkan




    Membuat Acara

    Semua acara terjadwal, terlepas dari reguler atau sifatnya yang berulang, dicatat dalam event meja. Tidak semua acara adalah acara yang berulang, jadi kita memerlukan kolom bendera, is_recurring , dalam tabel ini untuk secara eksplisit menentukan acara rutin. event_title dan event_description kolom menyimpan subjek dan ringkasan peristiwa. Deskripsi acara bersifat opsional, itulah sebabnya kolom ini dapat dibatalkan.

    Seperti namanya, start_date dan end_date kolom menyimpan tanggal mulai dan berakhirnya acara. Dalam kasus acara reguler, kolom ini menyimpan tanggal mulai dan akhir yang sebenarnya. Namun, mereka juga menyimpan tanggal kemunculan pertama dan terakhir dari peristiwa periodik. Kami akan menyimpan end_date kolom sebagai nullable, karena pengguna dapat mengonfigurasi acara rutin tanpa tanggal akhir. Dalam hal ini, kejadian di masa mendatang hingga tanggal akhir hipotetis (misalnya selama satu tahun) akan ditampilkan di UI.

    is_full_date_event kolom menandakan jika suatu acara adalah acara sehari penuh. Untuk acara sehari penuh, start_time dan end_time kolom akan menjadi nol; itulah alasan untuk menjaga kedua kolom ini nullable.

    created_by dan created_date kolom menyimpan pengguna mana yang membuat acara dan tanggal acara itu dibuat.

    Selanjutnya ada parent_event_id kolom. Ini memainkan peran utama dalam model data kami. Saya akan menjelaskan signifikansinya nanti.

    Mengelola Perulangan

    Sekarang kita langsung ke pernyataan masalah utama:Bagaimana jika acara berulang dibuat di event tabel – yaitu is_recurring bendera untuk acara tersebut adalah “Y”?

    Seperti yang dijelaskan sebelumnya, kita akan menyimpan pola berulang untuk kejadian sehingga kita dapat membangun semua kejadian di masa depan. Mari kita mulai dengan membuat recurring_pattern meja. Tabel ini memiliki kolom berikut:

    • Event_id – Kolom ini dirujuk dari event tabel, dan bertindak sebagai kunci utama dalam tabel ini. Ini menunjukkan hubungan pengidentifikasian antara event dan recurring_pattern tabel. Kolom ini juga akan memastikan bahwa ada maksimal satu pola berulang untuk setiap peristiwa.
    • Recurring_type_id – Kolom ini menandakan jenis perulangan, apakah harian, mingguan, bulanan atau tahunan.
    • Max_num_of_occurrances – Ada kalanya kita tidak tahu tanggal akhir yang tepat untuk suatu acara tetapi kita tahu berapa banyak kejadian (rapat) yang diperlukan untuk menyelesaikannya. Kolom ini menyimpan nomor arbitrer yang menentukan akhir logis untuk suatu peristiwa.
    • Separation_count – Anda mungkin bertanya-tanya bagaimana acara dua mingguan atau dua tahunan dapat dikonfigurasi jika hanya ada empat kemungkinan nilai tipe perulangan (harian, mingguan, bulanan, tahunan). Jawabannya adalah separation_count kolom. Kolom ini menandakan interval (dalam hari, minggu, atau bulan) sebelum kejadian berikutnya diperbolehkan. Misalnya, jika suatu acara perlu dikonfigurasi untuk setiap minggu, maka separation_count =“1” untuk memenuhi persyaratan ini. Nilai default untuk kolom ini adalah “0”.

    Mari kita pertimbangkan signifikansi kolom yang tersisa dalam kaitannya dengan jenis pengulangan yang berbeda.

    Pengulangan Harian

    Apakah kita benar-benar perlu menangkap pola untuk acara rutin harian? Tidak, karena semua detail yang diperlukan untuk menghasilkan pola pengulangan harian sudah dicatat dalam event tabel.

    Satu-satunya skenario yang memerlukan pola adalah ketika acara dijadwalkan untuk hari alternatif atau setiap X jumlah hari. Dalam hal ini, separation_count kolom akan membantu kita memahami pola pengulangan dan mendapatkan contoh lebih lanjut.

    Pengulangan Mingguan

    Kami hanya membutuhkan satu kolom tambahan, day_of_week , untuk menyimpan hari apa dalam seminggu acara ini akan berlangsung. Dengan asumsi Senin adalah hari pertama dalam seminggu dan Minggu adalah yang terakhir, nilai yang mungkin adalah 1,2,3,4,5,6, dan 7. Perubahan yang sesuai dalam kode yang menghasilkan kejadian individu harus dibuat sesuai kebutuhan. Semua kolom yang tersisa akan kosong untuk acara mingguan.

    Mari kita ambil jenis acara mingguan klasik:kejadian dua mingguan. Dalam hal ini, kami akan mengatakan itu terjadi setiap minggu alternatif pada hari Selasa, hari kedua dalam seminggu. Jadi:

    • recurring_type_id akan menjadi “mingguan”.
    • separation_count akan menjadi “1”.
    • day_of_week akan menjadi “2”.

    Pengulangan Bulanan

    Selain day_of_week , kami memerlukan dua kolom lagi untuk memenuhi skenario perulangan bulanan. Secara singkat, kolom-kolom ini adalah:

    • Week_of_month – Kolom ini untuk acara yang dijadwalkan untuk minggu tertentu dalam sebulan – yaitu pertama, kedua, terakhir, kedua hingga terakhir, dll. Kita dapat menyimpan nilai ini sebagai 1,2,3, 4,.. (dihitung dari awal bulan) atau -1,-2,-3,... (dihitung dari akhir bulan).
    • Day_of_month – Ada kasus ketika sebuah acara dijadwalkan pada hari tertentu dalam sebulan, katakanlah tanggal 25. Kolom ini memenuhi persyaratan ini. Sukai week_of_month , dapat diisi dengan angka positif ( "7" untuk hari ke-7 dari awal bulan) atau angka negatif ( "-7" untuk hari ketujuh dari akhir bulan).

    Sekarang mari kita pertimbangkan contoh yang lebih rumit – acara triwulanan. Misalkan sebuah perusahaan menjadwalkan acara proyeksi hasil kuartalan untuk hari ke-11 bulan pertama di setiap kuartal (biasanya Januari, April, Juli, dan Oktober). Jadi dalam hal ini:

    • recurring_type_id akan menjadi “bulanan”.
    • separation_count akan menjadi “2”.
    • day_of_month akan menjadi “11”.
    • Semua kolom yang tersisa akan kosong.

    Dalam contoh di atas, kami berasumsi bahwa pengguna membuat proyeksi hasil triwulanan di bulan Januari. Harap diperhatikan bahwa logika pemisahan ini akan mulai menghitung dari bulan, minggu, atau hari saat acara dibuat.

    Pada baris yang sama, acara setengah tahunan dapat dicatat sebagai acara bulanan dengan separation_count dari “5”.

    Pengulangan Tahunan

    Pengulangan tahunan cukup mudah. Kami memiliki kolom untuk hari-hari tertentu dalam seminggu dan bulan, jadi kami hanya memerlukan satu kolom tambahan untuk bulan dalam setahun. Kami menamai kolom ini month_of_year .

    Menangani Pengecualian untuk Peristiwa Berulang

    Sekarang mari kita membahas pengecualian. Bagaimana jika kejadian tertentu dari acara berulang dibatalkan atau dijadwalkan ulang? Semua kejadian tersebut dicatat secara terpisah di event_instance_exception meja.

    Mari kita lihat dua kolom, Is_rescheduled dan is_cancelled . Kolom-kolom ini menandakan apakah instance ini dijadwal ulang ke beberapa tanggal/waktu kemudian atau dibatalkan sama sekali. Mengapa saya memiliki dua kolom terpisah untuk ini? Nah, pikirkan saja acara yang awalnya dijadwalkan ulang dan kemudian dibatalkan sepenuhnya. Ini terjadi, dan kami memiliki cara untuk merekamnya dengan kolom ini.

    Selain dua kolom ini, semua kolom yang tersisa bertindak sama seperti di event tabel.

    Mengapa menautkan dua peristiwa melalui parent_event_id ?

    Ada aplikasi yang memungkinkan pengguna untuk menjadwal ulang semua kejadian yang akan datang dari acara berulang. Dalam kasus seperti itu, kami memiliki dua opsi. Kami dapat menyimpan semua instance mendatang di event_instance_exception (petunjuk:bukan solusi yang dapat diterima). Atau kita dapat membuat acara baru dengan parameter tanggal/waktu baru di event tabel dan tautkan dengan acara sebelumnya (acara induk) melalui id_parent_event kolom.

    Dengan solusi ini, kita bisa mendapatkan semua kejadian masa lalu dari suatu peristiwa, bahkan ketika pola pengulangannya telah diubah.

    Bagaimana Meningkatkan Penanganan Acara Berulang?

    Ada beberapa area yang lebih kompleks seputar acara berulang yang belum kita diskusikan. Ini dua:

    • Acara yang terjadi pada hari libur. Ketika suatu kejadian tertentu terjadi pada hari libur umum, haruskah secara otomatis dipindahkan ke hari kerja segera setelah hari libur? Atau harus dibatalkan secara otomatis? Dalam keadaan apa salah satu dari ini berlaku?
    • Konflik antar peristiwa. Bagaimana jika peristiwa tertentu (yang saling eksklusif) jatuh pada hari yang sama?

    Perubahan apa yang perlu kita buat untuk membangun kemampuan ini? Silakan beri tahu kami pandangan Anda di bagian komentar.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dampak kinerja dari berbagai teknik penanganan kesalahan

  2. Cara Mengubah Kolom Dari NULL menjadi NOT NULL

  3. Mengurangi Fragmentasi Indeks

  4. Semua yang Perlu Anda Ketahui Tentang SQL CTE di Satu Tempat

  5. Memahami peran arsitek data dalam tata kelola data