-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy path10s-denormalization.md.erb
50 lines (31 loc) · 9.02 KB
/
10s-denormalization.md.erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
---
title: การ Denormalize
slug: denormalization
date: 0010/01/02
number: 10.5
sidebar: true
contents: เข้าใจว่าการ denormalize คืออะไร|เปรียบเทียบ Mongo กับฐานข้อมูลทั่วไป|รู้ว่าเมื่อไรถึงไม่ควร denormalize
paragraphs: 15
---
การทำ Denormalize กับข้อมูลคือ การไม่เก็บข้อมูลนั้นในรูปแบบ "ปกติ" โดย denormalize ยังหมายถึงการที่มีข้อมูลเดียวกันหลายๆชุดไว้เอาเรียกใช้งาน
ในบทก่อนหน้านี้ เราได้ทำการ denormalize จำนวนข้อคิดเห็น ไปไว้ที่อ็อบเจกต์ข่าว เพื่อเลี่ยงการโหลดข้อคิดเห็นทั้งหมดอยู่ตลอดเวลา ในมุมมองของการทำแบบจำลองข้อมูลนั้น มันเป็นอะไรที่มากเกินไป เพราะเราสามารถทำการนับจำนวนข้อคิดเห็นเพื่อหาคำตอบได้ตลอดเวลาอยู่แล้ว (โดยยังไม่คิดเรื่องประสิทธิภาพ)
การ Denormalize บ่อยๆ หมายถึงงานที่เพิ่มขึ้นของนักพัฒนา ในตัวอย่างของเรานั้น ทุกครั้งที่เราเพิ่มหรือลบข้อคิดเห็น เราก็จำเป็นต้องอัพเดทข้อมูลข่าวที่เกี่ยวข้องเพื่อให้มั่นใจว่าฟิลด์ `commentsCount` ยังคงมีค่าที่ถูกต้อง และนี่ก็เป็นสาเหตุโดยตรงที่ฐานข้อมูลแบบ relational เช่น MySQL ไม่ค่อยถูกโฉลกกับแนวทางนี้
อย่างไรก็ตาม วิธีการแบบปกติก็มีข้อเสียของมัน นั่นคือ ถ้าไม่มีคุณสมบัติ `commentsCount` เราก็จำเป็นต้องส่งข้อคิดเห็น _ทั้งหมด_ มาตลอดเวลา เพียงเพื่อให้สามารถนับจำนวนมันได้เท่านั้น ซึ่งเป็นสิ่งที่เราทำในตอนแรก และการ Denormalize ช่วยเราให้หลีกเลี่ยงเรื่องแบบนี้ได้
<% note do %>
### การเผยแพร่แบบพิเศษ
มัน *เป็น* ไปได้ที่จะสร้างการเผยแพร่แบบพิเศษที่ส่งแค่จำนวนข้อคิดเห็นที่เราสนใจมาให้ (เช่น นับจำนวนข้อคิดเห็นของข่าวทั้งหมดที่เรากำลังดูอยู่ ด้วยการรันการสืบค้นที่เซิร์ฟเวอร์)
แต่ก็ควรต้องพิจารณาด้วยว่า ความซับซ้อนของโค้ดการเผยแพร่แบบนั้น ก็ไม่ควรจะมากไปกว่าความยากที่เกิดจากการ denormalize
<% end %>
แน่นอนที่สุดว่า การพิจาณานั้นขึ้นอยู่กับชนิดของแอปพลิเคชั่นด้วย ถ้าคุณเขียนโค้ดที่ยึดว่าความเป็นหนึ่งเดียวของข้อมูลเป็นสิ่งสำคัญ การหลีกเลี่ยงข้อมูลที่ไม่เป็นหนึ่งเดียวกันนั้นก็สำคัญมากกว่า และสำคัญยิ่งกว่าประสิทธิภาพที่จะได้รับเพิ่มขึ้นด้วย
### การฝังเอกสารลงไป หรือ การใช้หลายคอลเลกชั่น
ถ้าคุณมีประสบการณ์กับ Mongo คุณอาจประหลาดใจที่เราสร้างคอลเลกชั่นอีกตัวเพียงเพื่อจะเก็บข้อคิดเห็น ทำไมถึงไม่ฝังข้อคิดเห็นลงไปในลิสต์ข้างในเอกสารข่าวซะเลย?
เห็นได้ชัดว่า เครื่องมือหลายๆตัวของ Meteor ช่วยให้เราทำงานได้ดีขึ้นเมื่อทำงานที่ระดับของคอลเลกชั่น อย่างเช่น
1. ตัวช่วย `{{#each}}` ทำงานได้อย่างมีประสิทธิภาพมาก เมื่อทำงานซ้ำกับเคอร์เซอร์ (ผลลัพธ์ของคำสั่ง `collection.find()`) แต่จะไม่ได้ผลเหมือนเดิม ถ้าให้ทำซ้ำกับอาร์เรย์ของอ็อบเจกต์ภายในเอกสารที่ใหญ่ขึ้น
2. `allow` และ `deny` ทำงานที่ระดับเอกสาร และนั่นทำให้เป็นการง่ายที่จะทำให้แน่ใจว่า การเปลี่ยนแปลงใดๆกับข้อคิดเห็นแต่ละข้อเป็นเรื่องถูกต้อง ในมุมมองที่ว่ามันจะซับซ้อนมากขึ้นเมื่อเราทำงานที่ระดับของข่าว
3. DDP ทำงานที่ระดับของแอททริบิวต์ในระดับบนของเอกสาร ซึ่งอาจมีความหมายว่า ถ้า `comments` เป็นคุณสมบัติหนึ่งของ `post` ทุกครั้งที่ข้อคิดเห็นถูกสร้างขึ้นในหน้าข่าว เซิร์ฟเวอร์ก็จะส่งข้อคิดเห็นทั้งหมดของข่าวที่อัพเดทแล้วกลับไปที่ไคลเอนต์แต่ละตัวที่เชื่อมต่ออยู่
4. การเผยแพร่และบอกรับข้อมูล เป็นงานที่ง่ายกว่ามาก ถ้าทำงานในระดับของเอกสาร ตัวอย่างเช่น ถ้าเราต้องการแบ่งหน้าข้อคิดเห็นในหน้าข่าว เราอาจพบว่ามันยากที่จะทำ ยกเว้นถ้าข้อคิดเห็นอยู่ในคอลเลกชั่นของมันเอง
Mongo แนะนำให้ฝังเอกสารไว้ข้างใน เพื่อหลีกเลี่ยงจำนวนการสืบค้นที่มากเกินไปในการดึงเอกสารมาใช้หลายตัว อย่างไรก็ดี เรื่องนี้แทบจะไม่เป็นปัญหาถ้าเรามองว่า ด้วยสถาปัตยกรรมของ Meteor นั้น เราทำการสืบค้นข้อคิดเห็นที่ *ไคลเอนต์* เป็นส่วนใหญ่ โดยไม่ต้องเข้าถึงฐานข้อมูลเลย
<% note do %>
### ข้อเสียของการ Denormalize
มีข้อโต้แย้งที่ดีว่า คุณ *ไม่ควร* denormalize ข้อมูลของคุณ เพื่อให้คุณเข้าใจเรื่องที่แย้งกับการ denormalize เราแนะนำให้คุณอ่าน [Why You Should Never Use MongoDB](http://www.sarahmei.com/blog/2013/11/11/why-you-should-never-use-mongodb/) เขียนโดย Sarah Mei
<% end %>