สร้างฐานข้อมูล SQLite อย่างไรให้ไว?

ก่อนอื่นเลย คงจะรู้อยู่แล้วว่าบนแอนดรอยด์มี SQLite ให้ใช้ โดยที่ปกติมักจะสร้างฐานข้อมูลตอนที่เปิดแอพพลิเคชันเป็นครั้งแรกและในครั้งต่อไปก็ไม่ต้องสร้างแล้ว เปิดจากฐานข้อมูลมาใช้ต่อเลย

ถ้าข้อมูลมีนิดหน่อยก็คงไม่เจอปัญหาอะไรซักเท่าไร (พันกว่าตัว) แต่ถ้าข้อมูลมีขนาดเยอะมาก การสร้างฐานข้อมูลจะใช้เวลานานมาก อย่างเช่นแอพคำศัพท์สำหรับ Dictionary ของ Lexitron ที่มีคำศัพท์ประมาณ 8 หมื่นคำ มีคอลัมน์ 8 คอลัมน์ ข้อมูลโดยรวมแล้วตกประมาณ 10MB กว่าๆเลยทีเดียว พวกนี้จะใช้เวลาเป็นสิบนาทีเลยทีเดียว

ทีนี้ลองนึกถึงผู้ใช้ที่โหลดแอพไปใช้ แล้วพบว่าเปิดแอพครั้งแรกต้องมานั่งรอสร้างฐานข้อมูลสิบกว่านาที ใครจะไปนั่งรอใช้กันล่ะ? ถ้าเป็นแอพเกมสนุกๆก็ว่าไปอย่าง ดังนั้นเจ้าของบล็อกจึงเขียนบทความนี้ขึ้นมาเพื่อพูดถึง “วิธีลัด” ในการสร้างฐานข้อมูลขนาดใหญ่ ให้ใช้เวลาน้อย

สำหรับไฟล์ฐานข้อมูลจะสร้างจากไหนก็ได้ขอแค่ว่าเป็น SQLite หรือจะสร้างจาก SQLite Databases Browser ก้ได้

เมื่อได้ไฟล์ฐานข้อมูลมาแล้วก็เอาไปไว้ในโปรเจคได้เลย โดยเอาไว้ใน assets จะดีกว่าเพราะว่าสามารถเรียก Path ได้เลย

เมื่อได้ไฟล์ฐานข้อมูลมาพร้อมแล้ว เวลาเขียนโปรแกรมก็ทำการเช็คก่อน ว่ามีไฟล์ฐานข้อมูลแล้วหรือยัง โดยเช็คว่ามีไฟล์ใน data/data/package_name/databases/database_file หรือไม่ ถ้ายังไม่มีก็ให้ก๊อปไฟล์ฐานข้อมูลที่เตรียมไว้ไปวางแทน แต่ถ้ามีแล้วก็ข้ามไปให้แอพทำงานต่อตามต้องการเลย

สรุปก็คือจะใช้วิธีสร้างไฟล์ฐานข้อมูลเตรียมเอาไว้เลยแล้วจะใช้คำสั่งโยนไฟล์ดังกล่าวไปไว้ในตำแหน่งที่ไฟล์ฐานข้อมูลอยู่ ทีนี้ก็ลองดูตัวอย่างเลยดีกว่า

package app.akexorcist.databasequicksqlite; java.io.File; java.io.FileNotFoundException;import java.io.FileOutputStream; import java.io.IOException; java.io.InputStream; java.io.OutputStream; import java.util.ArrayList; android.os.Bundle; android.app.Activity; android.database.Cursor; android.database.sqlite.SQLiteDatabase; android.view.Window; android.widget.ArrayAdapter; android.widget.ListView;public class  Main Activity { SQLiteDatabase mDb; MyDbHelper mHelper; Cursor mCursor;public void  onCreate(Bundle savedInstanceState) { .onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE ); setContentView(R.layout.); checkDatabase(); ListView listView1 = (ListView)findViewById(R.id.); ArrayList<String> dirArray = ArrayList<String>(); mHelper = mDb = mHelper.getWritableDatabase(); mCursor = mDb.rawQuery("SELECT * FROM " + MyDbHelper.new MyDbHelper(); mCursor.moveToFirst(); (!mCursor.isAfterLast()){ dirArray.add("Name : " + mCursor.getString(mCursor.getColumnIndex(MyDbHelper."\nPiece Price : " + mCursor.getString(mCursor.getColumnIndex(MyDbHelper.TABLE_NAME, ); "\nCake Price" + mCursor.getString(mCursor.getColumnIndex(MyDbHelper.mCursor.moveToNext(); } ArrayAdapter<String> adapterDir = ArrayAdapter<String>(getApplicationContext() , android.R.layout.public void  checkDatabase() { String url = "/data/data/" + getPackageName() + "/databases/BTS"; File f = File(url); (!f.exists()) { {COL_NAME)) + mHelper = MyDbHelper(); mDb = mHelper.getWritableDatabase(); mDb.close(); mHelper.close(); InputStream in = getAssets().open("BTS"); OutputStream out = FileOutputStream(url); [] buffer = [in.available()]; in.read(buffer); out.write(buffer, 0, buffer.length); in.close(); out.close(); } (FileNotFoundException e) { e.printStackTrace(); } (IOException e) { e.printStackTrace(); } } }public void  onPause() { .onPause(); mHelper.close(); mDb.close(); } }COL_PIECE_PRICE)) +COL_CAKE_PRICE)));simple_list_item_1, dirArray); listView1.setAdapter(adapterDir); }


