<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Backend Development on Dev TLDRLSS</title>
        <link>https://dev.tldrlss.com/id/categories/backend-development/</link>
        <description>Recent content in Backend Development on Dev TLDRLSS</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>id</language>
        <lastBuildDate>Tue, 19 May 2026 18:10:00 +0800</lastBuildDate><atom:link href="https://dev.tldrlss.com/id/categories/backend-development/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Jangan Tertipu oleh Sifat Santai SQLite! Apa Saja Celah Tipe Dinamis? Mengapa ALTER TABLE Setengah Matang? Bagaimana Membangun Arsitektur Pemrograman Defensif di Node.js untuk Peningkatan Schema Tanpa Hambatan?</title>
        <link>https://dev.tldrlss.com/id/article/2026/05/sqlite-pitfall-intro/</link>
        <pubDate>Tue, 19 May 2026 18:10:00 +0800</pubDate>
        
        <guid>https://dev.tldrlss.com/id/article/2026/05/sqlite-pitfall-intro/</guid>
        <description>&lt;img src="https://dev.tldrlss.com/global-assets/images/database/sqlite-type-pitfall-1.jpg" alt="Featured image of post Jangan Tertipu oleh Sifat Santai SQLite! Apa Saja Celah Tipe Dinamis? Mengapa ALTER TABLE Setengah Matang? Bagaimana Membangun Arsitektur Pemrograman Defensif di Node.js untuk Peningkatan Schema Tanpa Hambatan?" /&gt;&lt;p&gt;Bayangkan sebuah tempat sampah daur ulang di mana Anda dengan jelas menempelkan label bertuliskan &amp;ldquo;Hanya untuk Botol Plastik&amp;rdquo;, tetapi ketika seseorang memasukkan selembar kertas ke dalamnya, ia menerimanya secara diam-diam tanpa ada satu pun kata protes?&lt;/p&gt;
&lt;p&gt;Ini adalah pengalaman yang mendebarkan ketika para pengembang pertama kali bertemu dengan sistem tipe &lt;code&gt;SQLite&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Jika Anda terbiasa dengan gaya petugas bea cukai yang ketat dari &lt;code&gt;PostgreSQL&lt;/code&gt; (di mana tipe yang salah langsung ditolak masuk), sifat santai &lt;code&gt;SQLite&lt;/code&gt; mungkin membuat Anda mempertanyakan hidup Anda.&lt;/p&gt;
&lt;p&gt;Bahkan yang lebih menakutkan, ketika Anda ingin &lt;strong&gt;mengubah struktur tabel&lt;/strong&gt;, ia akan memberi tahu Anda:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&amp;ldquo;Tabel tidak dapat diubah secara langsung. Silakan bangun rumah baru, pindahkan furnitur ke sana, lalu ledakkan rumah yang lama.&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;di-bawah-kap-sqlite-hanya-memiliki-5-kelas-penyimpanan&#34;&gt;Di Bawah Kap SQLite Hanya Memiliki 5 Kelas Penyimpanan
&lt;/h2&gt;&lt;p&gt;Tidak peduli apa pun nama tipe mewah yang Anda deklarasikan di &lt;code&gt;CREATE TABLE&lt;/code&gt; (&lt;code&gt;VARCHAR(255)&lt;/code&gt;, &lt;code&gt;BIGINT&lt;/code&gt;, &lt;code&gt;DECIMAL&lt;/code&gt;), &lt;code&gt;SQLite&lt;/code&gt; di balik layar hanya mengenali &lt;strong&gt;5 kelas penyimpanan&lt;/strong&gt; berikut:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Kelas Penyimpanan&lt;/th&gt;
          &lt;th&gt;Deskripsi&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;NULL&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Nilai kosong (null)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;INTEGER&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Integer (secara otomatis menempati 1 hingga 8 byte tergantung pada besarnya nilai)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;REAL&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Angka desimal float (tetap 8 byte)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;TEXT&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;String (default pengkodean UTF-8)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;strong&gt;BLOB&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Objek biner besar (disimpan persis seperti yang dimasukkan)&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Tipe yang Anda tetapkan pada kolom &lt;strong&gt;hanyalah &amp;quot;saran&amp;quot; bagi &lt;code&gt;SQLite&lt;/code&gt;, bukan &amp;quot;aturan wajib&amp;quot;&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ini disebut &lt;strong&gt;&amp;ldquo;Type Affinity&amp;rdquo;&lt;/strong&gt; (Afinitas Tipe). &lt;code&gt;SQLite&lt;/code&gt; akan mencoba mengonversi data Anda ke tipe yang disarankan, tetapi jika tidak bisa, ia akan memasukkan data asli begitu saja tanpa memicu error apa pun.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Anda dapat mendeklarasikan kolom &lt;code&gt;age INTEGER&lt;/code&gt; di &lt;code&gt;SQLite&lt;/code&gt; lalu memasukkan string &lt;code&gt;&#39;selamanya delapan belas&#39;&lt;/code&gt;; ia akan menerimanya dengan senang hati.&lt;/p&gt;
