Manipulasi Data Menggunakan Tabel Pada Database Lain di MySQL

Thursday, February 14th, 2008

MySQL mengizinkan kita untuk memanipulasi data menggunakan data dari database lain. Dengan catatan user kita memiliki akses ke database tersebut. Hal ini bisa dilakukan dengan menyertakan nama database di depan nama tabel. Berikut dua contoh untuk perintah SQL memanipulasi data dari database lain.

CREATE TABLE SELECT

CREATE TABLE  `tost`.`test` SELECT * FROM `test`.`test`
Hasil dari perintah SQL diatas akan membuat table test di database tost yang tabelnya itu (bentuk dan juga isinya) diduplikasi dari tabel test di datbase test.

UPDATE TABLE

UPDATE `tost`.`test`, `test`.`test`
SET `tost`.`test`.`text` = `test`.`test`.`text`
WHERE `tost`.`test`.`id` = `test`.`test`.`id`
Hasil dari perintah SQL diatas akan mengupdate isi field text di table test pada database tost agar sama dengan isi field text di table test pada database test.

Saya rasa kedua contoh perintah SQL diatas sudah cukup, dan mudah - mudahan postingan ini bisa menjawab pertanyaan berikut.

Optimasi Left Join Dengan Subquery di MySQL

Monday, September 3rd, 2007

Left Join adalah salah satu dari beberapa tipe join yang terdapat di SQL untuk mengkombinasikan lebih dari satu tabel. Mengkombinasikan lebih dari satu tabel akan mempengaruhi kecepatan suatu query dalam berinteraksi dengan database. Hal ini akan mengakibatkan aplikasi lebih lambat menampilkan informasi. Pada tulisan kali ini saya akan mengambil contoh penggunaan Left Join dengan 2 tabel, yaitu tabel berita dan tabel komentar dengan key berita_id.

Tabel berita memiliki attribut berita_id, tanggal, judul dan berita. Tabel komentar memiliki attribut komentar_id, pengirim, email, komentar dan berita_id. Kedua tabel ini hanya merupakan sampel yang kondisinya memenuhi syarat untuk menggunakan LEFT JOIN. Kalaupun ada kesamaan tokoh, karakter dan lain sebagainya bukanlah disengaja (koq kayak filem ya? hihihihi)

Untuk menampilkan informasi dari berita dengan jumlah komentar pada setiap berita, dapat menggunakan query berikut :

SELECT A.berita_id, A.judul, A.berita, COALESCE(COUNT(B.komentar_id), 0)
AS total_komentar FROM berita A LEFT JOIN komentar B
USING(berita_id) GROUP BY A.berita_id ORDER BY berita_id DESC

Kenapa query di atas bisa menjadi lambat dengan data dalam jumlah besar?

Karena query tersebut menghitung jumlah key pada tabel sebelah kanan (komentar) sebanyak key pada tabel sebelah kiri (berita). Maka jika tabel berita berisi 4000 data dan tabel komentar berisi 8000 data, maka query diatas akan melakukan pengecekan jumlah komentar sebanyak 4000 kali terhadap 8000 data komentar.

Bagaimana cara mengoptimasinya?

Query diatas dapat dioptimasi dengan membuat tabel di sebelah kanan (komentar) jumlah datanya lebih kecil atau sama dengan jumlah data pada tabel sebelah kiri (berita), dan tidak menghitung key pada tabel sebelah kanan sebanyak jumlah key pada tabel sebelah kiri (berita). Untuk melakukan hal ini bisa dengan menggunakan subquery.

SELECT A.berita_id, A.judul, A.berita, COALESCE(B.total_komentar, 0)
AS total_komentar FROM berita A LEFT JOIN
(SELECT berita_id, COUNT(komentar_id) AS total_komentar
FROM komentar GROUP BY berita_id) B
USING(berita_id) GROUP BY A.berita_id ORDER BY berita_id DESC

Dari query diatas, dapat dilihat tabel sebelah kanan (komentar) berisi subquery yang menghasilkan attribut berita_id dan total_komentar dengan jumlah data yang lebih kecil atau sama dengan jumlah data pada tabel sebelah kiri (berita). Kemudian dengan tabel sebelah kiri dan kanan dikombinasikan tanpa ada penghitungan key pada tabel sebelah kanan sebanyak key pada tabel sebelah kiri. Query ini jika dieksekusi akan memakan waktu sebesar 0.01 detik jauh lebih kecil dari query yang sebelumnya.

