วิธีจัดเก็บสถานะการบันทึก (เช่นรอดำเนินการเสร็จสมบูรณ์แบบร่างยกเลิก ... )


18

มีแอปพลิเคชันจำนวนมากที่ต้องการบันทึกในตารางเพื่อให้มีสถานะเช่น 'สมบูรณ์', 'ร่าง', 'ยกเลิก' วิธีที่ดีที่สุดในการจัดเก็บสถานะเหล่านี้คืออะไร เพื่อแสดงให้เห็นถึงสิ่งที่ฉันได้รับที่นี่เป็นตัวอย่างที่สั้นมาก)

ฉันมีแอปพลิเคชันบล็อกที่เรียบง่ายและโพสต์แต่ละรายการมีสถานะหนึ่งใน: เผยแพร่ร่างหรือรอดำเนินการ

วิธีที่ฉันเห็นมันมี 2 วิธีในการสร้างแบบจำลองนี้ในฐานข้อมูล

  1. ตารางโพสต์มีฟิลด์ข้อความที่มีข้อความสถานะ
  2. ตารางโพสต์มีฟิลด์สถานะที่มี ID ของบันทึกในตาราง PostStatus

ตัวอย่างบล็อกที่นี่เป็นตัวอย่างที่ง่ายมาก ที่ enum (ถ้าสนับสนุน) อาจพอเพียง อย่างไรก็ตามฉันต้องการคำตอบสำหรับคำถามเพื่อพิจารณาว่ารายการสถานะสามารถเปลี่ยนแปลงได้ตลอดเวลาดังนั้นสามารถเพิ่มหรือลบได้อีก

ทุกคนสามารถอธิบายข้อดี / ข้อเสียของแต่ละคนได้หรือไม่?

ไชโย!

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



"ตลอดเวลา" คุณหมายถึงอะไร นั่นหมายความว่าเป็นส่วนหนึ่งของกิจกรรมของผู้ใช้หรือเป็นส่วนหนึ่งของวงจรการเปิดตัวซอฟต์แวร์หรือไม่?
kevin cline

ทั้งสองอย่างซึ่งในกรณีนี้เป็นวิธีการใด ๆ ดังนั้นหากผู้ใช้สามารถเพิ่มสถานะใหม่หรือหากมีการเพิ่มสถานะใหม่ในภายหลังโครงการ
veganista

การจัดเก็บข้อความในฐานข้อมูลอาจเป็นการดีที่สุด ฉันคิดว่ามันอาจขึ้นอยู่กับรายละเอียดที่แม่นยำเช่นองค์กรของคุณเปลี่ยนกระบวนการบ่อยเพียงใด (นำไปสู่การเปลี่ยนแปลงสถานะที่เป็นไปได้)
Jaydee

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

คำตอบ:


14

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

สิ่งนี้ไม่ได้ทำให้ข้อมูลผิดปกติ แต่เปลี่ยนการเป็นตัวแทนเท่านั้น หากฐานข้อมูลรองรับการแจกแจงโดยตรงให้ใช้สิ่งนั้น มิฉะนั้นใช้ข้อ จำกัด ในการ จำกัด ค่าคอลัมน์ คุณกำลังจะมีข้อ จำกัด อย่างใดอย่างหนึ่ง: ข้อ จำกัด โดยตรงในค่าคอลัมน์หรือข้อ จำกัด ที่สำคัญต่างประเทศ

ใช่คุณอาจต้องแสดงสถานะที่แตกต่างกับผู้ใช้อื่น นั่นเป็นปัญหาการนำเสนอที่ต้องแก้ไขในเลเยอร์การนำเสนอไม่ใช่ชั้นการคงอยู่


1
+1, ยกเว้นความต้องการเฉพาะในการเก็บรายการสถานะใน db ซึ่งโดยทั่วไปเป็นวิธีที่ง่ายที่สุดและซับซ้อนน้อยที่สุดในการทำ
GrandmasterB

2
ไม่เป็นไรเว้นแต่คุณจะเริ่มเปลี่ยนสถาปัตยกรรมสถานะหรือจัดเก็บวันที่กลายพันธุ์
LastTribunal

10

การจัดเก็บข้อความสถานะเป็น IMO ไม่ใช่ความคิดที่ดีเนื่องจากอาจมีคนตัดสินใจว่า "เสร็จสิ้น" ควรจะเรียกว่า "เสร็จสิ้น" แทนแล้วคุณต้องอัปเดตฐานข้อมูลของคุณดูผ่านโปรแกรมหากมีคนเขียนรหัสข้อความ ฯลฯ