&lt;!--adsense--&gt;
&lt;h2 id=&#34;tiga-celah-tipe-paling-mudah-untuk-dilewati&#34;&gt;Tiga Celah Tipe Paling Mudah untuk Dilewati
&lt;/h2&gt;&lt;h3 id=&#34;celah-1-tidak-ada-boolean-bawaan&#34;&gt;Celah 1: Tidak Ada Boolean Bawaan
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;SQLite&lt;/code&gt; &lt;strong&gt;tidak memiliki tipe boolean&lt;/strong&gt;. &lt;code&gt;True&lt;/code&gt; dan &lt;code&gt;False&lt;/code&gt; hanya dapat diwakili oleh integer &lt;code&gt;1&lt;/code&gt; dan &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Saat Anda mengambil data dari &lt;code&gt;SQLite&lt;/code&gt; menggunakan &lt;code&gt;Node.js&lt;/code&gt;, you will get the number &lt;code&gt;1&lt;/code&gt; or &lt;code&gt;0&lt;/code&gt;, not &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Jika Anda langsung melakukan pemeriksaan seperti &lt;code&gt;if (user.is_admin === true)&lt;/code&gt;, itu tidak akan pernah bernilai benar.&lt;/p&gt;
&lt;h3 id=&#34;celah-2-tidak-ada-tipe-datetime&#34;&gt;Celah 2: Tidak Ada Tipe Date/Time
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;SQLite&lt;/code&gt; &lt;strong&gt;tidak memiliki tipe tanggal/waktu&lt;/strong&gt;. Anda hanya dapat menyimpan waktu sebagai:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Metode Penyimpanan&lt;/th&gt;
          &lt;th&gt;Contoh&lt;/th&gt;
          &lt;th&gt;Kelebihan &amp;amp; Kekurangan&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;TEXT (string ISO-8601)&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;&#39;2026-05-19T18:00:00Z&#39;&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Sangat direkomendasikan&lt;/strong&gt;, keterbacaan tinggi, konversi mulus saat pindah ke PostgreSQL di masa mendatang&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;INTEGER (Unix Timestamp)&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;1747656000&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;Ukuran kecil, tetapi tidak dapat dibaca manusia&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Jangan pernah menyimpan tanggal dalam format khusus yang sewenang-wenang seperti &lt;code&gt;2026/5/19 18.00&lt;/code&gt;, jika tidak migrasi data di masa mendatang akan menjadi bencana.&lt;/p&gt;
&lt;h3 id=&#34;celah-3-memasukkan-string-ke-kolom-integer-tidak-akan-memicu-error&#34;&gt;Celah 3: Memasukkan String ke Kolom Integer Tidak Akan Memicu Error
&lt;/h3&gt;&lt;p&gt;Di &lt;code&gt;PostgreSQL&lt;/code&gt;, memasukkan string ke kolom &lt;code&gt;INTEGER&lt;/code&gt; akan langsung memicu error. Namun &lt;code&gt;SQLite&lt;/code&gt; hanya akan mencoba mengonversinya secara diam-diam, dan jika gagal, ia menerima apa adanya.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ini berarti &lt;strong&gt;data kotor mungkin menyelinap masuk ke dalam database Anda secara diam-diam&lt;/strong&gt; sampai suatu hari program Anda crash karena menerima tipe yang tidak terduga, barulah Anda menyadari masalah tersebut.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;pemrograman-defensif-menghadapi-database-yang-santai-dengan-sikap-tegas&#34;&gt;Pemrograman Defensif: Menghadapi Database yang Santai dengan Sikap Tegas
&lt;/h2&gt;&lt;p&gt;Dihadapkan dengan sifat santai &lt;code&gt;SQLite&lt;/code&gt;, Anda harus membangun &lt;strong&gt;mekanisme pertahanan yang ketat&lt;/strong&gt; dalam pengembangan &lt;code&gt;Node.js&lt;/code&gt;:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Tingkat Pertahanan&lt;/th&gt;
          &lt;th&gt;Alat&lt;/th&gt;
          &lt;th&gt;Peran&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Penjaga Compile-time&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Menangkap tipe yang salah pada tahap penulisan kode&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Validasi Input API&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Zod&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Memvalidasi data masuk secara ketat (memastikan age selalu berupa angka)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Konversi Tipe Otomatis&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Prisma / Drizzle ORM&lt;/strong&gt;&lt;/td&gt;
          &lt;td&gt;Menangani perbedaan tipe secara otomatis antara SQLite dan PostgreSQL&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;Memindahkan &lt;strong&gt;&amp;quot;penjaga gerbang validasi data&amp;quot;&lt;/strong&gt; dari lapisan database ke lapisan aplikasi &lt;code&gt;Node.js&lt;/code&gt; adalah strategi kunci untuk memanfaatkan kecepatan pengembangan SQLite sambil memastikan skalabilitas di masa mendatang.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Saat menggunakan ORM, selama Anda mendeklarasikan &lt;code&gt;type: &#39;boolean&#39;&lt;/code&gt; di kode Anda, ORM secara otomatis mengonversinya menjadi &lt;code&gt;1/0&lt;/code&gt; saat menyimpan to &lt;code&gt;SQLite&lt;/code&gt;, dan mengonversinya kembali menjadi &lt;code&gt;true/false&lt;/code&gt; saat membaca, secara sempurna menutupi perbedaan tipe di bawahnya.&lt;/p&gt;