Sejauh ini saya masih menggunakan subquery untuk mengoptimasi LEFT JOIN pada contoh kasus seperti di atas. Pada contoh kasus di atas penggunaan subquery meningkatkan waktu eksekusi sebesar 90%.

Penggunaan GNU find Dalam Mencari Dokumen

Saturday, July 14th, 2007

GNU find adalah program di Unix yang digunakan untuk mencari file di dalam hirarki direktori. Program ini memiliki banyak opsi penggunaan yang memudahkan kita dalam mencari dokumen. GNU find mengizinkan kita memberikan perintah/aksi terhadap hasil pencarian, misalnya menghapus, menyalin, melihat ukuran file ataupun aksi - aksi lainnya.

Pada tulisan ini saya tidak akan membahas semua opsi yang ada pada GNU find tapi hanya membahas penggunaan find yang sering saya gunakan, seperti : mencari file/direktori, mencari file/direktori kemudian menghapusnya dan mencari direktori kemudian melihat kapasitas dari direktori tersebut.

Mencari File/Direktori
Untuk mencari file dapat menggunakan perintah ini :

find . -type f -iname 'nama file yang dicari'
Untuk mencari direktori kita hanya perlu mengganti opsi -type f menjadi -type d

find . -type d -iname 'nama direktori yang dicari'

Mencari File/Direktori kemudian menghapusnya
Untuk mencari file dan kemudian menghapusnya dapat menggunakan perintah ini :

find . -type f -iname 'nama file yang dicari' -exec rm -f {} \;
Untuk mencari direktori dan kemudian menghapusnya kita hanya perlu mengganti opsi -type f menjadi -type d

find . -type d -iname 'nama direktori yang dicari' -exec rm -f {} \;
Untuk melakukan aksi lainnya terhadap file yang dicari, cukup dengan mengganti rm -fr dari perintah diatas.

Melihat ukuran folder didalam direktori
Saya belum menemukan perintah untuk melihat ukuran dari folder - folder pada suatu direktori di Unix. Untuk melakukan hal ini saya biasa menggunakan GNU find dengan opsi -iregex untuk memfilter hasil pencarian.

find . -type d -iregex '^\.\/[^\/]*$' -exec du -sh {} \;
Perintah diatas sama halnya dengan perintah mencari direktori dan kemudian menghapusnya, cuma bedanya disini kita menggunakan menggunakan du -sh untuk melihat ukuran folder dan opsi -iregex. Opsi ini digunakan untuk memfilter hasil pencarian dengan menggunakan regex, karena jika tidak difilter GNU find akan menampilkan semua folder atau dengan kata lain folder yang ada didalam folder yang kita cari juga ditampilkan. Berikut hasil pencarian folder jika tidak difilter :

./Aqil
./Aqil/26-06-2007
./Aqil/03-07-2007
./Dolly

Dari hasil pencarian diatas, terlihat folder yang ada didalam folder Aqil juga ditampilkan. Padahal yang ingin kita tampilkan hanyalah folder Dolly dan Aqil. Untuk memfilternya digunakan opsi -iregex dengan pattern ‘^\.\/[^\/]*$’. Jika anda belum memahami tentang regex bisa melihat tautan berikut.

Opsi - opsi yang digunakan
Sekarang kita akan membahas opsi - opsi dari GNU find yang kita gunakan.

-type

Opsi ini digunakan untuk menentukan tipe dari file yang dicari. Sebagai contoh -type d digunakan untuk mencari direktori, -type f digunakan untuk mencari file

-iname

Opsi ini sama dengan opsi -name yang mencari file berdasarkan nama filenya, cuma bedanya opsi ini tidak case sensitive terhadap hasil pencarian

-exec

Opsi ini sama digunakan untuk melakukan aksi terhadap hasil pencarian

-iregex

Opsi ini sama dengan opsi -regex yang mencari file berdasarkan pattern yang diberikan, cuma bedanya opsi ini tidak case sensitive terhadap hasil pencarian.

Contoh penggunanan GNU find diatas bisa anda kembangkan lagi sesuai dengan kebutuhan anda. Untuk penjelasan selanjutnya bisa anda lihat di manual GNU find dengan menjalankan perintah man find dari shell anda atau bisa melihat tautan berikut.

Mengaktifkan Absolute URL di TinyMCE

Tuesday, July 3rd, 2007

