13 poin oleh GN⁺ 2024-07-25 | 1 komentar | Bagikan ke WhatsApp
  • Dengan fitur penjadwalan dari klon Google Calendar sebagai contoh, artikel ini menunjukkan alur desain yang tidak langsung membuat tabel, melainkan menyelesaikan model logis terlebih dahulu lalu memindahkannya ke skema SQL
  • Metode intinya adalah menemukan lebih dulu anchor seperti User, DayEvent, TimeEvent, dan Timezone, lalu memvalidasi kebutuhan dan kardinalitas melalui atribut serta relasi 1:N dan M:N
  • Jadwal dibagi menjadi event sepanjang hari dan event berbasis waktu; event berbasis waktu menyimpan waktu lokal mulai/selesai beserta masing-masing Timezone agar perubahan zona waktu di masa depan juga dapat ditangani
  • Jadwal berulang direpresentasikan dengan frekuensi, interval, metode pengulangan bulanan, kondisi akhir, dan relasi hari dalam minggu; untuk rendering layar dan perubahan pada instance individual, DaySlot dan TimeSlot dijadikan anchor terpisah
  • Desain fisik akhirnya memakai prinsip “satu tabel untuk tiap anchor”, tetapi tidak membuat DayOfTheWeek sebagai tabel, sehingga diringkas menjadi total 8 tabel SQL termasuk 6 tabel anchor dan 2 tabel relasi M:N

Pendekatan desain: buat model logis terlebih dahulu

  • Tujuannya adalah menunjukkan proses desain tabel database yang mendekati proyek nyata, dengan fitur kalender dari klon Google Calendar sebagai sasaran
  • Alur keseluruhannya adalah terlebih dahulu membuat model logis lengkap yang menjelaskan data kalender yang harus disimpan, lalu memindahkan model itu ke struktur tabel fisik
  • Bagian awal membahas model logis yang tidak terikat pada database tertentu
    • Memodelkan kebutuhan bisnis secara independen dari MySQL, Postgres, server relasional tradisional, NoSQL, maupun database cloud
  • Bagian akhir menunjukkan salah satu pendekatan untuk mengubah model logis menjadi tabel fisik
    • Untuk sistem dengan kebutuhan yang tidak terlalu menuntut, ini dapat dianggap sebagai pendekatan desain yang valid

Cakupan masalah: fitur inti penjadwalan Google Calendar

  • Sistem yang dituju adalah sistem multi-pengguna, dan data terkait pengguna hanya dimodelkan seminimal mungkin
  • Event bisa memiliki atribut seperti judul, deskripsi, dan lokasi, tetapi bagian yang paling kompleks adalah waktu dan tanggal
  • Event yang dimodelkan mencakup perbedaan berikut
    • event sepanjang hari dan event berbasis waktu
    • event berulang dan event tidak berulang
    • event sepanjang hari yang membentang beberapa hari
    • event berbasis waktu yang terhubung ke zona waktu, dan waktu mulai/selesai dapat berada pada tanggal berbeda atau zona waktu berbeda
  • Event berulang mencakup bentuk-bentuk berikut
    • berulang setiap hari atau setiap N hari
    • berulang tiap minggu pada hari tertentu, dengan interval 2 minggu atau lebih juga dimungkinkan
    • berulang tiap bulan pada tanggal tertentu atau pada hari tertentu di minggu tertentu
    • berulang tiap tahun
    • berulang selamanya, sampai tanggal tertentu, atau sebanyak jumlah tertentu
  • Instance tertentu dari event berulang dapat dipindahkan ke tanggal/jam lain atau dihapus
  • Jadwal berulang itu sendiri juga harus bisa diubah bahkan setelah sebagian event sudah lewat

