# Type-2 Slowly Changing Dimension (SCD) คือ?

**URL:** https://discuss.dataengineercafe.io/t/type-2-slowly-changing-dimension-scd/132
**Category:** General Discussion เรื่อง Data Engineering
**Tags:** data-warehouse, scd
**Created:** [March 14, 2022, 3:21pm UTC](https://discuss.dataengineercafe.io/t/type-2-slowly-changing-dimension-scd/132 "2022-03-14T15:21:31Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![zkan](https://yyz1.discourse-cdn.com/flex035/user_avatar/discuss.dataengineercafe.io/zkan/32/2_2.png) [@zkan](https://discuss.dataengineercafe.io/u/zkan)
#### Post date: [March 14, 2022, 3:21pm UTC](https://discuss.dataengineercafe.io/t/type-2-slowly-changing-dimension-scd/132/1 "2022-03-14T15:21:31Z")

</div>

ในโลก Data Warehouse หลายๆ คนอาจจะเคยได้ยินคำว่า Slowly Changing Dimension (SCD) กันมาบ้างเนอะ แล้วมันคืออะไรล่ะ? มันคือการจัดเก็บข้อมูลที่มีการเปลี่ยนแปลงไปเรื่อยๆ และที่เค้าบอกว่า slow เนี่ย เค้าหมายถึงข้อมูลที่เป็น dimension เนอะ เช่น ชื่อคน เพศ หรือ ชื่อ product อะไรแบบนี้ที่ไม่ได้มีการเปลี่ยนแปลงบ่อย ซึ่งโดยปกติแล้วข้อมูล dimension ก็จะเป็นประมาณนั้นอยู่แล้ว (แต่ถ้ามีการเปลี่ยนแปลงเร็วจริงๆ ลองดู [Rapidly Changing Dimension](https://dwgeek.com/rapidly-changing-dimension-data-warehouse.html/) เพิ่มนะ)

ลองนึกถึงการเก็บข้อมูลใน app สักตัวหนึ่ง อย่างเช่นข้อมูล order สินค้า แล้วก็มีฟิลด์ status เพื่อบอกว่าตอนนี้ order อยู่ในสถานะอะไร แล้วทีนี้ใน app ของเราเวลาที่มาอัพเดท status เราก็จะมาอัพเดทที่ข้อมูลเดิมกันเลยใช่ไหม? 😆 มาดูตัวอย่างกันให้ชัดๆ สมมุติว่าเรามีข้อมูลตั้งต้นประมาณนี้

| id | status | updated\_at |
| --- | --- | --- |
| 1 | pending | 2019-01-01 |

แล้วพอสถานะเปลี่ยน ข้อมูลก็จะกลายเป็นแบบนี้

| id | status | updated\_at |
| --- | --- | --- |
| 1 | shipped | 2019-01-02 |

ทีนี้มันก็มีปัญหาอยู่ว่าถ้าเราต้องการที่จะวิเคราะห์ช่วงระยะเวลาระหว่างจากสถานะ pending ไปเป็น shipped เนี่ย เราไม่สามารถที่จะรู้ได้เลย หรือถ้าเราต้องการที่จะดูว่าก่อนสถานะเป็น shipped เนี่ย มันเคยเป็นสถานะอะไรมาก่อน?

ตรงนี้แหละครับที่เราสามารถเอา SCD มาใช้ได้ โดยที่นิยมใช้ๆ กันก็คือ [Type-2](https://en.wikipedia.org/wiki/Slowly_changing_dimension#Type_2:_add_new_row) อธิบายง่ายๆ มันก็คือการเพิ่มข้อมูลมาอีก 1 แถวโดยที่ยังเก็บข้อมูลเก่าไว้

จากตัวอย่างข้อมูลด้านบน เราก็จะสามารถเก็บข้อมูลได้เป็นแบบนี้

| id | status | updated\_at | from | to |
| --- | --- | --- | --- | --- |
| 1 | pending | 2019-01-01 | 2019-01-01 | 2019-01-02 |
| 1 | shipped | 2019-01-02 | 2019-01-02 | null |

ซึ่งเราก็อาจจะมีฟิดล์ `from` กับ `to` เอาไว้บอกสักหน่อยว่าค่าๆ นี้เริ่มตั้งแต่เมื่อไหร่ และถึงเมื่อไหร่ถึงจะเปลี่ยนไปเป็นค่าใหม่ ก็เป็นอันเรียบร้อย… เรื่อง Type-2 SCD ก็ประมาณนี้แหละ 😄

จริงๆ เรื่องนี้เราสามารถพูดคุยตกลงกับทางสายพัฒนา software ได้เลยนะ หาทางออกร่วมกันว่าแบบไหนจะดีที่สุดสำหรับพวกเรา ตั้งแต่ในระดับ app เราสามารถเก็บ history ไว้ได้หรือเปล่า? ถ้าไม่ได้ แล้วเราสามารถทำเป็น change event มาได้ไหม? แล้วถ้าไม่ได้ โอเคเราสามารถเอามาทำ Type-2 SCD ก็พอจะตอบโจทย์การวิเคราะห์ข้อมูลไหม? บลาๆ

ฮ่าๆ ถ้าถามผมเนี่ย ผมไม่มีคำตอบที่ดีที่สุดให้นะครับ อันนี้อยู่ที่บริบทการคุยกันภายในทีมของแต่ละองค์กรเลย ทุกทางเลือกมี technical debt หมด อยู่ที่เราจะจัดการมันอย่างไร 😉

**Ref:** [Snapshots | dbt Docs](https://docs.getdbt.com/docs/building-a-dbt-project/snapshots)

---

<div class="post-metadata">

### Author: ![yothinix](https://yyz1.discourse-cdn.com/flex035/user_avatar/discuss.dataengineercafe.io/yothinix/32/147_2.png) [@yothinix](https://discuss.dataengineercafe.io/u/yothinix)
#### Post date: [March 15, 2022, 3:40am UTC](https://discuss.dataengineercafe.io/t/type-2-slowly-changing-dimension-scd/132/2 "2022-03-15T03:40:49Z")

</div>

อันนี้ดีมาก ผมเคยทำระบบที่เป็น pub/sub หลายปีมาแล้ว เคยเจอปัญหาว่า worker มัน failed แล้วมันไม่หยิบของไป processing เลย ซึ่งตอนแรกไม่ได้ design แบบนี้ ข้อมูลช่วงที่ worker failed คือทำ manual ใหม่หมดเลย

แต่พอใช้ท่าเก็บข้อมูลแบบข้างบน ตอนนั้นคือพอเกิดปัญหาอีกรอบ เราสามารถ re-execute worker ให้มันกลับมาทำต่อจากจุดที่เรารู้ว่ามัน failed ได้เลย เพราะ state ของข้อมูลมัน trace ไปได้หมดเลย

ข้อเสียเดียวที่ผมนึกออกตอนนั้นคือตัว change log อันนี้มันบวมมาก ตอนทำโปรเจ็คนั้นแล้วต้องคอยเคลียร์ทุกๆ เดือน แต่ถ้าเป็นสมัยนี้ของพวกนี้น่าจะเก็บลง Data lake ได้สบายๆ แล้วครับ

---

<div class="post-metadata">

### Author: ![gatukgl](https://yyz1.discourse-cdn.com/flex035/user_avatar/discuss.dataengineercafe.io/gatukgl/32/145_2.png) [@gatukgl](https://discuss.dataengineercafe.io/u/gatukgl)
#### Post date: [March 15, 2022, 4:16am UTC](https://discuss.dataengineercafe.io/t/type-2-slowly-changing-dimension-scd/132/3 "2022-03-15T04:16:55Z")

</div>

เพิ่งรู้ว่ามันมีชื่อเรียกวิธีการทำอะไรแบบนี้ด้วย ขอบคุณมากเลยค่า

---

<div class="post-metadata">

### Author: ![zkan](https://yyz1.discourse-cdn.com/flex035/user_avatar/discuss.dataengineercafe.io/zkan/32/2_2.png) [@zkan](https://discuss.dataengineercafe.io/u/zkan)
#### Post date: [March 21, 2022, 1:04am UTC](https://discuss.dataengineercafe.io/t/type-2-slowly-changing-dimension-scd/132/4 "2022-03-21T01:04:57Z")

</div>

อ่านเพิ่มเติมเกี่ยวกับ Slowly Changing Dimensions ได้ที่บทความนี้เลย อธิบายไว้ดีงาม

> **[6 Different Types of Slowly Changing Dimensions and How to Apply Them?](https://medium.com/geekculture/6-different-types-of-slowly-changing-dimensions-and-how-to-apply-them-b152ef908d4e)**
>
> Learn How Best to Apply These History Maintenance Methods Here

---

<div class="post-metadata">

### Author: ![zkan](https://yyz1.discourse-cdn.com/flex035/user_avatar/discuss.dataengineercafe.io/zkan/32/2_2.png) [@zkan](https://discuss.dataengineercafe.io/u/zkan)
#### Post date: [March 25, 2023, 4:49am UTC](https://discuss.dataengineercafe.io/t/type-2-slowly-changing-dimension-scd/132/5 "2023-03-25T04:49:34Z")

</div>

เผื่อใครอยากจะทำ SCD Type 2 ใน Spark

[https://towardsdatascience.com/slowly-changing-dimension-type-2-in-spark-7d5865ac915b](https://towardsdatascience.com/slowly-changing-dimension-type-2-in-spark-7d5865ac915b)

---

<div class="post-metadata">

### Author: ![kahnwong](https://yyz1.discourse-cdn.com/flex035/user_avatar/discuss.dataengineercafe.io/kahnwong/32/295_2.png) [@kahnwong](https://discuss.dataengineercafe.io/u/kahnwong)
#### Post date: [March 28, 2023, 1:54pm UTC](https://discuss.dataengineercafe.io/t/type-2-slowly-changing-dimension-scd/132/6 "2023-03-28T13:54:32Z")

</div>

จากประสบการณ์ พบว่า อย่าอัดค่าทับใน prod db โดยไม่ทำ log/trail ทิ้งไว้  
เพราะถ้าอัดทับ มันจะย้อนอดีตไม่ได้ 🤣  
แล้วมันจะมีแน่ๆ ที่คนอยากรู้ ว่า ใช้เวลาเท่าไหร่ในแต่ละช่วง แล้วบาง use case จะงอกมาตอนหลังๆ แต่ operation db เขาใช้งานกันจริงไปเรียบร้อยแล้ว…

เพราะฉะนั้น เก็บของดิบไว้ให้ครบๆ แล้วจะสบายสำหรับงานในอนาคต 😆

---

<div class="post-metadata">

### Author: ![zkan](https://yyz1.discourse-cdn.com/flex035/user_avatar/discuss.dataengineercafe.io/zkan/32/2_2.png) [@zkan](https://discuss.dataengineercafe.io/u/zkan)
#### Post date: [March 29, 2023, 7:31am UTC](https://discuss.dataengineercafe.io/t/type-2-slowly-changing-dimension-scd/132/7 "2023-03-29T07:31:10Z")

</div>

> [@kahnwong](#):
>
> เพราะฉะนั้น เก็บของดิบไว้ให้ครบๆ แล้วจะสบายสำหรับงานในอนาคต 😆

เห็นด้วยอย่างรุนแรงครับ ฮ่า ๆ
