Tak terasa sudah hampir menyentuh 4 tahun dan aplikasi web yang dibangun membengkak ukuran SQL-nya meningkatnya berlipat-lipat. Membengkaknya ukuran MYSQL jelas saja menurunkan performa speed website. 

Query data yang besar pada database jelas saja menjadi salah satu biang keroknya. Meski dapat di optimasi dengan banyak macam cara, misalnya dari mulai memindahkan database tidak dalam 1 hosting dengan aplikasinya, membuat clone,  sampai dengan mengganti platform Frameworknya dengan Laravel yang mampu meng-query data dengan baik menggunakan Elequent).

Namun, lagi-lagi cost yang dibutuhkan cukup lumayan dari sisi peningkatan performa Server untuk database dan tingkat fleksibilitas. Akhirnya karena skalanya sudah mulai besar dan rumit, diputuskanlah untuk mengupgrade ke PostgreSQL !!.

Alasan migrasi MySQL ke PostgreSQL

Ada beberapa alasan kenapa kami harus beralih ke PostgreSQL, diantaranya adalah :

  1. PostgreSQL paling cocok dipakai diLaravel karena perintah query eksekusi datanya hampir mirip dengan MySQL. (meski tidak semua ~ ada beberapa yang tidak compatible meskipun jumlahnya sedikit).
  2. Butuh fitur yang dapat menyimpan item data dalam jumlah banyak dalam satu record. PostgreSQL jagonya!
  3. PostgreSQL memiliki kecepatan lebih baik meski dalam Load tinggi. Jauh lebih baik dari kecepatan yang dimiliki MySQL dalam hal query dengan klausa JOIN dengan tingkat yang kompleks.
  4. Salah satu alasan utama kami pindah ke PostgreSQL, adalah karena memiliki  tipe Data Geometri yang digunakan untuk maps. Tipe data geometri yang disupport diantaranya adalah data titik, garis, lingkaran dan polygon. Sangat bermanfaat untuk membuat aplikasi web yang dengan basis untuk pemetaan dan lain sebagainya misalnya Web GIS
  5. PostgreSQL dapat mendefinisikan Field sebagai Array juga dapat menerjemahkan / mendefinisikan field yang biasanya belum dapat terdefinisi otomatis sebagai array.
  6. Free to Use alias gratis 😀 , memiliki Lisensi GPL (General Public License): yang dapat digunakan secara bebas oleh setiap penggunanya tanpa harus melalui proses pemesanan, pembayaran alias free of charged.

Migrasi PostgreSQL pada Laravel

Jika misalnya anda berencana membuat sebuah website dalam skala medium atau agak besar langsung saja deploy menggunakan database PostgreSQL kebetulan Laravel support dengan PostgreSQL. Tinggal setting saja dibagian .env (file dibagian root). Misalnya :

DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=databasemu

DB_USERNAME=usernamemu
DB_PASSWORD=passwordmu

atau jika tidak dideklarasikan di .env, maka bisa diganti dibagian app/config.php (bagian database).

