Basis data perlu berjalan secara optimal, tetapi itu bukan tugas yang mudah. Basis data SKEMA INFORMASI dapat menjadi senjata rahasia Anda dalam perang pengoptimalan basis data.
Kami terbiasa membuat database menggunakan antarmuka grafis atau serangkaian perintah SQL. Tidak apa-apa, tetapi juga bagus untuk memahami sedikit tentang apa yang terjadi di latar belakang. Ini penting untuk pembuatan, pemeliharaan, dan pengoptimalan database, dan juga merupakan cara yang baik untuk melacak perubahan yang terjadi 'di balik layar'.
Pada artikel ini, kita akan melihat beberapa kueri SQL yang dapat membantu Anda mengintip cara kerja database MySQL.
Basis Data INFORMATION_SCHEMA
Kita telah membahas INFORMATION_SCHEMA
basis data dalam artikel ini. Jika Anda belum membacanya, saya pasti akan menyarankan Anda melakukannya sebelum melanjutkan.
Jika Anda membutuhkan penyegaran pada INFORMATION_SCHEMA
database – atau jika Anda memutuskan untuk tidak membaca artikel pertama – berikut adalah beberapa fakta dasar yang perlu Anda ketahui:
INFORMATION_SCHEMA
database adalah bagian dari standar ANSI. Kami akan bekerja dengan MySQL, tetapi RDBMS lain memiliki variannya. Anda dapat menemukan versi untuk Database H2, HSQLDB, MariaDB, Microsoft SQL Server, dan PostgreSQL.- Ini adalah database yang melacak semua database lain di server; kami akan menemukan deskripsi semua objek di sini.
- Seperti basis data lainnya,
INFORMATION_SCHEMA
database berisi sejumlah tabel terkait dan informasi tentang objek yang berbeda. - Anda dapat membuat kueri database ini menggunakan SQL dan menggunakan hasilnya untuk:
- Pantau status dan kinerja basis data, dan
- Buat kode secara otomatis berdasarkan hasil kueri.
Sekarang mari kita beralih ke query database INFORMATION_SCHEMA. Kita akan mulai dengan melihat model data yang akan kita gunakan.
Model Data
Model yang akan kita gunakan dalam artikel ini ditunjukkan di bawah ini.
Ini adalah model yang disederhanakan yang memungkinkan kita untuk menyimpan informasi tentang kelas, instruktur, siswa, dan detail terkait lainnya. Mari kita membahas tabel secara singkat.
Kami akan menyimpan daftar instruktur di lecturer
meja. Untuk setiap dosen, kami akan mencatat first_name
dan last_name
.
class
tabel mencantumkan semua kelas yang kami miliki di sekolah kami. Untuk setiap record dalam tabel ini, kita akan menyimpan class_name
, ID dosen, start_date
yang direncanakan dan end_date
, dan class_details
tambahan apa pun . Demi kesederhanaan, saya akan berasumsi bahwa kita hanya memiliki satu dosen per kelas.
Kelas biasanya diselenggarakan sebagai rangkaian kuliah. Mereka umumnya membutuhkan satu atau lebih ujian. Kami akan menyimpan daftar kuliah dan ujian terkait di lecture
dan exam
tabel. Keduanya akan memiliki ID kelas terkait dan start_time
yang diharapkan dan end_time
.
Sekarang kami membutuhkan siswa untuk kelas kami. Daftar semua siswa disimpan di student
meja. Sekali lagi, kami hanya akan menyimpan first_name
dan last_name
setiap siswa.
Hal terakhir yang perlu kita lakukan adalah melacak aktivitas siswa. Kami akan menyimpan daftar setiap kelas tempat siswa terdaftar, catatan kehadiran siswa, dan hasil ujian mereka. Masing-masing dari tiga tabel yang tersisa – on_class
, on_lecture
dan on_exam
– akan memiliki referensi ke siswa dan referensi ke tabel yang sesuai. Hanya on_exam
tabel akan memiliki nilai tambahan:nilai.
Ya, model ini sangat sederhana. Kita bisa menambahkan banyak detail lain tentang mahasiswa, dosen, dan kelas. Kami dapat menyimpan nilai historis ketika catatan diperbarui atau dihapus. Namun, model ini akan cukup untuk tujuan artikel ini.
Membuat Basis Data
Kami siap membuat database di server lokal kami dan memeriksa apa yang terjadi di dalamnya. Kami akan mengekspor model (di Vertabelo) menggunakan “Generate SQL script
" tombol.
Kemudian kita akan membuat database pada instance MySQL Server. Saya memanggil database saya “classes_and_students
”.
Hal berikutnya yang perlu kita lakukan adalah menjalankan skrip SQL yang telah dibuat sebelumnya.
Sekarang kita memiliki database dengan semua objeknya (tabel, kunci utama dan kunci asing, kunci alternatif).
Ukuran Basis Data
Setelah script berjalan, data tentang “classes and students
” database disimpan di INFORMATION_SCHEMA
basis data. Data ini ada di banyak tabel yang berbeda. Saya tidak akan mencantumkan semuanya lagi di sini; kami melakukannya di artikel sebelumnya.
Mari kita lihat bagaimana kita dapat menggunakan SQL standar pada database ini. Saya akan mulai dengan satu pertanyaan yang sangat penting:
SET @table_schema = "classes_and_students"; SELECT ROUND(SUM( INFORMATION_SCHEMA.TABLES.DATA_LENGTH + INFORMATION_SCHEMA.TABLES.INDEX_LENGTH ) / 1024 / 1024, 2) AS "DB Size (in MB)", ROUND(SUM( INFORMATION_SCHEMA.TABLES.DATA_FREE )/ 1024 / 1024, 2) AS "Free Space (in MB)" FROM INFORMATION_SCHEMA.TABLES WHERE INFORMATION_SCHEMA.TABLES.TABLE_SCHEMA = @table_schema;
Kami hanya menanyakan INFORMATION_SCHEMA.TABLES
meja di sini. Tabel ini seharusnya memberi kita lebih dari cukup detail tentang semua tabel di server. Harap perhatikan bahwa saya hanya memfilter tabel dari "classes_and_students
" database menggunakan SET
variabel di baris pertama dan kemudian menggunakan nilai ini dalam kueri. Sebagian besar tabel berisi kolom TABLE_NAME
dan TABLE_SCHEMA
, yang menunjukkan tabel dan skema/database milik data ini.
Kueri ini akan mengembalikan ukuran database kami saat ini dan ruang kosong yang disediakan untuk database kami. Inilah hasil sebenarnya:
Seperti yang diharapkan, ukuran database kosong kami kurang dari 1 MB, dan ruang kosong yang dipesan jauh lebih besar.
Ukuran dan Properti Tabel
Hal menarik berikutnya yang harus dilakukan adalah melihat ukuran tabel di database kita. Untuk melakukannya, kami akan menggunakan kueri berikut:
SET @table_schema = "classes_and_students"; SELECT INFORMATION_SCHEMA.TABLES.TABLE_NAME, ROUND(SUM( INFORMATION_SCHEMA.TABLES.DATA_LENGTH + INFORMATION_SCHEMA.TABLES.INDEX_LENGTH ) / 1024 / 1024, 2) "Table Size (in MB)", ROUND(SUM( INFORMATION_SCHEMA.TABLES.DATA_FREE )/ 1024 / 1024, 2) AS "Free Space (in MB)", MAX( INFORMATION_SCHEMA.TABLES.TABLE_ROWS) AS table_rows_number, MAX( INFORMATION_SCHEMA.TABLES.AUTO_INCREMENT) AS auto_increment_value FROM INFORMATION_SCHEMA.TABLES WHERE INFORMATION_SCHEMA.TABLES.TABLE_SCHEMA = @table_schema GROUP BY INFORMATION_SCHEMA.TABLES.TABLE_NAME ORDER BY 2 DESC;
Kueri hampir identik dengan kueri sebelumnya, dengan satu pengecualian:hasilnya dikelompokkan pada tingkat tabel.
Berikut adalah gambar hasil yang dikembalikan oleh kueri ini:
Pertama, kita dapat melihat bahwa kedelapan tabel memiliki “Ukuran Tabel” minimal minimal dicadangkan untuk definisi tabel, yang mencakup kolom, kunci utama, dan indeks. “Ruang Kosong” didistribusikan secara merata di antara semua tabel.
Kita juga dapat melihat jumlah baris saat ini di setiap tabel dan nilai saat ini dari auto_increment properti untuk setiap tabel. Karena semua tabel benar-benar kosong, kami tidak memiliki data dan auto_increment diatur ke 1 (nilai yang akan ditetapkan ke baris yang disisipkan berikutnya).
Kunci Utama
Setiap tabel harus memiliki nilai kunci utama yang ditentukan, jadi sebaiknya periksa apakah ini benar untuk database kita. Salah satu cara untuk melakukannya adalah dengan menggabungkan daftar semua tabel dengan daftar batasan. Ini akan memberi kami info yang kami butuhkan.
SET @table_schema = "classes_and_students"; SELECT tab.TABLE_NAME, COUNT(*) AS PRI_number FROM INFORMATION_SCHEMA.TABLES tab LEFT JOIN ( SELECT INFORMATION_SCHEMA.COLUMNS.TABLE_SCHEMA, INFORMATION_SCHEMA.COLUMNS.TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE INFORMATION_SCHEMA.COLUMNS.TABLE_SCHEMA = @table_schema AND INFORMATION_SCHEMA.COLUMNS.COLUMN_KEY = 'PRI' ) col ON tab.TABLE_SCHEMA = col.TABLE_SCHEMA AND tab.TABLE_NAME = col.TABLE_NAME WHERE tab.TABLE_SCHEMA = @table_schema GROUP BY tab.TABLE_NAME;
Kami juga menggunakan INFORMATION_SCHEMA.COLUMNS
tabel dalam kueri ini. Sementara bagian pertama dari kueri hanya akan mengembalikan semua tabel dalam database, bagian kedua (setelah LEFT JOIN
) akan menghitung jumlah PRI dalam tabel ini. Kami menggunakan LEFT JOIN
karena kita ingin melihat apakah sebuah tabel memiliki 0 PRI di COLUMNS
tabel.
Seperti yang diharapkan, setiap tabel dalam database kami berisi tepat satu kolom kunci utama (PRI).
“Pulau”?
"Kepulauan" adalah tabel yang benar-benar terpisah dari model lainnya. Itu terjadi ketika tabel tidak berisi kunci asing dan tidak direferensikan di tabel lain mana pun. Ini seharusnya tidak terjadi kecuali ada alasan yang sangat bagus, mis. ketika tabel berisi parameter atau menyimpan hasil atau laporan di dalam model.
SET @table_schema = "classes_and_students"; SELECT tab.TABLE_NAME, (CASE WHEN f1.number_referenced IS NULL THEN 0 ELSE f1.number_referenced END) AS number_referenced, (CASE WHEN f2.number_referencing IS NULL THEN 0 ELSE f2.number_referencing END) AS number_referencing FROM INFORMATION_SCHEMA.TABLES tab LEFT JOIN -- # table was used as a reference ( SELECT INFORMATION_SCHEMA.KEY_COLUMN_USAGE.REFERENCED_TABLE_SCHEMA, INFORMATION_SCHEMA.KEY_COLUMN_USAGE.REFERENCED_TABLE_NAME, COUNT(*) AS number_referenced FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE INFORMATION_SCHEMA.KEY_COLUMN_USAGE.REFERENCED_TABLE_SCHEMA = @table_schema GROUP BY INFORMATION_SCHEMA.KEY_COLUMN_USAGE.REFERENCED_TABLE_SCHEMA, INFORMATION_SCHEMA.KEY_COLUMN_USAGE.REFERENCED_TABLE_NAME ) f1 ON tab.TABLE_SCHEMA = f1.REFERENCED_TABLE_SCHEMA AND tab.TABLE_NAME = f1.REFERENCED_TABLE_NAME LEFT JOIN -- # of references in the table ( SELECT INFORMATION_SCHEMA.KEY_COLUMN_USAGE.TABLE_SCHEMA, INFORMATION_SCHEMA.KEY_COLUMN_USAGE.TABLE_NAME, COUNT(*) AS number_referencing FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE INFORMATION_SCHEMA.KEY_COLUMN_USAGE.REFERENCED_TABLE_SCHEMA = @table_schema AND INFORMATION_SCHEMA.KEY_COLUMN_USAGE.REFERENCED_TABLE_NAME IS NOT NULL GROUP BY INFORMATION_SCHEMA.KEY_COLUMN_USAGE.TABLE_SCHEMA, INFORMATION_SCHEMA.KEY_COLUMN_USAGE.TABLE_NAME ) f2 ON tab.TABLE_SCHEMA = f2.TABLE_SCHEMA AND tab.TABLE_NAME = f2.TABLE_NAME WHERE tab.TABLE_SCHEMA = @table_schema;
Apa ide di balik kueri ini? Nah, kami menggunakan INFORMATION_SCHEMA.KEY_COLUMN_USAGE
tabel untuk menguji apakah ada kolom dalam tabel yang menjadi referensi ke tabel lain atau jika ada kolom yang digunakan sebagai referensi di tabel lain. Bagian pertama kueri memilih semua tabel. Setelah LEFT JOIN pertama, kami menghitung berapa kali kolom apa pun dari tabel ini digunakan sebagai referensi. Setelah LEFT JOIN kedua, kami menghitung berapa kali kolom mana pun dari tabel ini mereferensikan tabel lain.
Hasil yang dikembalikan adalah:
Di baris untuk class
tabel, angka 3 dan 1 menunjukkan bahwa tabel ini dirujuk tiga kali (dalam lecture
, exam
, dan on_class
tabel) dan berisi satu atribut yang mereferensikan tabel lain (lecturer_id
). Tabel lainnya mengikuti pola yang sama, meskipun angka sebenarnya tentu saja akan berbeda. Aturannya di sini adalah bahwa tidak ada baris yang harus memiliki 0 di kedua kolom.
Menambahkan Baris
Sejauh ini, semuanya berjalan seperti yang diharapkan. Kami telah berhasil mengimpor model data kami dari Vertabelo ke Server MySQL lokal. Semua tabel berisi kunci, seperti yang kita inginkan, dan semua tabel terkait satu sama lain – tidak ada “pulau” dalam model kita.
Sekarang, kami akan menyisipkan beberapa baris di tabel kami dan menggunakan kueri yang ditunjukkan sebelumnya untuk melacak perubahan dalam database kami.
Setelah menambahkan 1.000 baris di tabel dosen, kita akan menjalankan lagi query dari “Table Sizes and Properties
" bagian. Ini akan mengembalikan hasil berikut:
Kita dapat dengan mudah melihat bahwa jumlah baris dan nilai auto_increment telah berubah seperti yang diharapkan, tetapi tidak ada perubahan signifikan dalam ukuran tabel.
Ini hanya contoh tes; dalam situasi kehidupan nyata, kita akan melihat perubahan yang signifikan. Jumlah baris akan berubah drastis dalam tabel yang diisi oleh pengguna atau proses otomatis (yaitu tabel yang bukan kamus). Memeriksa ukuran dan nilai dalam tabel tersebut adalah cara yang sangat baik untuk menemukan dan memperbaiki perilaku yang tidak diinginkan dengan cepat.
Mau Berbagi?
Bekerja dengan database adalah upaya konstan untuk kinerja yang optimal. Agar lebih berhasil dalam pengejaran itu, Anda harus menggunakan alat apa pun yang tersedia. Hari ini kami telah melihat beberapa kueri yang berguna dalam perjuangan kami untuk kinerja yang lebih baik. Apakah Anda menemukan hal lain yang berguna? Sudahkah Anda bermain dengan INFORMATION_SCHEMA
basis data sebelumnya? Bagikan pengalaman Anda di komentar di bawah.