สิ่งที่ฉันเห็นในหลาย ๆ โปรแกรมคือรหัสตัวเลข (1 = ใหม่, 2 = ฉบับร่าง, 3 = ในการตรวจสอบ, 4 = เสร็จสมบูรณ์, 99 = ยกเลิก) หรือรหัสตัวอักษรผสมตัวเลขสั้น ("ใหม่", "DRA", "INV "," COM "," CAN ") ภายหลังทำให้รหัส (ในโปรแกรมหรือในฐานข้อมูล) อ่านง่ายขึ้นซึ่งโดยทั่วไปเป็นสิ่งที่ดี ในทางกลับกันรหัสตัวเลขทำให้ง่ายต่อการเปรียบเทียบ "มากกว่า" หรือ "เล็กกว่า"

select * from myrecords where status < Status.Complete;

คนงี่เง่าบางคนสามารถทำให้ ID ง่าย ๆ ได้เช่นกัน
ปัญญาอ่อน

ข้อดีอีกประการของ ID คือคุณต้องจัดเตรียมการแปล คุณสามารถใช้ ID ของคุณเพื่อค้นหาสตริงทรัพยากรและแสดงผล ด้วยสตริงที่เข้ารหัสยากนี้เป็นไปไม่ได้
armitage

3
ฉันไม่คิดว่าทำสถานะโดยใช้การเปรียบเทียบ "มากกว่า" หรือ "เล็กกว่า" เหมือนที่คุณแสดงเป็นความคิดที่ดี มันอาจจะทำงานสำหรับการใช้งานที่เรียบง่ายเช่นตัวอย่างนี้ แต่ไม่ดีสำหรับปพลิเคชันที่ซับซ้อนมากขึ้น (แม้ว่า im แน่ใจว่าคุณตระหนักถึงที่)
veganista

1
@ armitage: สามารถทำการค้นหาโดยใช้สตริงได้อย่างสมบูรณ์แบบ ชื่อทรัพยากรคือสตริง:status.draft=Draught
kevin cline

วีแก้น: แน่นอนว่าอาจมีความยากลำบากมากกว่า / เล็กกว่าการเปรียบเทียบ แต่ฉันได้เห็นระบบที่ซับซ้อนขนาดใหญ่ที่ทำสิ่งนั้นและมีชีวิตอยู่
281377

4

กฎสามข้อของฐานข้อมูลเชิงสัมพันธ์:

  1. ปกติ
  2. ปกติ
  3. ปกติ

ดังนั้นคำถามของคุณตอบเอง เก็บภายในสถานะของมันเองตารางและใช้ GUID / UUIDs เป็น ID GUIDS ที่จัดทำดัชนีนั้นรวดเร็วมากและแก้ไขปัญหาที่แท้จริงให้เป็นตัวเลขที่เพิ่มขึ้น ด้วย ID คุณสามารถทำสิ่งที่ยอดเยี่ยมเช่นขอให้ DB สำหรับโพสต์ที่เสร็จสมบูรณ์ทั้งหมดโดยใช้ ID และเนื่องจากคุณกำลังทำงานภายในกระบวนทัศน์ฐานข้อมูลเชิงสัมพันธ์มันเร็วมาก หากคุณมีเพียงหนึ่งเขตข้อมูลฐานข้อมูลจะต้องวนซ้ำแถวทุกแถวและทำการเปรียบเทียบข้อความอาจมีข้อผิดพลาดและนั่นช้ามาก

โพสต์ชื่อสถานะสามารถเปลี่ยนข้อมูลเพิ่มเติมเกี่ยวกับสถานะการโพสต์สามารถไปลงในตารางทุกอย่างเพียงทำงานถ้าคุณปกติ

ตัวอย่างเช่นคุณสามารถเพิ่มระดับสถานะเป็นข้อมูลเพิ่มเติมซึ่งจะช่วยให้การเปรียบเทียบ ammoQ กล่าวถึง แต่พวกเขาไม่ได้ขึ้นอยู่กับคีย์สำหรับการกำหนดตำแหน่งการอนุญาตให้จัดระดับสถานะใหม่โดยไม่ทำลายความสมบูรณ์ของฐานข้อมูล นอกจากนี้คุณยังสามารถแทรกระดับเพิ่มเติมซึ่งค่อนข้างเป็นกลหากคุณมีระดับที่เกี่ยวข้องกับคีย์การสร้างอัตโนมัติ


