มีตัวอย่างของวิธีการที่ไม่ใช่ CRUD หรือไม่?


14

ฉันเป็นโปรแกรมเมอร์ แต่ยังทำงานเป็นนักเก็บเอกสารด้วย ในฐานะที่เป็นผู้เก็บเอกสารสำคัญเป็นเรื่องเกี่ยวกับการเก็บข้อมูล

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

มีคำสำหรับสิ่งนี้หรือไม่? โดยพื้นฐานการสร้างและอ่านข้อมูลเท่านั้น? มีตัวอย่างของวิธีการนี้หรือไม่?


1
Is there a term for this? Basically only creating and reading data?แน่ใจว่ามี: CR; P
yannis

7
จากมุมมองของผู้ใช้ที่ยังคง CRUD ฉันไม่ทราบฉลากเฉพาะสำหรับรูปแบบการใช้งานนั้น แต่ฉันคิดว่าเป็นเรื่องธรรมดาในแอปพลิเคชัน MANY (การแลกเปลี่ยนสแต็คเป็นตัวอย่างที่ดี ... )
Mark E. Haase

คุณอาจต้องการที่จะดูการพูดคุยที่เรียกว่าความต้านทานไม่ตรงกันเป็นความผิดของเรา
Anton Barkovsky

+1 ณ จุดหนึ่งใครบางคนกำลังต้องการรายงานและมันยากมากที่จะสร้างรายงานเกี่ยวกับข้อมูลที่ไม่มีอยู่เพราะมันอยู่ในสถานะ "ปรับปรุง" ฉันค้นหาแนวทางของคุณที่กำลังคิดไปข้างหน้า
Chuck Conway

2
คุณอาจต้องการดูการพูดคุยเกี่ยวกับ Datomic: infoq.com/presentations/The-Design-of-Datomic
Marjan Venema

คำตอบ:


16

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

ควรสังเกตว่านี่เป็นเทคนิคการโต้เถียง ดูลิงค์: Con VS Pro


11

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

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


3
นี้. นอกจากนี้ความสมบูรณ์ของการอ้างอิงกลายเป็นฝันร้าย คุณไม่สามารถระบุคีย์ต่างประเทศให้กับ "บันทึกหนึ่งรายการในตารางนี้ด้วยรหัสที่ไม่ซ้ำกันซึ่งไม่ได้ทำเครื่องหมายว่าถูกลบ" คุณได้รับข้อมูลนั้นโดยการเก็บข้อมูลสำหรับสำเนาของระเบียนที่กำลังจะปรับปรุงลงในตารางอื่นก่อนที่จะอัปเดต "working copy" นี้กับข้อมูลใหม่ แต่คุณยังคงมีข้อมูลจำนวนมากที่ต้องจัดการ
KeithS

5

EventSourcingดูเหมือนรูปแบบที่คุณอาจมองหา