Jika anda menggunakan TinyMCE sebagai WYSIWYG editor, secara default URL dari image yang anda masukkan (http://example.com/main/image/example.jpg) akan di ubah menjadi Relative URL (../image/example.jpg).

Hal ini tentu menjadi masalah jika mencoba menampilkan image tersebut di root direktori (http://example.com) yang menyebabkan image tidak bisa ditampilkan. Hal ini juga yang saya alami kemarin, dan setelah googling menemukan jawaban bahwa Relative URL di TinyMCE itu bisa dinon aktifkan.

Untuk menon aktifkan Relative URL tersebut dapat dilakukan dengan cara menset relative_url menjadi false pada method tinyMCE.init()

tinyMCE.init({
/** other configs */
relative_urls : false
});

Pada method mcImageManager.init() relative_urls juga diset menjadi false.

mcImageManager.init({
relative_urls : false
});

Jika anda menghadapi permasalahan yang sama, cara diatas bisa dicoba.

Bersahabat Dengan Single Quotes

Thursday, June 14th, 2007

Jika tidak diescape, Single Quotes (tanda kutip satu) yang dikirim melalui form pada aplikasi web dapat menimbulkan masalah yang besar. Masalah yang ditimbulkannya bermacam - macam, dari SQL Injection sampai gagalnya data di insert ke database.

Dari PHP sendiri sebenarnya sudah ada setingan untuk mengescape single quotes, yaitu dengan menset magic_quotes_gpc menjadi On di php.ini. Tetapi kita tidak bisa mengandalkan hal ini, karena setingan server web hosting belum tentu sama dengan setingan di PC tempat anda mendevelop aplikasi tersebut. Dan anda tidak mempunyai akses untuk merubah setingan php.ini di server web hosting, kecuali server tersebut milik anda.

Cara lain yang sering digunakan adalah dengan mengescape single quotes secara manual dengan fungsi addslashes(). Sebenarnya cara ini kurang bijaksana dalam hal mengescape single quotes. Jika magic_quotes_gpc diaktifkan di server tersebut, maka single quotes ini akan otomatis diescape sehingga menghasilkan karakter berikut \’ . Jika kita menambahkan lagi addslashes() maka akan menghasilkan karakter \\\’ , karena yang diescape bukan hanya single quotes tapi backslash juga ikut di escape.
Jika anda pernah melihat karakter \’ (\’ adalah display dari karakter \\\’) pada suatu situs, maka hal diatas adalah penyebabnya.

Saya mempunyai cara tersendiri untuk mengatasi hal ini, yaitu dengan membuat satu fungsi yang melakukan pengecekan terlebih dahulu apakah magic_quotes_gpc diaktifkan atau tidak dengan menggunakan fungsi get_magic_quotes_gpc(). Jika magic_quotes_gpc diaktifkan maka single quotes tidak perlu di escape secara manual. Jika tidak aktif maka escape single quotes dengan fungsi addslashes().
Berikut ini contoh scriptnya :

function magic_quotes_gpc_on($string)
{
return (get_magic_quotes_gpc()) ? $string : addslashes($string) ;
}

// Contoh penggunaan
$nama = isset($_POST[’nama’]) ? magic_quotes_gpc_on($_POST[’nama’]) : ‘’ ;
Sangat simpel kan? Apakah anda mempunyai cara yang lain dalam mengatasi single quotes ini?

Menghapus Semua Tabel di Database

Tuesday, June 5th, 2007

Dalam MySQL, untuk menghapus sebuah tabel dapat menggunakan perintah DROP TABLE. Tapi bagaimana untuk menghapus semua tabel yang ada di database? Sementara ini perintah untuk menghapus semua tabel ini belum ada di MySQL. Lho, lantas bagaimana kalau kita ingin menghapus semua tabel? Apa dihapus satu persatu? Aduh, cape de…

Untuk mengatasi permasalahan diatas kita bisa menggunakan mysqldump dan sedikit shell script. Dapat dilihat pada contoh berikut :

mysqldump [-u username] [-ppassword] nama_database --no-data

--add-drop-table | grep ^DROP | xargs -0 mysql [-u username]

[-ppassword] nama_database -e

Penggunaan :

  • Opsi -u diatas bersifat optional. Artinya jika database anda tidak dimiliki oleh user tertentu opsi -u ini tidak diikut sertakan.
  • Opsi -p diatas bersifat optional. Artinya jika user dari database anda tidak memiliki password maka opsi -p ini tidak diikut sertakan.
  • nama_database diganti sesuai dengan database anda
  • Perintah ini hanya dapat dijalankan di unix shell dengan asumsi anda sudah menginstall mysqldump.