สำหรับคำสั่งใน Main.java ก็จะเหมือนกับคำสั่งสร้างฐานข้อมูลทั่วๆไปที่เอาข้อมูลในฐานข้อมูลมาแสดงบน List View แต่ว่าเจ้าของบล็อกจะมีการสร้างฟังก์ชัน checkDatabase ขึ้นมา ซึ่งเป็นฟังก์ชันตรวจสอบว่าไฟล์ฐานข้อมูลถูกสร้างขึ้นหรือยัง ทีนี้ขอข้ามไปอธิบายฟังก์ชัน checkDatabase เลยนะ สำหรับฟังก์ชันนี้ ก็จะสร้าง String ขึ้นมาเพื่อเก็บที่อยู่ของไฟล์ จะเห็นว่าเจ้าของบล็อกใช้ “/data/data/” + getPackageName() + “/databases/BTS” โดยที่ getPackageName() คือคำสั่งรับชื่อ Package ของแอพนั้นๆให้ทันที เวลาผู้ที่หลงเข้ามาอ่านเอาไปใช้ก็ไม่ต้องแก้ชื่อ Package เลย จากนั้นก็เรียกใช้คลาส File ขึ้นมา โดยใช้ URL จากตัวแปร String เมื่อกี้

ซึ่งก็คือ Object ตัวนี้จะ Path ไปยังไฟล์ที่กำหนดเป็น URL แล้วทำการเช็คด้วย if ว่ามีไฟล์ดังกล่าวอยู่หรือไม่ด้วยคำสั่ง f.exists() โดยใช้ ! ด้วย เพราะว่าจะให้ทำเงื่อนไขเมื่อไม่มีไฟล์นี้อยู่ เมื่อเข้าเงื่อนไขว่ายังไม่มีไฟล์ฐานข้อมูลอยู่ในเครื่อง ก็ให้เรียกใช้คลาสฐานข้อมูลเพื่อสร้างฐานข้อมูลเปล่าๆก่อน แล้วก็ปิดฐานข้อมูลซะ ไม่งั้นจะวางไฟล์ทับไม่ได้เพราะเปิดใช้งานอยู่ จากนั้นก็เรียกใช้คลาสของ InputStream กับ OutputStream เพื่อใช้สำหรับนำไฟล์ฐานข้อมูลที่เตรียมไว้ไปวางทับฐานข้อมูลเปล่า เท่านี้ก็เสร็จเรียบร้อยแล้ว

app.akexorcist.databasequicksqlite; android.content.Context; android.database.sqlite.SQLiteDatabase; android.database.sqlite.SQLiteOpenHelper; MyDbHelper SQLiteOpenHelper { private static final String DB_NAME = "BTS";private static final int  DB_VERSION = 1; public static final  String TABLE_NAME = "Product";public static final  String COL_NAME = "name"; public static final  String COL_PIECE_PRICE = "pieceprice";public static final  String COL_CAKE_PRICE = "cakeprice"; MyDbHelper(Context context) { (context, DB_NAME, , DB_VERSION); }public void onCreate(SQLiteDatabase db) { }public void  onUpgrade(SQLiteDatabase db, oldVersion, newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); } }


สำหรับคลาสนี้ก็ไม่มีอะไร แค่คลาส Database ปกติ โดยรวมของคลาสนี้ก็มีแค่สร้างฐานข้อมูลเปล่าๆ ที่ไม่มีตารางและฐานข้อมูลใดๆเลย เพราะจะนำไฟล์ฐานข้อมูลมาวางทับ

เรียบร้อยแล้ว ลองเอาไปทดสอบดูก็จะพบว่าไวกว่าเดิมเยอะ

ลองเอาวิธีนี้ไปใช้ดูละกันนะ