เจาะลึก JSON Storage เปลี่ยน Google Sheets ให้เป็นฐานข้อมูลสุดยืดหยุ่น
1. ปัญหาของการเก็บข้อมูลแบบแยกคอลัมน์ (Traditional Columns)
2. JSON Storage คืออะไร? และทำไมถึงเป็นคำตอบ?
ในบทความที่แล้ว เราได้เรียนรู้วิธีการทำ Data Routing เพื่อส่งข้อมูลไปจัดการในรูปแบบ CRUD (บันทึก-ดึง-แก้ไข-ลบ) พื้นฐานบน Google Sheets กันไปแล้ว ซึ่งวิธีนั้นเหมาะมากสำหรับการจัดการข้อมูลที่มีโครงสร้างนิ่ง ไม่ค่อยเปลี่ยนแปลง
แต่ในโลกความเป็นจริง แอปพลิเคชันหรือเว็บแอปมักจะมีการเติบโตและเปลี่ยนแปลงตลอดเวลา สมมติว่าวันนี้คุณทำระบบเก็บประวัติลูกค้า มีคอลัมน์ [ชื่อ, เบอร์โทร, ที่อยู่] แต่วันพรุ่งนี้คุณอยากเก็บข้อมูล "ความสนใจส่วนตัว" เพิ่ม... คุณจะต้องไปนั่งแทรกคอลัมน์ใหม่ใน Google Sheets แล้วกลับมาแก้โค้ดเพื่อระบุลำดับคอลัมน์ใหม่ทั้งหมดหรือเปล่า?
ถ้าคุณตอบว่า "ใช่" แสดงว่าระบบของคุณกำลังเจอปัญหาเรื่องความยืดหยุ่นครับ วันนี้เราจะพาคุณไปทำความรู้จักกับเทคนิค "JSON Storage" ซึ่งจะเปลี่ยนมุมมองการเก็บข้อมูลใน Google Sheets ไปตลอดกาล!
การเก็บข้อมูลแบบ 1 ข้อมูล = 1 คอลัมน์ (เช่น คอลัมน์ A คือ ID, B คือ ชื่อ, C คือ เบอร์โทร) เป็นวิธีมาตรฐานที่เข้าใจง่าย แต่เมื่อระบบใหญ่ขึ้น มันจะสร้างปัญหา (Technical Debt) ตามมา:
คอลัมน์งอกไม่หยุด (Column Sprawl): หากระบบมีข้อมูลหลายสิบประเภท หน้าชีทของคุณจะมีคอลัมน์ยาวเหยียดจนจัดการยาก
โค้ดเปราะบาง (Fragile Code): หากคุณแทรกคอลัมน์ตรงกลาง ลำดับของคอลัมน์ด้านหลังจะเปลี่ยนไปทั้งหมด หากโค้ดเก่าเขียนไว้ว่า
currentRow[3]เพื่อดึงข้อมูลคอลัมน์ D ข้อมูลที่ได้กลับมาอาจจะผิดพลาดทันทีเก็บข้อมูลซับซ้อนยาก: หากคุณอยากเก็บข้อมูลที่เป็น "รายการ" เช่น "รายการสินค้าที่เคยซื้อ" (Item_1, Item_2, Item_3) การแยกคอลัมน์จะลำบากมาก
คำว่า JSON (JavaScript Object Notation) คือรูปแบบการแลกเปลี่ยนข้อมูลมาตรฐานที่นักพัฒนายุคใหม่นิยมใช้ที่สุด มันสามารถเก็บข้อมูลได้หลายประเภท ทั้งข้อความ (String), ตัวเลข (Number), ค่าความจริง (Boolean), และที่สำคัญคือเก็บข้อมูลที่เป็นรายการ (Array) หรือข้อมูลที่ซ้อนกัน (Nested Object) ได้อย่างสวยงาม
JSON Storage ใน Google Sheets คือเทคนิคที่เรามัดรวมข้อมูลทั้งหมด (เช่น {ID, ชื่อ, เบอร์โทร, วันที่}) ให้กลายเป็นข้อความ JSON ก้อนเดียว แล้วหยอดมันลงไปในเซลล์เดียว (Cell) แทนที่จะแยกคอลัมน์ครับ!
3. เจาะลึกข้อดีมหาศาลของการเก็บข้อมูลแบบ JSON ในช่องเดียว
การทำ JSON Storage ไม่ได้แค่ทำให้หน้าชีทดูสะอาดตาขึ้น แต่ยังมีข้อดีทางเทคนิคที่โปรแกรมเมอร์มือโปรต้องการ:
ยืดหยุ่นขั้นสุด (High Flexibility): วันนี้อยากเก็บข้อมูลเพิ่ม? แค่เพิ่ม Key ลงไปใน JSON Payload ที่ฝั่งหน้าบ้าน (Frontend) ตอนส่งมา ไม่ต้องแก้โครงสร้าง Google Sheets แม้แต่ บรรทัดเดียว!
ประสิทธิภาพสูง (High Performance): ในเชิงการเขียนโปรแกรม การดึงข้อมูล 1 เซลล์ขนาดยักษ์ (ที่เก็บ JSON Payload) เร็วกว่าการสั่งดึงข้อมูลแยกคอลัมน์ 10 คอลัมน์ในแถวเดียวกันมาก เนื่องจาก Google Apps Script มี Overhead ในการเข้าถึงแต่ละเซลล์
โค้ดไล่ง่าย (Maintainable Code): ไม่ต้องมานั่งจำว่า
currentRow[12]คืออะไร เราสามารถเข้าถึงข้อมูลได้ด้วยชื่อ Key เช่นuserData.interest[0]ซึ่งอ่านง่ายกว่ามาก4. ส่องโค้ดตัวอย่าง: การบันทึกและดึงข้อมูลแบบ JSON Storage
เรามาดูโค้ดตัวอย่างในหมวด CRUD - Create และ CRUD - Read ที่ถูกอัปเกรดมาใช้เทคนิค JSON Storage กันครับ โดยเราจะใช้โครงสร้าง Data Routing จากบทความที่แล้วเพื่อความต่อเนื่อง
/** * หมวดหมู่: DATA ROUTING (โครงสร้างต่อเนื่องจากบทความตอนที่ 2) */ function routeDataAction(request) { var action = request.action; var payload = request.data; switch(action) { case "create_user_json": return createUserJSON(payload); // ส่งต่อไปฟังก์ชันบันทึกแบบ JSON case "get_user_json_by_id": return readUserJSONById(payload.userId); // ส่งต่อไปฟังก์ชันดึงข้อมูลแบบ JSON default: return { status: "error", message: "ไม่พบคำสั่งที่ระบุในระบบ" }; } } /** * หมวดหมู่: CRUD - CREATE (อัปเกรดเป็น JSON) * ฟังก์ชัน: createUserJSON * วัตถุประสงค์: บันทึกข้อมูลผู้ใช้งานทั้งหมดลงในช่องเดียว (JSON Payload) */ function createUserJSON(data) { try { var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); var sheet = spreadsheet.getSheetByName("User_JSON_Database"); // ตรวจสอบความปลอดภัยตามสูตรเดิม if (!sheet) return { status: "error", message: "ไม่พบหน้าชีทระบบ" }; // 1. เตรียมข้อมูลพื้นฐานที่ต้องแยกคอลัมน์ (เช่น ID เพื่อใช้ค้นหา) var userId = "UID-" + new Date().getTime(); var userName = data.fullName; // 2. มัดรวมข้อมูลที่เหลือทั้งหมดเป็นวัตถุ (Object) var jsonPayload = { phoneNumber: data.phoneNumber, email: data.email, interest: data.interest || [], // เก็บ Array ได้สบาย config: data.config || {}, // เก็บ Object ซ้อนได้ registered_at: new Date() }; // 3. หัวใจสำคัญ: แปลง Object ให้เป็นข้อความสตริง (String) // ผลลัพธ์: '{"phoneNumber":"08123x...","registered_at":"..."}' var jsonString = JSON.stringify(jsonPayload); // 4. บันทึกข้อมูลลงชีท [ID, ชื่อ, JSON Payloadขนาดยักษ์] var newRow = [ userId, userName, jsonString // ข้อมูลจบในช่องที่ 3 ช่องเดียว ]; sheet.appendRow(newRow); return { status: "success", message: "บันทึกข้อมูลผู้ใช้งานแบบยืดหยุ่นเรียบร้อยแล้ว!", userId: userId }; } catch(error) { return { status: "error", message: "เกิดข้อผิดพลาดในการบันทึก JSON: " + error.toString() }; } } /** * หมวดหมู่: CRUD - READ (อัปเกรดเพื่ออ่าน JSON) * ฟังก์ชัน: readUserJSONById * วัตถุประสงค์: ค้นหาข้อมูลผู้ใช้งานจาก ID และแปลง JSON String กลับเป็น Object */ function readUserJSONById(userIdToFind) { try { var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); var sheet = spreadsheet.getSheetByName("User_JSON_Database"); if (!sheet) return { status: "error", message: "ไม่พบหน้าชีทระบบ" }; // ดึงข้อมูลทั้งหมดในชีทออกมา (ยกเว้นหัวตาราง) var lastRow = sheet.getLastRow(); if (lastRow <= 1) return { status: "empty", message: "ยังไม่มีข้อมูลในระบบ" }; // ดึงคอลัมน์เฉพาะที่จำเป็น (A: ID, C: JSON Payload) เพื่อความเร็ว var dataRange = sheet.getRange(2, 1, lastRow - 1, 3); var allRows = dataRange.getValues(); // วนลูปค้นหาด้วย ID (คอลัมน์ที่ 1 หรือ Index 0) for (var i = 0; i < allRows.length; i++) { var currentRow = allRows[i]; var userId = currentRow[0].toString().trim(); if (userId === userIdToFind.toString().trim()) { // 1. เจอข้อมูลแล้ว! ดึง JSON String มาจากคอลัมน์ที่ 3 (Index 2) var jsonString = currentRow[2]; // 2. หัวใจสำคัญ: แปลงข้อความ JSON กลับเป็น JavaScript Object var userData = JSON.parse(jsonString); // 3. เตรียมข้อมูลส่งกลับหน้าบ้าน (Frontend) โดยรวมข้อมูลที่แยกคอลัมน์ไว้ด้วย var finalResponse = { userId: userId, fullName: currentRow[1], extraData: userData // ส่ง JSON Object กลับไปเลย }; return { status: "found", data: finalResponse }; } } return { status: "not_found", message: "ไม่พบข้อมูลผู้ใช้งานที่ระบุ" }; } catch(error) { return { status: "error", message: "เกิดข้อผิดพลาดในการค้นหา JSON: " + error.toString() }; } }
6. ข้อดีของโค้ดแนวโมดูลที่เน้นยืดหยุ่น
การฝึกเขียนโค้ดแยกหน้าที่ชัดเจน โดยแยกโมดูล
Data Routing,CRUD, และJSON Storageออกจากกัน มีประโยชน์มากครับ:
ซ่อมง่าย: เวลาที่ระบบบันทึก JSON ไม่ได้ คุณก็แค่มาไล่โค้ดที่ฟังก์ชัน
createUserJSONเท่านั้น ไม่ต้องไปยุ่งกับระบบค้นหาเลยขยายง่าย: วันหน้าอยากเพิ่มฟังก์ชัน
Updateแบบ JSON คุณก็แค่สร้างโมดูลupdateUserJSONแล้วเอามาผูกกับrouteDataActionก็เสร็จแล้วครับสรุป
JSON Storage คือเทคนิค "หักดิบ" การเก็บข้อมูลแบบเดิมๆ บน Google Sheets ที่มอบ ความยืดหยุ่นมหาศาล ให้กับนักพัฒนาซอฟต์แวร์
การเข้าใจวงจรชีวิตของข้อมูลตั้งแต่ตอนที่มันถูกมัดก้อนด้วย
JSON.stringify()จนกระทั่งตอนที่มันถูกดึงออกมาแกะก้อนด้วยJSON.parse()คือกุญแจสำคัญที่จะช่วยให้คุณสร้างเว็บแอปพลิเคชันหรือระบบอัตโนมัติที่เติบโตได้อย่างไร้ขีดจำกัด บนฐานข้อมูลที่เราคุ้นเคยอย่าง Google Sheets ครับ!