Namun jika melakukan migrasi dari situs yang sudah ada menggunakan MySQL, maka banyak hal yang harus diperhatikan, akan banyak sekali error disana-sini, terutama yang berkaitan dengan Query dan CRUD yang berlokasi dibagian Controller, Command atau Model . Misalnya yang paling mencolok menurut pengalaman saya adalah:

  1. Fungsi “groupBy” tidak berjalan dengan baik.  Kebanyakan code error ini saya alami dibagian ini. Solusinya saya menggantinya dengan “distinct” dan menambahkan beberapa script tambahan collections.
  2. Error random yang muncul adalah fungsi query “LIKE”. Dalam beberapa kesempatan hasil “LIKE” tidak menghasilnya hasil yang tepat ketika menggunakan PostgreSQL. Salah satu penyebabnya adalah PostgreSQL tidak dapat mendeteksi otomatis text Uppercase dan Lowercase (case sensitive) seperti halnya MySQL. Misalnya saja didalam kolom tabel data terdapat name dengan 3 value yaitu “KANGmas”, “kangartha” dan “Kangkung” dengan query:

    $data = Data::where("name", "LIKE", "%kang%")->get();
    // MySQL akan menghasilkan 3  buah data
    // PostgreSQL akan menghasilkan 1 buah data

    Untuk saat ini solusi yang saya pakai mengganti LIKE dengan ILIKE dan hasilnya sesuai dengan hasil MySQL. Meski saya merasakan bahwa query dengan ILIKE sedikit lambat jika melakukan query dalam jumlah besar misalnya saja dipakai untuk membuat fungsi search, namun pendekatan ini lebih bagus dibandingkan dengan menambahkan fungsi LOWER(namaKolom), atau UPPER(namaKolom). Hasil penambahan dengan ILIKE adalah sebagai berikut

    $data = Data::where("name", "ILIKE", "%kang%")->get();
  3. Entah kenapa ada beberapa tabel yang tidak dapat dilakukan “insert data” secara otomatis menggunakan script php yang sudah dibuat di Laravel, error yang muncul misalnya sebagai berikut :

    PDOException::("SQLSTATE[23505]: Unique violation: 7 ERROR: duplicate key value violates unique constraint "recording_calltools_pkey"DETAIL: Key (id)=(5) already exists.")

    Error diatas disebabkan karena PostgreSQL menolak memasukkan data karena key id-nya (angka 5) exist, seakan-akan tidak dapat melakukan autodetect last-id untuk memasuk-kan data. Sehingga mau nggak mau harus merubah menambahkan insert data.id manual pada waktu insert data. Contoh kalau biasanya kita membikin script PHP insert data :

    MySQL
    $data = new Data;
    $data->name = "kangartha";
    $data->status = "kawin";
    $data->save();

    PostgreSQL
    $data = new Data;
    $data->id = 6; /* contoh data id yang dimasukkan */
    $data->name = "kangartha";
    $data->status = "kawin";
    $data->save();

    dengan cara ini PostgreSQL dapat memasukkan datanya kedalam database, selama ditabel tidak ada id no 6. Masalahnya adalah kita ingin melakukan insert data secara otomatis, sehingga kita musti membuat script yang mampu mendeteksi id terakhir dari data yang sudah ada. Sehingga sewaktu memasukkan $data->id = lastid + 1 . Bagaimana caranya? nah untuk saat ini, ini yang saya pakai untuk dimasukkan ke bagian Model Data :

    protected function getNextStatementId()
    {
       $latest = DB::table('nama_tabel')->latest('id')->first();
       return $latest->id + 1;
    }

    Sehingga Script Query di Controller nantinya akan menjadi :

    $data = new Data;
    $data->id = Data::getNextStatementId();
    $data->name = "kangartha";

    $data->status = "kawin";
    $data->save();
  4. Import Expor data agak ribet, meskipun ekspor data dari MySQL dapat menggunakan perintah mysqldump (memakai console), sayangnya hasil dari ekspor ini terkadang tidak selalu dapat digunakan. Kadang masih memberikan error ketika import dilakukan ke PostgreSQL. Solusi lain yang dapat dilakukan sih menggunakan sebuah script Python.

    wget https://raw.githubusercontent.com/lanyrd/mysql-postgresql-converter/master/db_converter.py
    python db_converter.py namadatakamu.mysql namadatakamu.psql

    nah selanjutnya import deh ke PostgreSQL menggunakan perintah psql -f namadatakamu.psql

    Atau bagi yang tidak paham dengan console, bisa menggunakan bantuan tool lain untuk urusan Export Import misalnya adminer.
  5. Kadang Instalasi PostgreSQL macet (hanya saya temui di Localhost Laptop ~ bisa jadi disebabkan karena conflict dengan database lain). Ada muncul pesan error :  Unable to connect to PostgreSQL server: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket “/tmp/.s.PGSQL.5432”? . Dan solusinya dengan mengetikkan perintah ini di console : 

    rm /usr/local/var/postgres/postmaster.pid

 

Catatan :

  • Environment yang saya pakai pada aplikasi web yang saya bangun menggunakan Laravel 5.8 (sudah melakukan beberapa kali upgrade Laravel dari versi 4, belum mencoba untuk versi Laravel 6.0 yang konon lebih baik supportnya menggunakan PostgreSQL).
  • Instalasi PostgreSQL sedikit berbeda dengan MySQL dalam Localhost (development/laptop/PC). Biasanya saya mendevelop aplikasi web menggunakan MAMP pada Laptop MAC, namun berhubung database PostgreSQL tidak disediakan di MAMP, maka harus mengunduh postgreSQL di https://www.postgresql.org/download/ , ikuti petunjuknya 😀 .
  • Sebelum melakukan migrasi pastikan sesuai dengan kebutuhan, ada banyak database lain yang  tak kalah baik, misalnya MongoDB, namun karena kebutuhan kami adalah banyak data Polygon dan MultiPolygon maka pilihan kami jatuh ke PostgreSQL.
  • Setelah selesai Migrasi, pastikan lakukan 2 command ini pada command console php artisan cache:clear dan php artisan config:clear.
  • Issues yang saya tulis diatas hanyalah berdasarkan pengalaman yang kami alami, bisa jadi ada issues lain yang belum terdeteksi, yang dilain waktu jika ditemukan, maka kami akan update secara continue dalam artikel ini.