ลองมาตัวอย่างโดยใช้วัตถุ "รถยนต์" ง่าย ๆ ที่เราต้องการติดตามสี (หลอกรหัส C # ดังนี้)

public class Car {
  public string Color { get; set; }
  public Car() { this.Color = "Blue"; }
}

ด้วยการใช้ CRUD เมื่อเราอัปเดตสีของรถสีก่อนหน้านี้จะหายไป

MyCar.Color = "Red";
MyCar.Save();  // Persist the update to the database and lose the previous data

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

หากเราต้องเขียนคลาสรถใหม่เพื่อตอบสนองต่อกิจกรรมแทนเมื่ออัปเดตการเปลี่ยนแปลงอาจมีลักษณะเช่นนี้:

public class Car {
    public string Color { get; private set; } // Cannot be set from outside the class

    public void ApplyEvent(CarColorChangedEvent e) {
      this.Color = e.Color;
    }
}

ตอนนี้เราจะปรับปรุงสีของวัตถุนี้ได้อย่างไร เราสามารถสร้างกิจกรรมCarColorChanged !

var evnt = new CarColorChangedEvent("Red");
MyEventStore.save(evnt);
MyCar.ApplyEvent(evnt);

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

ตอนนี้ขอกรอไปข้างหน้าและเปลี่ยนสีอีกสองสามครั้ง:

var evnt = new CarColorChangedEvent("Green");
MyEventStore.save(evnt);
MyCar.ApplyEvent(evnt);

var evnt = new CarColorChangedEvent("Purple");
MyEventStore.save(evnt);
MyCar.ApplyEvent(evnt);

ถ้าเราดูที่การจัดเก็บเหตุการณ์ของเรา (อาจเป็นฐานข้อมูลความสัมพันธ์, ไฟล์, ฯลฯ ) เราจะเห็นชุดของเหตุการณ์ที่เกี่ยวข้องกับวัตถุรถยนต์ของเรา:

CarColorChangedEvent => Red
CarColorChangedEvent => Green
CarColorChangedEvent => Purple

หากเราต้องการสร้างรถยนต์ชิ้นนั้นขึ้นมาใหม่เราสามารถทำได้โดยการสร้างวัตถุรถยนต์ใหม่และใช้กิจกรรมจากที่จัดกิจกรรมของเรากับวัตถุดังกล่าว

var MyCar = new Car();
var events = MyDatabase.SelectEventsForCar("CarIdentifierHere");
foreach(var e in events) {
  MyCar.ApplyEvent(e);
}
Console.WriteLine(MyCar.Color); // Purple

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

var MyCar = new Car();
var event = MyDatabase.GetFirstEventForCar("CarIdentifierHere");
MyCar.ApplyEvent(e);
Console.WriteLine(MyCar.Color); // Red

5

การจัดหากิจกรรมเป็นหนทางไปและคุณควรดูว่า Greg Young พูดเกี่ยวกับเรื่องนี้อย่างไร

http://goodenoughsoftware.net/

ดูที่การนำเสนอนี้ในฐานข้อมูลของเขา (Event Store) คุณสามารถค้นหาวิดีโออื่น ๆ ได้เช่นกัน

http://oredev.org/2012/sessions/a-deep-look-into-the-event-store

ฉันจะไม่ตอบคำถามแบบ "soft-delete" เว้นแต่คุณจะต้องค้นหารายการที่ถูกลบโดยเฉพาะ แต่คุณไม่ควรคิดว่ามันถูกลบ แต่ถูกเก็บถาวร ฉันคิดว่าคำศัพท์มีความสำคัญมากที่นี่

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

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

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

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

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

ในกรณีที่มีการดีบักบ่อยครั้งที่คุณขอให้ผู้ใช้บอกสิ่งที่พวกเขาทำ ... ทำไมไม่เพียงแค่เล่นซ้ำสิ่งที่พวกเขาทำแล้วก้าวผ่านรหัส! น่ารักดีนะฮะ

หวังว่านี่จะช่วยได้


2

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

ผู้คนจำนวนมากพาความคิดนั้นไปสู่ระบบในภายหลัง ฉันได้ยินสิ่งที่คุณกำลังอธิบายเรียกว่าตาราง WORM แต่เฉพาะในแวดวงเหล่านั้น


2

ใช่มันค่อนข้างบ่อยในระบบองค์กรมีสองวิธีโดยทั่วไป: -

  • "bi - temporal" ซึ่งทุกระเบียนมีข้อมูลที่ถูกต้องและใช้ได้กับการประทับเวลา (บันทึก "ปัจจุบัน" ที่มีวันที่ "ถาวร" - null, "9999-12-31" หรือค่าสูงบางอย่างดังกล่าว) ระเบียนจะไม่ถูกลบแทนวันที่ "ใช้ได้กับ" จะถูกตั้งค่าเป็นเวลาปัจจุบันและในกรณีของการอัพเดตจะมีการแทรกระเบียนใหม่ด้วยข้อมูลที่ถูกต้องจากเวลาปัจจุบันและถูกต้องตลอดไปจนถึงวันที่
  • "ตารางประวัติ" - ทุกครั้งที่มีการเปลี่ยนแปลงระเบียนสำเนาของระเบียนเก่าจะถูกทิ้งในตารางประวัติ / บันทึกด้วยเวลาประทับสำหรับเหตุการณ์

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

โดยทั่วไปการพูด "bi-temporal" เป็นงานพิเศษมากมายและคุ้มค่าหากคุณมีกรณีการใช้งานจำนวนมากเช่น "ผู้ตรวจสอบได้รับสถานะคำสั่ง ณ วันที่ 31 ธันวาคม"


1

คุณสามารถใช้ "นุ่มลบ" ขณะที่สาธารณรัฐประชาธิปไตยประชาชนลาวแนะนำ สำหรับการอัปเดตคุณสามารถเก็บประวัติของเรียงลำดับเหมือนคำตอบของฉันที่นี่: /dba/28195/save-history-editable-data-rdbms/28201#28201ที่ OP ต้องการ สามารถติดตามข้อมูลบางประเภททุกรุ่นได้


-2

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

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