&lt;!--adsense--&gt;
&lt;h2 id=&#34;alter-table-setengah-matang-apa-yang-bisa-dan-tidak-bisa-diubah&#34;&gt;ALTER TABLE Setengah Matang: Apa yang Bisa dan Tidak Bisa Diubah
&lt;/h2&gt;&lt;p&gt;Dukungan &lt;code&gt;SQLite&lt;/code&gt; untuk mengubah struktur tabel sangat terbatas:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Operasi&lt;/th&gt;
          &lt;th&gt;Didukung&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Tambah Kolom (&lt;code&gt;ADD COLUMN&lt;/code&gt;)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Ya&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Ubah Nama Kolom (&lt;code&gt;RENAME COLUMN&lt;/code&gt;)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Ya&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Hapus Kolom (&lt;code&gt;DROP COLUMN&lt;/code&gt;)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Ya&lt;/strong&gt; (di versi yang lebih baru)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Ubah Nama Tabel (&lt;code&gt;RENAME TO&lt;/code&gt;)&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Ya&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Ubah Tipe Kolom&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Tidak&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Tambah/Hapus Batasan &lt;code&gt;UNIQUE&lt;/code&gt;, &lt;code&gt;NOT NULL&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Tidak&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Ubah Primary Key&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Tidak&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Ubah Foreign Key&lt;/td&gt;
          &lt;td&gt;&lt;strong&gt;Tidak&lt;/strong&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;Begitu Anda perlu melakukan salah satu modifikasi yang &amp;quot;tidak didukung&amp;quot;, &lt;code&gt;SQLite&lt;/code&gt; mengharuskan Anda untuk menjalankan strategi &lt;strong&gt;&amp;quot;buat ulang dan pindahkan&amp;quot;&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;empat-langkah-buat-ulang--pindahkan-cara-peningkatan-tabel-sqlite&#34;&gt;Empat Langkah Buat Ulang &amp;amp; Pindahkan: Cara Peningkatan Tabel SQLite
&lt;/h2&gt;&lt;p&gt;Karena tidak dapat diubah secara langsung, praktik standar yang direkomendasikan oleh dokumentasi resmi adalah &lt;strong&gt;membangun rumah baru, memindahkan furnitur, meledakkan rumah lama, dan memasang papan nama baru&lt;/strong&gt;:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Langkah&lt;/th&gt;
          &lt;th&gt;Tindakan&lt;/th&gt;
          &lt;th&gt;Deskripsi&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;1&lt;/td&gt;
          &lt;td&gt;Buat Tabel Baru&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;CREATE TABLE users_new (...)&lt;/code&gt; menggunakan struktur yang benar&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;2&lt;/td&gt;
          &lt;td&gt;Salin Data&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;INSERT INTO users_new SELECT ... FROM users&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;3&lt;/td&gt;
          &lt;td&gt;Hapus Tabel Lama&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;DROP TABLE users&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;4&lt;/td&gt;
          &lt;td&gt;Ubah Nama Tabel&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;ALTER TABLE users_new RENAME TO users&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Keempat langkah ini harus dijalankan &lt;strong&gt;sekaligus dalam satu waktu&lt;/strong&gt;; mati listrik atau crash aplikasi di tengah jalan akan menyebabkan hilangnya data.&lt;/p&gt;
