คือตอนนี้ผมกำลังเขียน RSS Reader ในแบบ Google Reader อยู่ครับ (หาตัวที่ถูกใจไม่ได้ เลยว่าจะเขียนเอง) โดยผมใช้ CodeIgniter เป็นเฟรมเวิร์ก
หลักการทำงานของมันคือเก็บ url ของ feed ทั้งหมดไว้ในตาราง rss_feeds และตั้ง cron ให้ไปดึงข้อมูลมาเป็นระยะๆ โดยเอาข้อมูลที่ไปดึงมาใส่ไว้ในฐานข้อมูลด้วย (เผื่อต้องการอ่านย้อนหลัง และเผื่อไม่ได้อ่านนานๆ feed เก่าตกขอบ) โดยจะเอาไปเก็บไว้ใน rss_feed_items
ในตอนแรกจะทำเป็น single user ก็ไม่มีปัญหาอะไรครับ เพิ่มฟิลด์ is_read เข้าไปอีกอันเพื่อเก็บว่าอ่านแล้วหรือยัง แต่ทีนี้มันมีปัญหาที่ผมทำให้มันเป็นแบบ multi user ครับ โดยจะมีตารางเพิ่มมาอีกอันนึง (rss_feed_subscribe) ใช้เก็บข้อมูลว่า user คนนี้ตาม feed ไหนบ้าง โดยจะไปดึงข้อมูลจาก rss_feed_items มาแสดง (จะได้ไม่ต้องไปโหลด feed ใหม่ตลอด)
ทีนี้ปัญหาก็เกิดขึ้นตรงนี้ครับ โดยผมไม่ทราบว่าจะเก็บสถานะ read/unread ของแต่ละคนยังไงดี ในทีแรกกะว่าจะทำตาราง rss_feed_item_read ขึ้นมาเพื่อเก็บสถานะอ่านแล้วอีกอันนึง แต่คิดว่านานๆ ไปข้อมูลมันจะเยอะและทำงานได้ช้าแน่ๆ (สมมุติแค่มีคนใช้ 20 คน มี item ที่ดูดมา 1000 ไอเทม ก็ต้องใช้ถึง 20000 ระเบียนในการเก็บข้อมูล ผมว่ามันน่าจะเยอะเกินไปโดยใช่เหตุ)
ว่าไป มันเหมือนกับตามเว็บบอร์ดที่เวลาล็อกอินเข้าไปแล้วจะมีบอกว่ากระทู้ไหนยังไม่ได้อ่านนั่นแหละ
ใครพอมีไอเดียมั๊ยครับ ว่าจะทำยังไงดี
ขอบคุณครับ
ผมว่าวิธีนั้นก็ถูกแล้วนะครับ database 20000 item ก็ไม่เยอะนะผมว่า
อาจจะตั้ง service ขึ้นมาตัวนึงคอยกวาดเอาข้อมูลเก่า ๆ ออกไป มาร์คว่าเป็น read ก็ได้ถ้ากังวลว่ามันจะเยอะเกินไปน่ะครับ
ฐานข้อมูลมันก็ออกแบบให้รับข้อมูลอย่างนั้นอยู่แล้วนิ... ตั้ง index ดีๆ ก็ไม่ช้าแล้วล่ะ
ถ้าไม่ได้จะ query เอาเฉพาะที่ read หรือเฉพาะที่ unread ผมว่าเก็บใส่ใน table user เพิ่มไปอีก column ก็ได้นะครับ เป็นฟิลด์ read_items เก็บ id ของ item ที่อ่านแล้ว อาจจะเป็น CSV ก็ได้
ตอนแสดงผลค่อยเอามาเปรียบเทียบ อาจจะช้าหน่อยถ้ามีจำนวนเยอะๆ ซึ่งก็อาจจะตั้ง limit ไว้ว่าเก็บแค่ n item ล่าสุดก็ได้
pittaya.com
แบ่ง Table ออกเป็นสองส่วนครับ ส่วนแรกใช้สำหรับ Front-End อย่างเดียว ไม่มีการ update มันจะเพิ่มความเร็วในการอ่านข้อมูลได้เยอะมาก และเราสามารถที่จะเลือกได้ว่า จะใช้ Table แบบใหน เช่น memcached (เอา Table สำหรับที่อ่านอย่างเดียวไปไว้บน memory)
หรือจะใช้ Database ที่มีความเร็วกว่า MySQL ก็ได้ครับสำหรับในส่วนที่ใช้ Read เช่น MongoDB
ส่วนที่ 2 ก็ใช้สำหรับการ update / insert อย่างเดียว
ถ้าแบ่งออกแบบนี้จะช่วยเรื่องของความเร็วได้เยอะครับ
ตอนนี้ได้ไอเดียใหม่ครับ คือจะมีตารางเก็บว่า อันไหนที่เรากาไว้ว่ายังไม่ได้อ่านแทน
โดยเมื่อเราเข้าเว็บมา ก็จะดึง feed item จาก feed ที่เราติดตามทั้งหมดตั้งแต่ที่เราล็อกอินล่าสุดมาให้ และจัดการโยนมันเข้าไปในตาราง unread พออันไหนอ่านแล้วก็ลบเรคคอร์ดนั้นทิ้งไป เวลาเรากลับมาใหม่ ระบบก็จะดึงจากที่เข้ามาล่าสุด และอันที่อยู่ในตาราง unread
ถ้าผมทำแบบนี้ มันจะเร็วกว่าเก็บสถานะทุกอันมั๊ยครับ อีกอย่างนึงคือตอนลบเรคคอร์ด unread ถ้าเทียบระหว่างลบทิ้งไปเลย กับเปลี่ยนค่าเป็น false แล้วตามลบเองทีหลัง (อาจจะทำ cron ไว้ตามลบ) แบบไหนจะทำงานได้เร็วกว่าครับ?
ขอบคุณครับ
ผมว่าไม่ต่างกันครับ เผลอ ๆ คราวนี้ต้องสร้าง record บ่อยกว่าเดิมด้วยซ้ำ (เพราะต้องสร้างทุกครั้งที่มี entry ใหม่)
ถ้าสร้างเฉพาะตอนอ่านแล้วนี่ยังแค่สร้าง record เฉพาะตอนที่อ่านจบแล้วเท่านั้น
ถ้าบอกว่าตาม webboard ผมเข้าใจว่า มันมอง index จาก reply เที่ยบกับที่ index reply ที่เคย read ครั้งล่าสุดเอานะ ถ้า index reply ไหนมากกว่า index ที่เคย read ก่อนหน้า มันก็จะทำตัวหนาให้ .... ที่คิดว่าเป็นยังงั้นเพราะว่าบางกระทู้ที่ผมยังไม่อ่าน แต่กลับมาอีกทีมันไม่เป็นตัวหนาให้ มีแต่กระทู้ที่มี reply เพิ่มจากครั้งก่อน ถึงจะขึ้นตัวหนา (อ้างอิงจากเวบ overclockzone นะครับ) .... ถ้าตามนี้ก็แต่ละ user มี field เดียวจบเลย =w=! (last_index < current_reply_index) แต่คิดไปคิดมา มันเอาไปใช้กับพวก feed ไม่ได้สินะ
เก็บเฉพาะที่อ่านแล้วดีกว่านะ เพราะถ้าเนื้อหาเยอะๆคงไม่มีใครนั่งอ่านกระทู้ซะทั้งหมดหรอก
สมมุติมี 1000 กระทู้ อ่านกระทู้เดียวก็เก็บตัวเดียว
ทำแบบ 2 ตาราง อันนี้ผมดันครับ
แต่.. อันนึงเป็น real table อันอันเป็น view table โดย ตอน Create View นั้นให้อ้างจาก list ของ user ทั้งหมดที่เข้าชม
ถ้า user ที่เข้าชม เคยเข้าดู topic นั้นๆ แล้วก็ ให้แสดง UI เป็นแบบ Read ครับ สามารถแก้ปัญหา Multi user ได้ด้วยนะครับ
ปล. ผมยังไม่เคยเลยทำนะครับ