Mengekspresikan kebutuhan dengan anchor, atribut, dan relasi

  • Pemodelan dimulai dengan menemukan anchor terlebih dahulu
    • Anchor adalah objek seperti User atau Event yang dapat dihitung dan dapat ditambahkan ke database
    • Jika bisa diucapkan secara alami seperti “There are 200 Users in our database” atau “When this button is clicked, a new DayEvent is created”, maka itu dapat dianggap sebagai anchor
  • Atribut menyimpan informasi aktual tentang anchor
    • User memiliki atribut email
    • DayEvent memiliki nama, tanggal mulai, dan tanggal selesai
    • Bahkan untuk event satu hari, tanggal mulai dan tanggal selesai disimpan dengan nilai yang sama agar ditangani dengan struktur yang sama seperti event multi-hari
  • Jika dua anchor memiliki hubungan, gunakan relasi alih-alih atribut
    • “User mana yang membuat DayEvent ini” bukanlah atribut logis berupa ID User yang dimasukkan langsung ke DayEvent, melainkan relasi antara User dan DayEvent
    • Relasi memakai kardinalitas 1:N, M:N, atau 1:1, dan maknanya divalidasi dua arah dengan dua kalimat
  • Ada relasi 1:N antara User dan DayEvent
    • User dapat membuat banyak DayEvent
    • DayEvent dibuat oleh satu User

Event berbasis waktu dan penanganan Timezone

  • Untuk event berbasis waktu, ditambahkan anchor Timezone dan TimeEvent
  • Model Timezone diminimalkan untuk keperluan tutorial, sehingga hanya memiliki atribut nama yang bisa dibaca manusia
    • Contoh nilainya adalah Europe/Kyiv
    • Definisi zona waktu yang nyata memerlukan UTC offset, apakah daylight saving time berlaku, awal/akhir DST, UTC offset saat DST berlaku, definisi historis, status aktif/nonaktif, dan seterusnya, tetapi itu dibiarkan sebagai tugas terpisah
  • TimeEvent memiliki nama, tanggal-waktu lokal mulai, dan tanggal-waktu lokal selesai
    • Contoh nilainya adalah 2024-01-14 12:30, 2024-01-14 13:15
  • Waktu tidak disimpan hanya sebagai UTC, tetapi sebagai waktu lokal yang dimasukkan pengguna
    • Sebagai contoh, permainan biliar pada 6 September 2058 pukul 09:30~11:00 waktu Cologne harus disimpan persis seperti yang dimasukkan pengguna, karena UTC offset pada saat itu belum tentu diketahui sekarang
    • Jika hukum setempat berubah di kemudian hari, datanya harus bisa disesuaikan dengan perubahan itu
  • TimeEvent memiliki relasi 1:N ke Timezone secara terpisah untuk zona waktu mulai dan zona waktu selesai
    • Seperti contoh tiket pesawat, penerbangan dari Amsterdam ke London dapat memiliki zona waktu berbeda antara keberangkatan dan kedatangan
    • Sebagian besar event berbasis waktu memang memakai zona waktu yang sama untuk mulai dan selesai, tetapi demi kasus umum, keduanya selalu ditentukan

Pemodelan event sepanjang hari yang berulang

  • Event sepanjang hari yang berulang direpresentasikan dengan menambahkan atribut dan relasi terkait pengulangan pada DayEvent
  • Frekuensi pengulangan dibuat sebagai atribut bertipe either/or/or
    • Nilai yang mungkin adalah daily, weekly, monthly, annually
    • Jika nilainya tidak diatur, event dianggap tidak berulang
  • Interval pengulangan adalah atribut integer yang hanya bermakna “jika event ini berulang”
    • Contoh nilainya adalah 2
    • Dipakai dengan arti seperti setiap 2 hari, setiap 2 minggu, atau setiap 2 bulan
  • Pengulangan bulanan memiliki atribut pilihan terpisah
    • same_day untuk mengulang pada tanggal yang sama
    • same_weekday untuk mengulang pada hari yang sama dalam minggu yang sama seperti tanggal asal
  • Hari tertentu pada pengulangan mingguan tidak dimodelkan sebagai atribut array string, melainkan dengan anchor DayOfTheWeek dan relasi M:N
    • Contoh ID DayOfTheWeek adalah Mon, Tue, Wed, Thu, Fri, Sat, Sun
    • DayEvent dapat terjadi pada banyak DayOfTheWeek, dan DayOfTheWeek dapat dimiliki banyak DayEvent
  • Kondisi akhir pengulangan juga dibuat sebagai atribut
    • forever
    • until_date
    • N_repetitions
    • Untuk until_date, ditambahkan atribut tanggal akhir
    • Untuk N_repetitions, ditambahkan atribut jumlah pengulangan

