Nama | NIM |
---|---|
Dhafin Fawwaz Ikramullah | 13522084 |
DBMS yang dibuat merupakan data dari game Super Mario Bros yang data-datanya merupakan hasil web scrapping. Topik ini dipilih karena akan cocok untuk dijadikan sebuah sistem basis data relasional dengan adanya hal-hal seperti character yang memiliki beberapa tipe, level yang berisikan item-item dengan jumlah tertentu, hubungan antara power up, playable character, dan form power up, dan sebagainya. Dengan adanya DBMS ini kita dapat dengan mudah memperoleh sebuah insight untuk game ini.
Pastikan untuk membuka folder DataScraping/src
di terminal.
Buat file .env
di dalam folder Data Scraping/src dengan isi dapat mengikuti examplenya pada file Data Scraping/src/.env.example.docker atau Data Scraping/src/.env.example.localhost. Atau langsung saja rename yang Data Scraping/src/.env.example.localhost menjadi Data Scraping/src/.env
.
Jika ingin menggunakan docker, jalankan ini
docker-compose up
Program akan secara otomatis melakukan web scraping dan menyimpannya di Data Scraping/src/json/data.json serta memasukkan data-data ke basis data.
Jika hanya ingin menghidupkan database, jalankan ini
docker-compose up database
Jika hanya ingin menjalankan web scraping, jalankan ini
docker-compose up scrape
Jika ingin query sql ke database, buka terminal baru dan jalankan ini
docker exec -it <CONTAINER_NAME> psql -U <DB_USERNAME> <DB_NAME>
<QUERY_SQL>;
Misalnya
docker exec -it mariodb psql -U user mariodb
SELECT * FROM image;
Jika ingin mengecek kapan terakhir kali data diupdate, bisa dengan query berikut
SELECT pg_xact_commit_timestamp(xmin) FROM <TABLE_NAME> LIMIT 1;
Misalnya
SELECT pg_xact_commit_timestamp(xmin) FROM obstacle LIMIT 1;
jalankan command berikut untuk melakukan dump database
docker exec -it mariodb pg_dump mariodb > dump/dump.sql
Hasil dump ada di Data Scraping/src/dump/dump.sql
jalankan command berikut untuk melakukan restore database
docker exec -i mariodb psql -U user -d mariodb < dump/dump.sql
Jika tidak menggunakan docker, anda bisa mengikuti ini. Pastikan Python dan PostgreSQL terinstall. Jalankan
python main.py
Dan akan otomatis web scraping dan memasukkan data ke basis data.
Jika hanya ingin web scraping saja maka jalankan
python scrape.py
Jika hanya ingin memasukkan ke database saja maka jalankan
python db.py
Contoh jika ingin menjalankan sebuah sql query dari code adalah sebagai berikut.
python db.py "SELECT * FROM item"
Pastikan node.js sudah diinstall. Pastikan database menyala. Buka folder Data Visualization/src di terminal. Copy paste file .env
yang ada di saata Data Scraping ke folder tersebut. Jalankan
npm install
npm run dev
Buka browser sesuai dengan url yang diberikan di terminal. Misalnya http://localhost:3000/
.
{
"character": {
// array of playable characters, keunikannya punya relasi dengan form (misal mario menjadi fiery mario)
"pc": {
"name": string,
"description": string,
"image": {
"name": string,
"url": string,
"width": number,
"height": number
},
"detail_url": string
}[],
// array of non playable characters
"npc": {
"name": string,
"description": string,
"image": {
"name": string,
"url": string,
"width": number,
"height": number
},
"detail_url": string,
}[],
// array of enemies, keunikannya punya points
"enemy": {
"name": string,
"description": string,
"image": {
"name": string,
"url": string,
"width": number,
"height": number
},
"detail_url": string,
"points": number,
}[]
},
// array of obstacles yang ada di game
"obstacle": {
"name": string,
"description": string,
"image": {
"name": string,
"url": string,
"width": number,
"height": number
},
"detail_url": string,
}[],
// array of item yang ada di game
"item": {
"name": string,
"description": string,
"image": {
"name": string,
"url": string,
"width": number,
"height": number
},
"detail_url": string,
}[],
// array of power up yang ada di game, dapat membuat playable character berubah form
"power_up": {
// ada yang N/A karena state saat playable character sedang tidak menggunakan power up
"name": null || string,
"description": string,
// ada yang N/A karena state saat playable character sedang tidak menggunakan power up
"image": null || {
"name": string,
"url": string,
"width": number,
"height": number
},
// ada yang N/A karena state saat playable character sedang tidak menggunakan power up
"detail_url": null || string,
// khusus untuk playable character bernama 'mario'
"mario_form": {
"name": string,
"image": {
"name": string,
"url": string,
"width": number,
"height": number
},
"detail_url": string
},
// khusus untuk playable character bernama 'luigi'
"luigi_form": {
"name": string,
"image": {
"name": string,
"url": string,
"width": number,
"height": number
},
"detail_url": string
},
}[],
// array of object yang ada di game. tiap object memiliki typenya masing-masing, namun tidak ada keunikan dari tiap type, hanya sebagai penamaan saja. Lalu tiap 4 level memiliki image yang sama.
"object": {
"name": string,
"description": string,
"image": Image,
"detail_url": string,
"type": string
}[],
// array of reference yang ada pada game
"reference": {
"name": string,
"description": string,
"detail_url": string,
"type": string
}[],
// array of version yang ada pada game
"version": {
"year": string,
"description": string,
}[],
// array of level yang ada pada game. Tiap level memiliki item, power_up, enemies, dan obstacle dengan jumlah tertentu. Namun website sering tidak konsisten. Misal dalam item ada power_up. Kadang enemies dicampur dengan obstacle.
"level": {
"name": string,
"image": {
"name": string,
"url": string,
"width": number,
"height": number
},
"detail_url": string,
"setting": string,
// Saat scraping juga memiliki id html yang tidak konsisten. Bisa beda-beda antara Level_map, Level_maps, Course_map, Map
"course_map_image": {
"name": string,
"url": string,
"width": number,
"height": number
},
// Website sering tidak konsisten. Di dalam ini bisa ada power_up
"item": {
"name": string;
"count": number;
"detail_url": string;
"description": string;
}[],
// Website sering tidak konsisten. Kadang enemies, kadang campuran enemies dan obstacle, kadang tidak ada sama sekali
"enemies": null || {
"name": string,
"count": number,
"detail_url": string
}[],
"enemies_and_obstacle": null || {
"name": string,
"count": number,
"detail_url": string
}[],
}[]
}
Proses translasi ERD menjadi diagram relasional dilakukan dengan cara mengubah setiap entitas dan relasi yang ada pada ERD menjadi tabel-tabel pada database. Setiap atribut cpada entitas akan menjadi kolom pada tabel. Setiap relasi akan menjadi foreign key pada tabel yang berelasi. Entity character memiliki relasi ISA dengan cardinality one to one dengan entity pc, npc, dan enemy. Ini diubah menjadi tabel character, pc, npc, dan enemy. Setiap tabel turunannya memiliki id primary key yang sekalian foreign key yang sama dengan character. Untuk entity pc memiliki hubungan many to many dengan entity power_up dan memiliki relasi form yang memiliki atribut relasi yang atribut relasi itu juga berelasi dengan image. Setelah ditransformasi maka menjadi tabel pc, form, dan power_up yang dihubungkan melalui primary key dan foreign key. Untuk tabel form terdapat atribut tambahan sesuai dengan relasi form. Terdapat sebuah entity level yang berelasi dengan entity item, object, enemy, dan power_up dengan cardinality one to many. Maka level akan menjadi tabel, yang akan dihubungkan ke tabel item, object, enemy, dan power_up melalui tabel level_item, level_object, level_enemy, dan level_power_up dengan primary key dan foreign keynya dan memiliki tambahan atribut count. Reference dan version tidak memiliki relasi dengan entity lain sehingga langsung diubah menjadi tabel. Kemudian untuk masing-masing entity yang memiliki relasi dengan image akan memiliki atribut image_id untuk dihubungkan ke tabel image. Untuk setting level yang berelasi dengan entity level akan diubah menjadi tabel setting_level yang berelasi dengan level yang dihubungkan melalui primary key dan foreign key.
Proses web scraping dapat diupdate dalam jangka waktu tertentu. Dalam program ini, proses web scraping akan dijalankan setiap 2 menit. Konfigurasi ini bisa diubah dari main.py pada variabel wait_time. Nilainya dalam detik. File json hasil scraping akan disimpan di Data Scraping/src/json/data.json.
Total item, power up, obstacle, dan enemy yang ada di tiap level.
Contoh login dan query SELECT ke tabel obstacle.
Contoh mengambil timestamp untuk mengetahui kapan terakhir kali obstacle diupdate.
Yang bawah merupakan setelah ditunggu sekitar 2 menit.
- Bahasa Pemrograman: Python
- Library:
- asyncio: web request secara konkuren sekalian untuk scheduling
- BeautifulSoup: scrapping html website
- psycopg2: driver database
- DBMS: PostgreSQL
- URL Website yang discrape:
- https://www.mariowiki.com/Super_Mario_Bros
- https://www.mariowiki.com/World_1-1_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_1-2_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_1-3_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_1-4_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_2-1_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_2-2_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_2-3_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_2-4_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_3-1_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_3-2_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_3-3_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_3-4_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_4-1_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_4-2_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_4-3_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_4-4_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_5-1_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_5-2_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_5-3_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_5-4_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_6-1_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_6-2_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_6-3_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_6-4_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_7-1_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_7-2_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_7-3_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_7-4_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_8-1_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_8-2_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_8-3_(Super_Mario_Bros.)
- https://www.mariowiki.com/World_8-4_(Super_Mario_Bros.)