&lt;!--adsense--&gt;
&lt;h2 id=&#34;memastikan-peningkatan-tidak-kehilangan-data-dua-lapis-pertahanan-keamanan&#34;&gt;Memastikan Peningkatan Tidak Kehilangan Data: Dua Lapis Pertahanan Keamanan
&lt;/h2&gt;&lt;h3 id=&#34;pertahanan-lapis-1-pertahanan-fisik-salin-file-secara-langsung&#34;&gt;Pertahanan Lapis 1: Pertahanan Fisik, Salin File Secara Langsung
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;SQLite&lt;/code&gt; pada dasarnya hanyalah sebuah file. Sebelum melakukan perubahan schema apa pun, cukup salin file &lt;code&gt;.db&lt;/code&gt; sebagai cadangan.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;fs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;fs&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;fs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;copyFileSync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;my_project.db&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;my_project_backup.db&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;Jika terjadi kesalahan, mengganti file cadangan akan memulihkan semuanya dalam sekejap. Ini adalah kelebihan yang tidak dimiliki database besar lainnya.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;pertahanan-lapis-2-pembungkus-transaction-mesin-waktu-database&#34;&gt;Pertahanan Lapis 2: Pembungkus Transaction, Mesin Waktu Database
&lt;/h3&gt;&lt;p&gt;Bungkus semua langkah migrasi di dalam satu &lt;code&gt;Transaction&lt;/code&gt;; jika ada langkah yang gagal, seluruh proses akan &lt;strong&gt;dibatalkan secara otomatis (Rollback)&lt;/strong&gt; seolah tidak terjadi apa-apa.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Database&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;better-sqlite3&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;db&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Database&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;my_project.db&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;migrateData&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;transaction&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;prepare&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sb&#34;&gt;    CREATE TABLE users_new (
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sb&#34;&gt;      id INTEGER PRIMARY KEY AUTOINCREMENT,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sb&#34;&gt;      name TEXT NOT NULL,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sb&#34;&gt;      age INTEGER NOT NULL DEFAULT 18
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sb&#34;&gt;    )
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sb&#34;&gt;  `&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;prepare&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sb&#34;&gt;    INSERT INTO users_new (id, name, age)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sb&#34;&gt;    SELECT id, name, COALESCE(age, 18) FROM users
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sb&#34;&gt;  `&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;prepare&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;DROP TABLE users&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;prepare&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;ALTER TABLE users_new RENAME TO users&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;migrateData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Tabel berhasil ditingkatkan&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Peningkatan gagal, data dipulihkan dengan aman:&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&amp;quot;File cadangan + Pengikatan Transaction&amp;quot;&lt;/strong&gt; adalah kantong udara pengaman migrasi database Anda.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;kendalikan-sqlite-yang-santai-dengan-sikap-tegas&#34;&gt;Kendalikan SQLite yang Santai dengan Sikap Tegas
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;Kuasai &lt;code&gt;SQLite&lt;/code&gt; yang santai dengan &lt;strong&gt;arsitektur lapisan aplikasi yang ketat&lt;/strong&gt; untuk menikmati kecepatan pengembangan kilatnya sekaligus menghindari utang teknis di masa mendatang.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sistem tipe SQLite sangat santai, dan &lt;code&gt;ALTER TABLE&lt;/code&gt; memiliki banyak batasan.&lt;/p&gt;
&lt;p&gt;Namun, selama Anda melakukan &lt;strong&gt;pemeriksaan tipe TypeScript + validasi Zod + ORM abstraksi&lt;/strong&gt; di sisi &lt;code&gt;Node.js&lt;/code&gt;, dipadukan dengan strategi keamanan &lt;strong&gt;cadangan fisik + Transaction&lt;/strong&gt;, Anda dapat menikmati efisiensi pengembangan yang ditawarkan &lt;code&gt;SQLite&lt;/code&gt; dengan aman sambil meratakan jalan untuk bermigrasi ke &lt;code&gt;PostgreSQL&lt;/code&gt; di masa mendatang.&lt;/p&gt;
&lt;!--adsense--&gt;
&lt;h2 id=&#34;reference&#34;&gt;Reference
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://sqlite.org/datatype3.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Datatypes In SQLite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.runoob.com/sqlite/sqlite-data-types.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SQLite 数据类型 | 菜鸟教程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.sqlite.org/lang_transaction.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Transaction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://sqlite.org/lang.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Query Language Understood by SQLite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/SQLite&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SQLite - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        
    </channel>
</rss>