Slot untuk rendering dan perubahan instance individual

  • Jika event berulang hanya disimpan sebagai satu event asal, query untuk mencari event yang harus ditampilkan pada tampilan minggu tertentu bisa menjadi rumit
  • Untuk rendering layar dan perubahan individual pada event berulang, diperkenalkan konsep Slot
    • DaySlot merepresentasikan instance event sepanjang hari pada tanggal tertentu
    • TimeSlot merepresentasikan instance event berbasis waktu pada tanggal dan jam tertentu
  • DaySlot memiliki tanggal dan status dilewati
    • Tanggal pada slot tertentu dapat diubah
    • Jika rapat pada minggu tertentu dibatalkan, DaySlot tersebut dapat ditandai sebagai skipped
  • DayEvent dan DaySlot memiliki relasi 1:N
    • Satu DayEvent dapat menghasilkan banyak DaySlot
    • DaySlot berkorespondensi dengan satu DayEvent
    • Bahkan untuk DayEvent yang tidak berulang, DaySlot tetap selalu dibuat agar kode rendering lebih sederhana
  • Untuk event yang berulang tanpa batas, ada persoalan jangkauan pembuatan slot
    • Event seperti ulang tahun yang berulang tiap tahun selamanya bisa dibuatkan slot sampai batas arbitrer seperti 100 tahun
    • Atau slot dapat dibuat on-demand ketika pengguna meminta halaman kalender di masa depan yang jauh
  • Perhitungan tanggal perlu diperhatikan
    • ulang tahun 29 Februari
    • event bulanan yang terjadi setiap tanggal 31
    • Untuk kasus seperti ini, perlu diputuskan apakah penggunaannya dilarang, atau dipindahkan satu hari lebih awal atau lebih akhir

TimeSlot dan zona waktu

  • Untuk event berulang berbasis waktu, pendekatan yang sama seperti event sepanjang hari diterapkan dengan anchor TimeSlot
  • TimeSlot merepresentasikan instance tanggal-waktu tertentu dari suatu event, dan TimeEvent berulang berkorespondensi dengan banyak TimeSlot
  • Atribut TimeSlot adalah tanggal-waktu lokal mulai, tanggal-waktu lokal selesai, dan status dilewati
  • Karena TimeSlot tertentu dapat dipindahkan ke hari lain, informasi waktu mulai/selesai dipertahankan secara terpisah
  • TimeSlot juga memiliki relasi 1:N ke Timezone secara terpisah untuk zona waktu mulai dan zona waktu selesai
  • Ada relasi 1:N antara TimeEvent dan TimeSlot, dan TimeSlot juga dibuat untuk TimeEvent yang tidak berulang

Model logis yang selesai

  • Total anchor yang didefinisikan sejauh ini adalah 7
    • User
    • Timezone
    • DayEvent
    • TimeEvent
    • DayOfTheWeek
    • DaySlot
    • TimeSlot
  • Atributnya terdiri dari email User, nama Timezone, nama/tanggal mulai/tanggal selesai/informasi pengulangan pada DayEvent, waktu lokal mulai/selesai pada TimeEvent, serta waktu kejadian dan status skipped pada DaySlot dan TimeSlot
  • Total relasinya diringkas menjadi 10
    • User dengan DayEvent, User dengan TimeEvent
    • Timezone dengan zona waktu mulai/selesai pada TimeEvent
    • DayEvent dengan DayOfTheWeek, TimeEvent dengan DayOfTheWeek
    • DayEvent dengan DaySlot, TimeEvent dengan TimeSlot
    • Timezone dengan zona waktu mulai/selesai pada TimeSlot