เหตุผลที่คุณระบุไว้ในที่นี้คือเหตุผลที่ฉันใช้ตารางอื่นเพื่อจัดเก็บสิ่งของของฉัน เหตุผลหลักที่ฉันถามคำถามนี้คือเพื่อดูว่าบางครั้งมันเป็นเรื่องดีที่จะใช้ช่องข้อความที่เรียบง่าย
veganista

@ เลียมเท่านั้นถ้ามันเป็นปกติลงในช่องข้อความ นั่นคือถ้าช่องข้อความของคุณขึ้นอยู่กับคีย์หลักเท่านั้นและคุณกำลังค้นหาสิ่งต่าง ๆตามคีย์หลักโดยที่ฟิลด์ข้อความจะปรากฏขึ้น ฐานข้อมูลเชิงสัมพันธ์นั้นเกี่ยวกับความสัมพันธ์คุณมีอยู่ที่นี่ดังนั้นจึงจำเป็นต้องกำหนด หนึ่งในข้อยกเว้นบางประการคือถ้าคุณจัดการข้อมูลสกปรกจากแหล่งภายนอกและคุณไม่มีเวลาในการสร้างแบบจำลองทั้งหมด หลีกเลี่ยงสิ่งนี้ถ้าเป็นไปได้
Spencer Rathbun

ซ่อนตาไว้ทุกข์ GUID ที่จะไม่กลับมา
sq33G

คุณควรเขียน "สามทฤษฎีของฐานข้อมูลเชิงสัมพันธ์" ทฤษฎีนั้นไม่สามารถนำไปใช้ได้จริงเสมอไป บ่อยครั้งจะมีประสิทธิภาพมากกว่าในการจัดเก็บรหัสสถานะลงในระเบียนที่เกี่ยวข้องโดยตรง หากคุณไม่จำเป็นต้องค้นหาเพื่อใช้งานการลบการเข้าร่วมไปยังตารางอื่นจะช่วยประหยัดการประมวลผลที่สูญเปล่ามากมาย
Suncat2000

ลงเนื่องจากข้อมูลผิดเกี่ยวกับประเภทคอลัมน์เทียบกับการสแกนตารางแบบเต็ม
igorrs

3

ใช่คุณควรไปกับตัวเลือก 2 โดยมีตาราง PostStatus

นอกเหนือจากข้อดีทั้งหมดที่กล่าวถึงในคำตอบอื่น ๆ

โปรดทราบว่าสถานะจะต้องเพิ่มหรือลบออกคุณสามารถมีคอลัมน์ "เปิดใช้งาน" ในตาราง PostStatus ดังนั้นหากสถานะถูกลบออกให้ทำเครื่องหมายคอลัมน์ "เปิดใช้งาน" เป็น "N" ด้วยวิธีนี้คุณจะสามารถ เพิ่มหรือลบสถานะและระเบียนที่มีอยู่จะไม่มีปัญหา


1

ฉันต้องการเพิ่มคำตอบที่ลึกซึ้งเป็นอย่างอื่นซึ่งสำหรับการทำให้เป็นมาตรฐานโดยสมบูรณ์การเปลี่ยนแปลงสถานะของเอนทิตีนั้นเป็นแบบจำลองในเอนทิตีที่แยกต่างหากเช่นชื่อ 'เปลี่ยนสถานะ'

คุณต้องเข้าร่วมเป็นพิเศษกับสถานะเปลี่ยนเอนทิตี แต่คุณจะชนะความเป็นไปได้ของการเพิ่มข้อมูลพิเศษเช่นนักแสดงที่ทำการเปลี่ยนแปลงความเห็นที่เป็นไปได้เกี่ยวกับสาเหตุที่การเปลี่ยนแปลงเกิดขึ้นและวันที่สถานะเปลี่ยนอาจดำเนินการ มันจะมีประสิทธิภาพ


0

การใช้ข้อความสำหรับสถานะในตารางบันทึกอาจไม่เป็นความคิดที่ดีเนื่องจากสามารถเปลี่ยนแปลงได้และจะเป็นการยากที่จะทำการตรวจสอบความสมบูรณ์ของข้อมูลในการแทรก / อัปเดต หากคุณกำลังใช้ DBMS กับประเภทข้อมูล enum คุณสามารถใช้สิ่งนี้แทน (ประสิทธิภาพอาจไม่ถูกทำลาย ... ขึ้นอยู่กับ)

