MySQL
MySQL adalah sebuah
perangkat lunak Pembuat database yang bersifat terbuka atau open source dan
berjalan disemua platform baik Linux maupun Si Windows, MySQL merupakan program pengakses
database yang bersifat network sehingga dapat digunakan untuk aplikasi Multi
User (Pengguna Banyak).
MySQL adalah Relational
Database Management System (RDBMS) yang didistribusikan secara gratis dibawah
lisensi GPL (General Public License).
Dimana setiap orang bebas untuk menggunakan MySQL, namun tidak boleh dijadikan
produk turunan yang bersifat komersial.
Keistimewaan MySQL
MySQL
memiliki beberapa keistimewaan, antara lain :
1. Portabilitas. MySQL dapat berjalan
stabil pada berbagai sistem operasi seperti Windows, Linux, FreeBSD, Mac Os X
Server, Solaris, Amiga, dan masih banyak lagi.
2. Perangkat lunak sumber
terbuka.
MySQL didistribusikan sebagai perangkat lunak sumber terbuka,
dibawah lisensi GPL sehingga dapat digunakan secara gratis.
3. Multi-user. MySQL dapat digunakan
oleh beberapa pengguna dalam waktu yang bersamaan tanpa mengalami masalah atau
konflik.
4. 'Performance tuning',
MySQL memiliki kecepatan yang menakjubkan dalam menangani query sederhana,
dengan kata lain dapat memproses lebih banyak SQL per satuan waktu.
5. Ragam tipe data. MySQL memiliki ragam tipe
data yang sangat kaya, seperti signed / unsigned integer, float, double, char,
text, date, timestamp, dan lain-lain.
6. Perintah dan Fungsi. MySQL memiliki operator
dan fungsi secara penuh yang mendukung perintah Select dan Where dalam perintah
(query).
7. Keamanan. MySQL memiliki beberapa
lapisan keamanan seperti level subnetmask,
nama host, dan izin akses user dengan
sistem perizinan yang mendetail serta sandi terenkripsi.
8. Skalabilitas dan Pembatasan. MySQL mampu menangani
basis data dalam skala besar, dengan jumlah rekaman (records) lebih dari
50 juta dan 60 ribu tabel serta 5 milyar baris. Selain itu batas indeks yang
dapat ditampung mencapai 32 indeks pada tiap tabelnya.
9. Konektivitas. MySQL dapat melakukan
koneksi dengan klien menggunakan protokol TCP/IP, Unix soket (UNIX),
atau Named Pipes (NT).
10. Lokalisasi. MySQL dapat mendeteksi
pesan kesalahan pada klien dengan menggunakan lebih dari dua puluh bahasa.
Meski pun demikian, bahasa Indonesia belum termasuk di dalamnya.
11. Antar Muka. MySQL memiliki antar muka
(interface) terhadap berbagai aplikasi dan bahasa pemrograman dengan
menggunakan fungsi API (Application Programming Interface).
12. Klien dan Peralatan. MySQL dilengkapi dengan
berbagai peralatan (tool)yang dapat digunakan untuk administrasi basis data, dan
pada setiap peralatan yang ada disertakan petunjuk online.
13. Struktur tabel. MySQL memiliki struktur
tabel yang lebih fleksibel dalam menangani ALTER TABLE, dibandingkan basis data
lainnya semacam PostgreSQL ataupun Oracle.
Lewat artikel ini kita akan membahas hal-hal
dasar apa yang perlu diketahui agar bisa memakai MySQL dengan efektif dan
efisien. Mari kita mulai dengan hal nomor satu:
Programer PHP atau Perl tentu saja familiar
dengan array dan hash, yang biasanya dipakai untuk menyimpan sekumpulan data
terkait. Sebagian dari mereka yang tidak familiar dengan MySQL akan cenderung
menganalogikan tabel database dengan array/hash (tepatnya, array of array atau
array 2 dimensi). Tabel dipandang sama seperti sebuah array, hanya saja bisa
berukuran besar sekali dan persisten (disimpan di disk).
Cara pandang ini tidak sepenuhnya salah,
karena toh dalam mengambil record dari tabel biasanya ditampung ke dalam
variabel array/hash. Hanya saja, cara pandang ini kadang-kadang membuat
programer PHP melakukan sesuatu seperti:
$res
= mysql_query("SELECT * FROM t1");
$rows = array();
while ($row = mysql_fetch_row($res)) $rows[] = $row;
echo "Jumlah record di tabel t1 = ", count($rows);
$rows = array();
while ($row = mysql_fetch_row($res)) $rows[] = $row;
echo "Jumlah record di tabel t1 = ", count($rows);
atau membuat tabel seperti:
CREATE
TABLE t2 (
f0 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
f1 INT UNSIGNED,
f2 VARCHAR(5),
f3 VARCHAR(200),
f4 VARCHAR(200),
f5 BLOB
);
f0 INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
f1 INT UNSIGNED,
f2 VARCHAR(5),
f3 VARCHAR(200),
f4 VARCHAR(200),
f5 BLOB
);
Apa yang salah dengan kode PHP pertama di
atas, yang bertujuan mencari jumlah record dalam sebuah tabel? Si programer,
yang terlalu terobsesi menganggap tabel MySQL sebagai sebuah array, mencoba
membangun dulu arraynya dengan mengisi satu-persatu elemen dari hasil query
agar nantinya bisa menggunakan fungsi array count(). Masalahnya, bagaimana
kalau jumlah record ada 100 ribu? 1 juta? 10 juta? Bukan itu saja, selesai di-count() variabel$rows langsung
dibuang lagi! Padahal, ada cara yang jauh lebih efisien:
SELECT
COUNT(*) FROM t1
Hasil querynya hanyalah sebuah record saja,
tak peduli berapa pun ukuran tabel t1.
Lalu apa yang salah dengan kode SQL kedua? Si
programer Perl, dalam hal ini, terobsesi ingin mengambil tiap record di tabel
dengan fungsi DBI $sth->fetchrow_array()
@row
= $sth->fetchrow_array();
print $row[0]; # f0
print $row[1]; # f1
print $row[2]; # f2
# ...
print $row[0]; # f0
print $row[1]; # f1
print $row[2]; # f2
# ...
Enak bukan? Elemen ke-0 berisi nilai field f0,
elemen ke-1 field f1, dst. Masalahnya, kemudahan ini mengorbankan nama
field yang menjadi sangat tidak deskriptif. Belum lagi kalau tabel perlu diubah
dengan menyisipkan field-field lain di antara field yang sudah ada. Atau
field-field lama perlu dihapus. Semuanya akan menjadi mimpi buruk.
Sebagian pembaca mungkin geleng-geleng
kepala. Apa benar ada programer PHP dan Perl yang melakukan kedua hal di atas?
Percaya deh, ada. Saya pernah harus ketiban getah memaintain tabel dengan nama
field kriptik seperti ini.
MySQL adalah database SQL bukan? Sayangnya,
programer PHP pemula kadang terbatas sekali pengetahuan SQL-nya. Padahal, untuk
menggunakan database MySQL dengan efektif, ia tidak boleh malas mempelajari
bahasa kedua, yaitu SQL. Jika tidak belajar SQL, maka ada kemungkinan Anda akan
melakukan hal-hal seperti:
$res
= mysql_query("SELECT * FROM bigtable");
while ($row = mysql_fetch_assoc($res)) {
if ($row['age'] >= 40) {
echo "Ditemukan kustomer yang berusia lebih dari 40 tahun!\n";
break;
}
}
while ($row = mysql_fetch_assoc($res)) {
if ($row['age'] >= 40) {
echo "Ditemukan kustomer yang berusia lebih dari 40 tahun!\n";
break;
}
}
Apa salah kode di atas? Si programer PHP
mencoba mensimulasikan klausa WHERE SQL dengan melakukan pengujian
kondisi di kode PHP. Padahal, yang seharusnya dilakukan adalah:
SELECT
* FROM bigtable WHERE age >= 40
Ini amat mengirit trafik client/server karena
tidak semua record harus dikirimkan dari MySQL ke program PHP Anda.
Sebagian pembaca mungkin geleng-geleng
kepala. Apa benar ada programer PHP yang seperti ini? Percaya deh, ada.
SQL sudah menyediakan cara untuk menyortir
data, memformat tampilan, mengelompokkan dan memfilter record, dsb. MySQL juga
terkenal banyak menyediakan fungsi-fungsi, mulai dari manipulasi tanggal,
angka, string, dsb. Kenali SQL dan fungsi-fungsi MySQL; jangan duplikasikan ini
semua di PHP sebab akan lebih efisien jika dilakukan di level MySQL.
Ini contoh lain programer PHP yang tidak
memanfaatkan fasilitas dari MySQL:
$res
= mysql_query("SELECT * FROM customers");
while ($row = mysql_fetch_assoc($res)) {
# format semula yyyy-mm-dd...
preg_match("/(\d\d\d\d)-(\d\d?)-(\d\d?)/", $row[date], $matches);
# ... dan ingin dijadikan dd/mm/yyyy
$tanggal = "$matches[3]/$matches[2]/$matches[1]";
echo "Nama=$row[name], Tanggal lahir=$tanggal<br>\n";
}
while ($row = mysql_fetch_assoc($res)) {
# format semula yyyy-mm-dd...
preg_match("/(\d\d\d\d)-(\d\d?)-(\d\d?)/", $row[date], $matches);
# ... dan ingin dijadikan dd/mm/yyyy
$tanggal = "$matches[3]/$matches[2]/$matches[1]";
echo "Nama=$row[name], Tanggal lahir=$tanggal<br>\n";
}
Padahal MySQL sudah menyediakan fungsi
pemformatan dan manipulasi tanggal:
$res
= mysql_query("SELECT name, DATE_FORMAT(date,'%d-%m-%Y') as tanggal
".
"FROM customers");
while ($row = mysql_fetch_assoc($res)) {
# tidak perlu capek-capek manipulasi string lagi...
echo "Nama=$row[name], Tanggal lahir=$row[tanggal]<br>\n";
}
"FROM customers");
while ($row = mysql_fetch_assoc($res)) {
# tidak perlu capek-capek manipulasi string lagi...
echo "Nama=$row[name], Tanggal lahir=$row[tanggal]<br>\n";
}
Poin no. 2 ini kedengarannya klise, tapi,
seperti nasihat Inggris bilang: know thy tools.
Salah satu alasan mengapa MySQL sangat cocok
untuk aplikasi Web adalah mendukung klausaLIMIT. Dengan klausa ini, mudah sekali
membatasi jumlah record hasil yang diinginkan dalam satu perintah SQL. Tidak
perlu bermain kursor atau bersusah payah lewat cara lainnya. Belakangan
database lain seperti PostgreSQL dan Firebird pun ikut mendukung fungsionalitasLIMIT (dengan
sintaks yang tidak persis sama tentunya).
Sayangnya, programer PHP sendiri yang belum
mengenal MySQL dengan baik tidak menggunakannya dengan semestinya.
$res
= mysql_query("SELECT name FROM users ORDER BY date");
$rows = array();
for ($i=1; $i<=10; $i++) $rows[] = mysql_fetch_row($res);
$rows = array();
for ($i=1; $i<=10; $i++) $rows[] = mysql_fetch_row($res);
Si programer hanya berniat mengambil 10
record, tapi menyuruh MySQL mengambil semua record yang ada dulu. Bagaimana
kalau ada 100 ribu record? 1 juta record? 10 juta? Seharusnya, setiap kali Anda
menginginkan hanya satu, sepuluh, lima belas record, Anda perlu memberitahu
MySQL lewat klausa LIMIT.
SELECT
name FROM users ORDER BY date LIMIT 10
Sehingga kita bisa mengirit trafik komunikasi
client/server dan mengizinkan MySQL melakukan optimisasi terhadap query
tersebut.
Berbeda dengan PHP dan bahasa-bahasa
skripting yang mengizinkan kita menaruh apa saja dalam sebuah $variable tanpa
deklarasi tipe terlebih dahulu, di MySQL kita perlu mendeklarasikan tipe-tipe
data semua field yang ada pada saat membuat sebuah tabel. Seorang programer PHP
yang tidak kenal MySQL kadang-kadang cenderung memilih jenis data yang salah
(umumnya: memilih VARCHAR() padahal ada tipe data yang lebih tepat) dikarenakan
tidak mengenal jenis-jenis data yang tersedia.
Berikut beberapa contoh kurang tepatnya
pemilihan tipe data: 1) memilih CHAR(8) atauVARCHAR(10) dan
bukannya DATE untuk menyimpan tanggal; kerugiannya, lebih boros
tempat dan tidak bisa memanfaatkan fungsi-fungsi khusus tanggal; 2) memilih CHAR(3) atau CHAR(6)ketimbang TINYINT
UNSIGNED untuk menyimpan data boolean (“YES” dan “NO”; atau “TRUE” dan
“FALSE”; padahal jauh lebih irit dinyatakan dengan 1 dan 0 yang hanya menempati
1 byte); 3) memilih FLOAT atau DOUBLE dan bukannya DECIMAL untuk menyimpan
jumlah uang; kerugiannya, FLOAT dan DOUBLE adalah berbasis biner dan seringkali
tidak eksak dalam menyimpan pecahan desimal.
Nomor 3 sering terjadi karena programer
biasanya hanya mengenal single/double floating point number yang tersedia di
bahasa pemrograman. Padahal database umumnya menyediakan angka pecahan berbasis
desimal yang bisa eksak menyimpan pecahan desimal.
Manual MySQL amat membantu di sini; di subbab
tentang Column Types dijelaskan dengan rinci jenis-jenis data
yang ada, termasuk rentang nilai yang dapat ditampung, berapa byte yang ditempati
tipe data tersebut, dsb.
Normalisasi, skema, entiti-atribut, primary
key (PK) dan foreign key (FK), tabel entiti, tabel relasi, OLTP & OLAP…
semuanya adalah istilah-istilah yang umum dijumpai dalam pemodelan fisik database.
Sayangnya, banyak programer pemula tidak memiliki kemampuan modeling. Sehingga
jika disuruh mendesain skema database (sekumpulan tabel-tabel beserta nama
field dan tipenya) hasilnya tidak optimal bahkan berantakan. Skema yang buruk
berakibat terjadinya duplikasi data, tidak scalable, performance yang buruk,
tidak memenuhi requirements, dsb.
Modeling tentunya tidak bisa diajarkan dalam
1–2 hari, apalagi dalam artikel yang singkat ini. Anda perlu membaca buku-buku
mengenai pemodelan database dan belajar dari pengalaman maupun dari model-model
yang sudah ada. Tapi beberapa nasihat yang mungkin bisa saya berikan di sini
adalah sbb.
Satu, langkah pertama dalam pemodelan adalah
menemukan entiti-entiti. Entiti bisa dibilang “objek” yang akan kita gelluti.
Misalnya, customer, produk, dan transaksi. Setiap entiti umumnya ditaruh dalam
satu tabel, tabel ini disebut tabel entiti. Langkah kedua adalah mencari
atribut-atribut entiti tersebut. Misalnya tabel customers memiliki atribut
sapaan, nama, alamat (jalan + kota + kodepos + propinsi + negara), tanggal
record ini ditambahkan, dsb. Langkah ketiga adalah mencari relasi di antara
entiti-entiti. Umumnya relasi adalah satu dari: 1-1, 1-many, many-many.
Misalnya, relasi antara transaksi dan produk adalah many-many, artinya sebuah
transaksi pembelian dapat berisi banyak produk dan sebuah produk tentu saja
dapat dibeli dalam lebih dari satu transaksi. Setiap relasi juga akan
ditempatkan pada tabel, yaitu tabel relasi.
Dua, dalam pemodelan tidak ada istilah model
yang benar atau salah. Yang ada adalah model yang tepat dan tidak tepat untuk
keperluan tertentu. Misalnya, untuk aplikasi sederhana modelnya sederhana.
Semakin kompleks aplikasi, model pun semakin rumit (jumlah entiti, relasi, dan
atribut akan bertambah). Pada umumnya, seiring kompleksitas bertambah, yang
tadinya atribut akan berubah menjadi entiti dikarenakan adanya
kenyataan hubungan 1-many/many-many antara atribut. Contohnya, tabel customers
memiliki atribut alamat. Jika kita ingin mendukung banyak alamat untuk satu
customers, maka alamat akan menjadi entiti dan menempati tabel sendiri. Lalu
kita membuat tabel relasi customers-alamat.
Indeks adalah sesuatu yang berkaitan erat
dengan implementasi, bukan modeling. Kita seringkali perlu menambahkan indeks
pada sebuah field atau banyak field dikarenakan jika tidak ditambahkan maka
performance database tidak menjadi praktis. Serba-serbi indexing juga mungkin
terlalu panjang untuk bisa dijelaskan dalam artikel pendek ini, tapi intinya
setiap kolom yang: 1) memiliki rentang nilai cukup banyak; 2) terletak pada
tabel yang berisi banyak record; 3) seringkali disebutkan di klausa WHERE dan/atau ORDER
BY dan/atau GROUP BY; perlu diberi indeks. Ini dikarenakan indeks
membantu mencari secara cepat sebuah nilai dari banyak nilai yang ada. Beberapa
contoh:
* Setiap primary key umumnya otomatis diberi
indeks oleh database server, meskipun tabelnya masih berisi sedikit record atau
bahkan kosong. Ini dikarenakan database perlu selalu mengecek keberadaan sebuah
nilai field ini manakala ada sebuah record yang ditambahkan (ingat, PK artinya
tak boleh ada dua record yang mengandung nilai field ini yang sama). Tanpa
indexing, pengecekan akan linear dan memakan waktu lama.
* Field tanggal lahir dalam tabel customers
kemungkinan besar harus diindeks. Bahkandayofyear() field ini juga mungkin
perlu diindeks. Mengapa? Karena: 1) rentang nilai cukup besar (365 hari dalam
setahun x +- 60 jumlah tahun); 2) tabel customers potensial ukurannya besar; 3)
sering disebutkan di klausa WHERE (misalnya mencari customer yang
ultah hari ini).
* Field memo/notes kemungkinan besar tidak
perlu diindeks (secara biasa). Mengapa? Karena meskipun 1) rentang nilai cukup
besar; dan 2) tabel customers bisa besar; tapi 3) field ini tidak pernah
disebutkan di klausa WHERE secara langsung (mis: Anda tidak pernah
menyebutkan: …WHERE notes='nilai catatan tertentu' atau WHERE notes
> 'nilai tertentu'). [Catatan: ada indeks lain yang “tidak biasa” di MySQL,
yaitu FULLTEXT. Tapi ini di luar cakupan artikel kita kali ini.]
* Field jenis kelamin mungkin tidak perlu
diindeks, kecuali jika perbandingan pria:wanita amat drastis bedanya. Mengapa?
Sebab: 1) rentang nilai yang ada hanyalah dua: L (lelaki) dan P (perempuan).
Meskipun Anda beri indeks, tidak akan memperbaiki kinerja.
Programer web pemula kadang-kadang tidak
menyadari bahwa program/skrip yang dibuatnya tidaklah seperti program desktop
yang dijalankan oleh satu user. Melainkan, dalam satu waktu bisa saja ada 10
atau 100 user yang “menembak” skrip Anda di Web. Karena itu, isu locking dan
konkurensi penting sekali. Contohnya adalah seperti ini:
$res
= mysql_query("SELECT value FROM counters WHERE name='counter1'");
list ($value) = mysql_fetch_row($res);
$value++;
// do something else first...
$res = mysql_query("UPDATE counter SET value=$value WHERE name='counter1'");
list ($value) = mysql_fetch_row($res);
$value++;
// do something else first...
$res = mysql_query("UPDATE counter SET value=$value WHERE name='counter1'");
Di antara baris pertama (saat kita mengambil
nilai record) dan baris keempat (saat kita menaruh kembali nilai dalam record)
mungkin saja telah terjadi beberapa kali perubahan terhadap si record.
Misalnya, pada baris pertama klien1 memperoleh nilai $value = 100. Di baris 3 $value di-increment
menjadi 101. Tapi apa yang terjadi jika selama selang waktu itu nilai record
counter1 telah menjadi 103 (karena misalnya klien2, klien3, dan klien4 telah
meng-incrementnya)? Oleh si klien1, counter1 direset kembali menjadi 101 dan
akibatnya increment oleh klien2, klien3, dan klien4 hilang. Seharusnya nilai
counter1 menjadi 104.
Untuk kasus di atas, pemecahannya cukup
gampang. Lakukan increment secara atomik:
//
tidak perlu ambil nilai counter dulu...
// do something else first...
$res = mysql_query("UPDATE counter SET value=value+1 WHERE name='counter1'");
// do something else first...
$res = mysql_query("UPDATE counter SET value=value+1 WHERE name='counter1'");
Tapi dalam kasus lain, kadang-kadang kita
harus melakukan locking terhadap tabel atau record untuk
menjamin bahwa selama kita // do something else… klien2, klien3, dan
klien4 tidak bisa seenaknya menaikkan nilai counter:
mysql_query("LOCK
TABLES cuonters");
$res = mysql_query("SELECT value FROM counters WHERE name='counter1'");
list ($value) = mysql_fetch_row($res);
// do something else first... increase value or something...
$res = mysql_query("UPDATE counter SET value=$value WHERE name='counter1'");
mysql_query("UNLOCK TABLES");
$res = mysql_query("SELECT value FROM counters WHERE name='counter1'");
list ($value) = mysql_fetch_row($res);
// do something else first... increase value or something...
$res = mysql_query("UPDATE counter SET value=$value WHERE name='counter1'");
mysql_query("UNLOCK TABLES");
atau (lebih baik karena kita tidak perlu
melock keseluruhan tabel):
mysql_query("SELECT
GET_LOCK('lock1')");
$res = mysql_query("SELECT value FROM counters WHERE name='counter1'");
list ($value) = mysql_fetch_row($res);
// do something else first... increase value or something...
$res = mysql_query("UPDATE counter SET value=$value WHERE name='counter1'");
mysql_query("SELECT RELEASE_LOCK('lock1')");
$res = mysql_query("SELECT value FROM counters WHERE name='counter1'");
list ($value) = mysql_fetch_row($res);
// do something else first... increase value or something...
$res = mysql_query("UPDATE counter SET value=$value WHERE name='counter1'");
mysql_query("SELECT RELEASE_LOCK('lock1')");
Ingat, locking dapat berakibat samping yaitu
deadlock.
Transaksi. Transaksi pun sesuatu yang
dipergunakan secara meluas di dunia database, tapi hampir tidak pernah kita
jumpai di bahasa pemrograman (ini karena data di bahasa pemrograman ditaruh
dalam variabel di memori semua; tidak ada isu disk yang crash/lambat/rusak/harus
disinkronkan dengan data di memori). Karena itu Anda perlu memahami konsep ini
dari buku-buku tentang database.
Di MySQL dikenal istilah table handler dan
jenis tabel. Saat ini ada 3 jenis tabel utama yang bisa dipakai di MySQL:
MyISAM (default), BerkeleyDB, dan InnoDB. Yang perlu diketahui ada tiga hal: 1)
tidak semua tabel mendukung transaksi (MyISAM tidak mendukung transaksi, jadi
COMMIT dan ROLLBACK tidak melakukan sesuatu yang semestinya jika Anda
menerapkan pada tabel MyISAM); 2) tidak semua tabel punya karakteristik
performance yang sama (BerkeleyDB misalnya, lambat jika ukuran tabel besar) dan
disimpan dengan cara yang sama (tabel MyISAM misalnya disimpan dalam 3 file:
.MYI, .MYD, .frm sementara tabel-tabel dan database-database InnoDB disimpan
bersama dalam daerah disk yang disebut tablespace; 3) distribusi MySQL yang
bukan -Max tidak dikompile dengan dukungan terhadap BerkeleyDB dan InnoDB.
Nomor 3 penting Anda ketahui karena jika kita
menginstruksikan MySQL untuk membuat database dengan jenis tertentu:
CREATE
TABLE (...) TYPE=BDB;
Dan MySQL tidak dikompile untuk mendukung
BerkeleyDB, maka MySQL tidak akan protes dengan error,
melainkan membuatkan tabel tersebut untuk kita tapi dengan tipe default yaitu
MyISAM. Jadi Anda perlu mengecek dulu menggunakan SHOW TABLE STATUS:
mysql>
create table t4 (i int) type=innodb;
Query OK, 0 rows affected (0.00 sec)
mysql> show table status from mydb like 't4';
+------+--------+-...
| Name | Type | ...
+------+--------+-...
| t4 | MyISAM | ...
+------+--------+-...
Query OK, 0 rows affected (0.00 sec)
mysql> show table status from mydb like 't4';
+------+--------+-...
| Name | Type | ...
+------+--------+-...
| t4 | MyISAM | ...
+------+--------+-...
Ternyata MyISAM!
Penutup
Sebetulnya untuk memakai MySQL dengan baik
dan benar diperlukan skill-skill dasar lain seperti membackup, merestore,
mengeset parameter-parameter server, memonitor server, dsb. Tapi itu semua
lebih merupakan tugas seorang administrator (DBA).
Tidak ada komentar:
Posting Komentar