Memindahkannya ke tabel SQL

  • Desain fisik menggunakan strategi satu tabel untuk tiap anchor untuk tujuan pembelajaran
  • Model logis memiliki 7 anchor, 21 atribut, dan 10 relasi
  • Secara umum jumlahnya akan menjadi 9 tabel dengan menambahkan jumlah anchor dan relasi M:N, tetapi pada desain akhir DayOfTheWeek diperlakukan secara khusus sehingga tidak dibuat sebagai tabel fisik
  • Total tabel SQL akhirnya adalah 8
    • users
    • timezones
    • day_events
    • time_events
    • day_slots
    • time_slots
    • day_event_dows
    • time_event_dows
  • Relasi 1:N masuk sebagai kolom bernuansa foreign key di tabel sisi N
    • day_events.user_id
    • time_events.user_id
    • time_events.start_timezone_id
    • time_events.end_timezone_id
    • day_slots.day_event_id
    • time_slots.time_event_id
    • time_slots.start_timezone_id
    • time_slots.end_timezone_id
  • Relasi M:N dibuat sebagai tabel terpisah
    • day_event_dows menghubungkan DayEvent dengan hari dalam minggu
    • time_event_dows menghubungkan TimeEvent dengan hari dalam minggu
  • Tipe fisik dipilih sesuai pasangan tipe logisnya
    • string menjadi VARCHAR
    • tanggal menjadi DATE
    • tanggal-waktu lokal menjadi DATETIME
    • yes/no menjadi TINYINT UNSIGNED
    • atribut yang saling terkait dan hanya bermakna secara kondisional memakai tipe yang mengizinkan NULL
  • NULL dan nilai sentinel diperlakukan sebagai konsep skema fisik, bukan model logis

Indeks dan atribut yang dihilangkan

  • Skema SQL contoh tidak mencantumkan indeks yang menurut pengembang database berpengalaman mungkin diperlukan
    • Sebagai contoh, day_events.user_id mungkin memerlukan indeks
  • Kolom atau kombinasi kolom mana yang perlu diberi indeks bergantung pada bagaimana aplikasi melakukan query ke tabel
  • Untuk topik indeks, dapat merujuk ke Use The Index, Luke
  • Saat menjelaskan skema logis, beberapa atribut dihilangkan karena mengikuti pola serupa
    • nama pengguna
    • hash kata sandi pengguna
    • lokasi event
    • daftar orang yang diundang
  • Elemen data yang dihilangkan dapat ditambahkan ke tabel model logis dengan cara yang sama lalu dicerminkan ke skema SQL

Prosedur keseluruhan

  • Mulai dari teks bebas yang menjelaskan masalah bisnis
  • Menyusun daftar anchor
  • Menyusun daftar atribut, sambil menuliskan makna atribut secara jelas dalam bentuk pertanyaan
  • Menyusun daftar relasi, lalu memeriksa dengan kalimat apakah kardinalitasnya tepat
  • Jika perlu, membuat skema grafis berdasarkan model logis
  • Menyusun model fisik dengan mengisi nama tabel, nama kolom, dan tipe data fisik
  • Menggunakan informasi dari langkah sebelumnya untuk menulis skema SQL dalam pernyataan CREATE TABLE
  • Mengirimkan skema ke server database, memperbaiki salah ketik, lalu mengirimkannya lagi
  • Membagikan model logis kepada tim