หากสถานะของคุณต้องการข้อมูลเมตา (คำอธิบายสร้างโดยชื่อที่จำง่าย ... ) คุณจะต้องจัดเก็บสถานะในตารางแยกต่างหากและมีรหัสสถานะในตารางบันทึกของคุณ (ตรวจสอบให้แน่ใจว่าคุณใช้รหัสต่างประเทศ) ID ไม่จำเป็นต้องเป็นตัวเลขเพียง PK ของตารางสถานะ นอกจากนี้หากสถานะอยู่ในตารางของตัวเองคุณสามารถแบ่งปันกับประเภทระเบียน (ตาราง) หากมี ฉันจะไม่กังวลเกี่ยวกับปัญหาด้านประสิทธิภาพเมื่อเข้าร่วมกับตารางสถานะ

ไม่ว่าคุณจะทำอะไรให้แน่ใจว่าคุณหลีกเลี่ยงสถานะเวทย์มนตร์ (1 สำหรับการใช้งาน, 2 สำหรับการลบ, ... ) สิ่งนี้อาศัยเอกสารและประเพณีซึ่งมักจะมีแนวโน้มที่จะหลงทางในไทม์ไลน์ขนาดใหญ่พอ หากคุณกำลังใช้รหัสตัวเลขให้ตรวจสอบให้แน่ใจว่ามีการเชื่อมโยงแบบข้อความอยู่ในฐานข้อมูลของคุณ


หากคุณไม่ต้องกังวลเกี่ยวกับประสิทธิภาพคุณอาจเสียสละความสามารถในการปรับขนาดได้ เป็นไปไม่ได้ที่คอมพิวเตอร์จะหลีกเลี่ยงสถานะเวทย์มนตร์: 0 และ 1 เป็นสิ่งมหัศจรรย์ภายใน
Suncat2000

0

ขึ้นอยู่กับวัตถุประสงค์ของการออกแบบฐานข้อมูล

หากคุณออกแบบฐานข้อมูลเพียงเพื่อรองรับแอปพลิเคชัน (เช่นวัตถุ (รหัส) เป็นหลักของทั้งหมด) จากนั้นใช้การแจงนับ (หรือการแจงนับ psuedo สำหรับชั้นเรียนที่ไม่สนับสนุนพวกเขา) และเก็บออกชื่อของ enum เป็น ความคิดที่ดีเพราะคุณยังคงควบคุมค่าที่อนุญาตผ่าน enum และคุณยังทำให้ตารางอ่านง่ายขึ้นเมื่อคุณถูกบังคับให้ดูข้อมูลดิบ (ซึ่งไม่ใช่เรื่องที่มักจะเกิดขึ้นถ้ารหัสกฎจริง ๆ ทั้งหมด) แต่ถ้าการแจงนับถูกตั้งค่าสถานะ จากนั้นฉันมักจะเก็บค่า enum (จำนวนเต็ม)


-1

สถานะมีความสำคัญมากทุกครั้งที่คุณรับข้อมูลโพสต์คุณจะต้องได้รับสถานะหรือคุณต้องการกรองการโพสต์ตามสถานะ หากคุณมีสถานะในตารางอื่นคุณจะต้องทำการเข้าร่วมเพื่อรับข้อมูลนี้และประสิทธิภาพจึงลดลง แน่นอนคุณควรมีสถานะในตารางเดียวกัน และใส่ดัชนีลงไป! คุณยังสามารถใช้จำนวนเต็มเป็นสถานะหรืออาจเป็นฟิลด์ enum


-2

วิธีแก้ไขที่ถูกต้องคือการใช้ Event Store / Source ด้วย CQRS หรือ blockchain ปัญหาเกี่ยวกับการจับภาพเหตุการณ์ใน RDB คือ RDB เก็บสแน็ปช็อตของเหตุการณ์เดี่ยวในเวลาและสิ่งต่าง ๆ เช่น "สถานะ / รัฐ" เป็นลำดับของการกลายพันธุ์ที่วิวัฒนาการตลอดเวลา


หากคุณกำลังจะลงคะแนนโพสต์ของฉันให้ทำกรณี คุณเป็นเพียง lemming ใจอ่อนที่มีขอบเขตน้อยมากนอกกรอบ
LastTribunal
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.