1 komentar

 
GN⁺ 2024-07-25
Pendapat di Hacker News
  • Jika saya menserialisasi satu event acak dari kalender saya ke iCalendar, ukurannya sekitar 740 byte. Bahkan kalender yang sangat sibuk dengan event setiap 15 menit dari pukul 09.00 sampai 17.00 selama setahun penuh hanya berisi 11.680 item, sekitar 8 MB
    Jadi, alih-alih merancang skema, kalender tampak seperti masalah yang mungkin jauh lebih baik diimplementasikan cukup dengan pemindaian sekuensial. Jika parser iCalendar dioptimalkan agar dapat menyapu rentang event yang di-dump dengan throughput kelas GB/s, skenario terburuk di atas pun bisa dipindai dalam hitungan milidetik satu digit
    Mengoptimalkan parser adalah masalah yang jauh lebih sederhana dan hanya perlu diselesaikan sekali dibandingkan mengubah atau memperluas model data yang buruk setelah tersebar ke banyak pengguna. Lagi pula, pekerjaan pertama model data baru kemungkinan besar tetap impor/ekspor iCalendar, jadi ini terlihat sebagai kompromi yang cukup baik

    • Kalau begitu, bukankah kita harus membuat ulang pencarian rentang seperti BETWEEN ... AND ... di SQL? Begitu juga untuk mencari event milik pengguna 1, 2, 3
      Dalam aplikasi nyata, kemungkinan sudah ada hal seperti akun pengguna di basis data relasional, tetapi tiba-tiba kita harus memindai event di direktori lalu menghubungkan hasilnya dengan record basis data
      Untuk aplikasi tertentu itu mungkin cocok, tetapi ada pekerjaan tertentu yang memang sangat dikuasai basis data, dan karena itulah basis data menjadi pilihan yang baik. Dengan indeks yang tepat, throughput yang sama atau bahkan lebih baik juga mungkin dicapai. Kecuali jika Anda membuat struktur direktori cerdas untuk event; itu pada dasarnya sama seperti indeks satu dimensi, sementara di basis data Anda bisa membuat indeks untuk banyak dimensi dan kombinasi dimensi
      Pada akhirnya itu benar, dan ini soal kompromi
    • iCalendar dirancang sebagai format pertukaran, bukan format penyimpanan untuk akses cepat ke data kalender
      Usia formatnya terlihat; tampak bahwa ia dirancang sebelum XML/JSON menjadi “populer”
      Referensi: https://en.wikipedia.org/wiki/ICalendar
    • Meski bisa dilakukan tanpa DBMS, datanya tetap membutuhkan skema yang baik, dan itu tidak semestinya berupa sekumpulan record iCalendar. Misalnya, hanya ada alamat email yang dapat berubah dan berulang, bukan ID pengguna yang stabil
    • Pendekatan seperti itu tampaknya juga bisa memberikan solusi yang lebih rapi untuk masalah slot waktu tak terbatas yang disebutkan dalam artikel
  • Ini artikel tentang menangani jadwal berulang dalam aplikasi, dan bagi saya pribadi sangat membuka mata. Sangat saya sarankan untuk dibaca: https://github.com/bmoeskau/Extensible/blob/master/recurrenc...

    • Menarik karena saran di artikel asli dan saran di artikel ini saling berlawanan
      Artikel asli mengatakan untuk selalu menyimpan zona waktu pada setiap tanggal, sedangkan artikel yang ditautkan mengatakan untuk mengonversi semuanya ke UTC. Untuk bagian ini saya setuju dengan artikel asli
      Artikel asli mengatakan untuk membuat baris basis data untuk setiap event, sedangkan artikel yang ditautkan mengatakan jangan lakukan itu. Untuk bagian ini saya setuju dengan artikel yang ditautkan
  • Kegagalan terbesar saya dalam wawancara adalah ketika diminta membuat sistem reservasi sederhana yang juga harus menangani reservasi berulang
    Sejak awal masa kuliah, saya tidak pernah merasa begitu tersesat dan bingung saat mencoba menyelesaikan sesuatu dengan kode. Sampai sekarang pun saya langsung gentar ketika harus mengerjakan hal terkait tanggal/waktu, dan entah kenapa semuanya tidak pernah terasa pas di kepala saya

    • Pertanyaan desain “rancang sistem reservasi, termasuk reservasi berulang” mirip dengan pertanyaan “tulis fungsi untuk mengurutkan daftar string, tetapi harus mematuhi kebiasaan urutan alfabet untuk string UTF-8 arbitrer dan semua locale”
      Di permukaan tampak sederhana, tetapi jika ingin membuatnya bekerja secara umum di dunia nyata, masalahnya menjadi begitu kompleks hingga nyaris mustahil
    • Tidak perlu terlalu menyalahkan diri sendiri. Saya pernah ditugaskan memperbaiki kalender di CMS agar mendukung jauh lebih banyak fitur, dan nyaris habis dimakan olehnya. Saat itu pengalaman kerja saya sudah sekitar 8 tahun
      Ini adalah masalah yang tampak menipu mudah padahal sulit, dan membutuhkan kemampuan pemodelan data yang sangat baik
  • Kemampuan memodelkan sistem kurang dihargai. Dalam domain baru, kita harus mulai dari analisis menyeluruh atas masalah untuk menangkap baik struktur statis sistem, yaitu model kelas, maupun perilaku dinamisnya, yaitu use case
    Jika langsung melompat ke model basis data statis, perilaku dinamis mudah terlewat. Untuk aplikasi CRUD sederhana seperti ini mungkin tidak apa-apa, tetapi pada sistem yang lebih kompleks itu bisa menjadi kesalahan besar

    • Sebagai data scientist, beberapa kali saya cukup kesulitan secara spontan dengan pertanyaan wawancara yang tampak sederhana seperti “bagaimana Anda akan membuat skemanya”
      Pertanyaan terakhir yang saya ingat adalah bagaimana membuat tabel produk yang memiliki kupon. Awalnya saya pikir dua tabel saja cukup, tetapi bukankah riwayat juga harus dipertahankan? Kalau begitu, kita harus memasukkan dan memperbarui tanggal/waktu per produk dan kupon. Sekarang kita juga harus memikirkan indeks tabel, dan apakah join untuk mendapatkan harga diskon merupakan cara yang baik. Sebagian besar kupon hanya bisa dipakai sekali oleh satu orang, lalu bagaimana cara mengimplementasikannya?
      Mungkin mereka hanya menginginkan tabel produk + kupon sederhana, tetapi saya malah menggali sendiri terlalu jauh seperti orang gila
    • Seperti apa bentuk keluaran dari analisis semacam ini? Saya penasaran kalau ada tautan referensi seperti contoh dokumen atau bab buku
  • Saya rasa ini domain yang dipilih dengan baik untuk menunjukkan pemodelan, dan merupakan artikel pengantar yang bagus
    Istilah “anchor” terasa agak aneh, tetapi penjelasannya sangat konkret dan membumi seperti jangkar sungguhan, jadi cukup bisa diterima
    Konsep mendefinisikan atribut melalui pertanyaan itu solid. Terlalu sering kita langsung melompat ke nama kolom/atribut minimum tanpa mendefinisikan pertanyaan apa yang ingin kita jawab, dan itu gagal menghilangkan ambiguitas di kepala pelanggan. Definisi atribut berbasis pertanyaan adalah cara yang baik untuk mendapatkan kejelasan dengan cepat

    • Istilah “anchor” diwarisi dari Anchor Modeling(https://en.wikipedia.org/wiki/Anchor_modeling). “Entity” memang banyak digunakan, tetapi saya tidak ingin memakainya karena bisa membawa beban dan asumsi yang tidak perlu
      Selain itu, istilah ini sudah sangat kelebihan makna. Dalam ilmu komputer, pada dasarnya semua hal adalah objek atau entitas
      Tanggapan bahwa konsep mendefinisikan atribut melalui pertanyaan itu solid menjadi konfirmasi penting atas validitas pendekatan ini
  • Zona waktu benar-benar bisa bikin pusing, terutama di sekitar titik transisi
    Misalnya zona waktu maju satu jam saat daylight saving time, lalu mundur satu jam saat kembali ke waktu standar
    Jika waktu melompat maju satu jam, event berdurasi 1 jam bisa terlihat di layar seolah berlangsung selama 2 jam, dan jam kedua itu tidak bisa dijangkau atau bahkan tidak ada
    Jika waktu mundur satu jam, event berdurasi 1 jam bisa terlihat seperti 2 jam, atau terlihat seperti 0 jam
    Zona waktu adalah konstruksi buatan manusia, jadi nilainya tidak boleh di-hardcode. Suatu saat pasti berubah

    • Ini jadi lebih menarik kalau melacak waktu sambil memperhitungkan perjalanan. Pertama kali saya mengalaminya saat melacak waktu di kapal yang berada di laut selama beberapa hari
      Kita bisa bolak-balik melintasi zona waktu ke dua arah, bisa juga melintasi garis tanggal internasional, dan tanggal/waktu mulai lokal bahkan bisa terjadi setelah tanggal/waktu selesai lokal
    • Apakah maksudnya kita harus membuat kalender seluruhnya dalam UTC tanpa zona waktu? Saya setuju bahwa zona waktu adalah sesuatu yang kita buat, tetapi itu dibuat untuk pengorganisasian lokal yang lebih baik. Kami bekerja dengan pelanggan di seluruh dunia dan semua orang memakai zona waktu. Secara pribadi, ini terdengar seperti tuntutan yang cukup tidak masuk akal
      Lebih baik fokus menghapus konsep daylight saving time di beberapa wilayah yang masih menggunakannya. Hal itu paling sering menimbulkan kebingungan antarzona waktu, terutama saat merencanakan jadwal setelah transisi yang akan datang
  • Saya tidak ingin menyimpan dua tanggal untuk sebuah event. Lebih mudah menyimpan waktu mulai dan durasi event
    Dengan begitu, logika pembaruan event menjadi sederhana. Waktu selesai kapan saja bisa dihitung berdasarkan waktu mulai dan durasi

    • Jujur saja, simpan saja ketiganya: waktu mulai, waktu selesai, dan durasi, lalu gunakan yang diperlukan sesuai tujuan. Cukup sediakan satu titik masuk/pembaruan yang menyinkronkan representasi alternatif itu
    • Pendekatan itu bisa bermasalah untuk performa database. Setiap kali query, durasinya harus dihitung secara langsung
    • Bukankah kebalikannya juga sama? Kalau ada waktu mulai dan selesai, durasinya tinggal dihitung
  • Dulu saya pernah mengerjakan aplikasi kalender dengan jadwal berulang. Setelah banyak riset, kami memutuskan memakai RRules untuk merepresentasikannya, dan hasilnya sangat memuaskan. Pekerjaan awal itu saya lakukan saat masih di agensi
    Belakangan, ketika saya bergabung penuh waktu dengan perusahaan itu, saya terkejut melihat kontraktor dari perusahaan lain menghapus RRules dan menggantinya dengan cara membuat serta menghapus instance event secara langsung. Toleransi gangguannya nyaris tidak ada, sehingga skrip yang juga mengerjakan hal lain dan kadang gagal bisa gagal membuat event baru. Akibatnya, ada bulan yang hilang dari event berulang bulanan
    Rasanya sangat menjengkelkan melihat sesuatu yang dibuat lewat banyak pemikiran dan riset dihapus oleh seseorang tanpa usaha yang sepadan. Setelah beberapa minggu saja di perusahaan itu, jelas terlihat bahwa CEO berharap tim engineering terus mengeluarkan fitur yang tidak dipakai siapa pun sesuai kemauannya, dan karena ketidakpastian pasar kerja, sayangnya saya bertahan selama 2 tahun
    Sebagai tambahan, belakangan saat saya mencari, rasanya benar-benar pahit melihat di Glassdoor ada ulasan palsu yang jelas ditulis CEO, semuanya dengan gaya tulisan yang sama dan tanpa satu pun komentar buruk. Saya dan beberapa kenalan yang pernah bekerja di sana tidak menyukainya, tetapi setidaknya ada penghiburan bahwa saya menulis beberapa esai terbaik saya di perusahaan itu. CTO-nya juga tidak bisa diharapkan

  • Saya pernah mengimplementasikan backend kalender dan kontrol resource untuk platform low-code
    Kontrolnya sangat bisa dikustomisasi, dan selain berbagai tampilan seperti harian, bulanan, dan tahunan, juga bisa memilih tampilan resource. Resource bisa dipesan dengan grup kustom, dan bisa dikelompokkan berdasarkan plugin, ID resource, dan sebagainya. Di data source, kami mendefinisikan “plugins”, lalu menentukan kolom mulai/selesai, kolom judul, dan kolom resource. Resource bisa berasal dari foreign key atau relasi 1:1, bisa juga dari relasi 1:N pada data source “anak”, atau dari data source/tabel yang sama
    Kami juga mengimplementasikan berbagai seri appointment seperti bulanan, mingguan, hari tertentu dalam minggu, harian, dan sebagainya, serta memungkinkan pengguna memilih nilai kolom mana yang akan disalin. Konflik appointment juga ditangani, dan konflik bisa dianggap terjadi hanya saat memesan resource yang sama. Buffer sebelum dan sesudah appointment, yang tidak boleh diisi appointment lain, juga bisa dikonfigurasi
    Kadang cukup menantang karena zona waktu Eropa serta waktu musim panas/musim dingin, tetapi pekerjaannya cukup menyenangkan

  • Yang saya inginkan dari Google Calendar hanyalah log perubahan untuk kalender itu sendiri. Tolong sekali tambahkan ini ke database