ความจริงก่อนหรือทำไมระบบต้องออกแบบโดยอิงจากอุปกรณ์ฐานข้อมูล

เฮ้ ฮับ!

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

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

บทความนี้เขียนขึ้นจาก หนึ่งคำถามที่กำหนดใน Stack Overflow

การสนทนาที่น่าสนใจเกี่ยวกับ reddit ในหัวข้อต่างๆ /r/ชวา и /r/การเขียนโปรแกรม.

การสร้างรหัส

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

	for (Record2<String, String> record : DSL.using(configuration)
//   ^^^^^^^^^^^^^^^^^^^^^^^ Информация о типах выведена на 
//   основании сгенерированного кода, на который ссылается приведенное
// ниже условие SELECT 
 
       .select(ACTOR.FIRST_NAME, ACTOR.LAST_NAME)
//           vvvvv ^^^^^^^^^^^^  ^^^^^^^^^^^^^^^ сгенерированные имена
       .from(ACTOR)
       .orderBy(1, 2)) {
    // ...
}

รหัสถูกสร้างขึ้นด้วยตนเองภายนอกบิลด์ หรือสร้างด้วยตนเองในทุกบิลด์ ตัวอย่างเช่น การฟื้นฟูดังกล่าวอาจตามมาทันทีหลังจากนั้น การโยกย้ายฐานข้อมูล Flyway ซึ่งสามารถทำได้ด้วยตนเองหรือโดยอัตโนมัติ.

การสร้างซอร์สโค้ด

มีปรัชญา ข้อดีและข้อเสียต่างๆ ที่เกี่ยวข้องกับวิธีการสร้างโค้ดเหล่านี้ ทั้งแบบแมนนวลและอัตโนมัติ ซึ่งฉันจะไม่พูดถึงรายละเอียดในบทความนี้ แต่โดยทั่วไปแล้ว จุดรวมของโค้ดที่สร้างขึ้นคืออนุญาตให้คุณสร้าง "ความจริง" ที่เรายอมรับใน Java ได้ ไม่ว่าจะภายในระบบของเราหรือภายนอกระบบก็ตาม ในแง่หนึ่ง คอมไพเลอร์ที่สร้าง bytecode, machine code หรือโค้ดประเภทอื่นๆ จากซอร์สโค้ดจะทำสิ่งเดียวกัน นั่นคือเราได้ตัวแทนของ "ความจริง" ในภาษาอื่น โดยไม่คำนึงถึงเหตุผลเฉพาะเจาะจง

มีตัวสร้างรหัสดังกล่าวมากมาย ตัวอย่างเช่น, XJC สามารถสร้างโค้ด Java ตามไฟล์ XSD หรือ WSDL. หลักการจะเหมือนกันเสมอ:

  • มีความจริงบางอย่าง (ภายในหรือภายนอก) - ตัวอย่างเช่น ข้อกำหนด แบบจำลองข้อมูล เป็นต้น
  • เราต้องการตัวแทนในท้องถิ่นของความจริงนี้ในภาษาโปรแกรมของเรา

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

ผู้ให้บริการประเภทและการประมวลผลคำอธิบายประกอบ

หมายเหตุ: อีกวิธีหนึ่งที่ทันสมัยและเฉพาะเจาะจงมากขึ้นในการสร้างรหัสสำหรับ jOOQ เกี่ยวข้องกับการใช้ผู้ให้บริการประเภท ตามที่นำไปใช้ใน F #. ในกรณีนี้ โค้ดถูกสร้างขึ้นโดยคอมไพเลอร์ จริงๆ แล้วอยู่ที่ขั้นตอนการคอมไพล์ โดยหลักการแล้ว รหัสดังกล่าวไม่มีอยู่ในรูปแบบของซอร์สโค้ด ใน Java มีเครื่องมือที่คล้ายกันแม้ว่าจะไม่สวยงามเท่า - เครื่องมือเหล่านี้คือตัวประมวลผลคำอธิบายประกอบเช่น ลอมบอก.

ในแง่หนึ่ง สิ่งเดียวกันนี้เกิดขึ้นที่นี่เช่นเดียวกับในกรณีแรก ยกเว้น:

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

ปัญหาของการสร้างรหัสคืออะไร?

นอกจากคำถามที่ยุ่งยากว่าการเริ่มสร้างโค้ดจะดีกว่าอย่างไร - ด้วยตนเองหรือโดยอัตโนมัติ ฉันต้องพูดถึงว่ามีคนจำนวนมากที่เชื่อว่าการสร้างโค้ดนั้นไม่จำเป็นเลย เหตุผลสำหรับมุมมองนี้ซึ่งฉันพบบ่อยที่สุดคือการตั้งค่าไปป์ไลน์การสร้างนั้นยาก ใช่ มันยากจริงๆ มีค่าใช้จ่ายด้านโครงสร้างพื้นฐานเพิ่มเติม หากคุณเพิ่งเริ่มต้นใช้งานผลิตภัณฑ์ใดผลิตภัณฑ์หนึ่ง (ไม่ว่าจะเป็น jOOQ หรือ JAXB หรือ Hibernate เป็นต้น) ต้องใช้เวลาในการตั้งค่าเวิร์กเบนช์ที่คุณต้องการใช้เรียนรู้ API เองเพื่อรับประโยชน์จากผลิตภัณฑ์นั้น .

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

หลายคนจะบอกว่าพวกเขาไม่มีเวลาทำทั้งหมดนี้ พวกเขากำลังจะถึงกำหนดเวลาสำหรับ Super Product สักวันหนึ่งเราจะหวีสายพานประกอบ เราจะมีเวลา ฉันจะตอบพวกเขา:

ความจริงก่อนหรือทำไมระบบต้องออกแบบโดยอิงจากอุปกรณ์ฐานข้อมูล
ดั้งเดิม, Alan O'Rourke, Audience Stack

แต่ใน Hibernate / JPA การเขียนโค้ด "ใน Java" นั้นง่ายมาก

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

	@Entity
class Book {
  @Id
  int id;
  String title;
}

และเกือบทุกอย่างพร้อมแล้ว ตอนนี้ไฮเบอร์เนตจำนวนมากคือการสร้าง "รายละเอียด" ที่ซับซ้อนว่าจะกำหนดเอนทิตีนี้ใน DDL ของ "ภาษาถิ่น" ของ SQL อย่างไร:

	CREATE TABLE book (
  id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
  title VARCHAR(50),
 
  CONSTRAINT pk_book PRIMARY KEY (id)
);
 
CREATE INDEX i_book_title ON book (title);

... และเริ่มเรียกใช้แอปพลิเคชัน คุณลักษณะที่ยอดเยี่ยมมากในการเริ่มต้นใช้งานอย่างรวดเร็วและทดลองทำสิ่งต่างๆ

อย่างไรก็ตามให้ฉัน ฉันโกหก

  • ไฮเบอร์เนตจะบังคับใช้คำจำกัดความของคีย์หลักที่มีชื่อนี้หรือไม่
  • Hibernate จะสร้างดัชนีใน TITLE หรือไม่ ฉันรู้แน่นอนว่าเราต้องการมัน
  • ไฮเบอร์เนตจะทำให้คีย์นี้เป็นคีย์ข้อมูลประจำตัวในข้อกำหนดข้อมูลประจำตัวหรือไม่

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

	@Entity
@Table(name = "book", indexes = {
  @Index(name = "i_book_title", columnList = "title")
})
class Book {
  @Id
  @GeneratedValue(strategy = IDENTITY)
  int id;
  String title;
}

เย็น. สร้างใหม่ ในกรณีนี้ มันจะง่ายมากในตอนเริ่มต้น

แต่คุณจะต้องจ่ายในภายหลัง

ไม่ช้าก็เร็วคุณจะต้องเข้าสู่การผลิต นั่นคือเมื่อโมเดลหยุดทำงาน เพราะ:

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

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

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

แต่ตั้งแต่เริ่มแรก ทุกอย่างสามารถทำได้แตกต่างไปจากเดิมอย่างสิ้นเชิง ตัวอย่างเช่น ใส่ล้อกลมบนจักรยาน

ฐานข้อมูลก่อน

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

และนั่นไม่ใช่ทั้งหมด ตัวอย่างเช่น เมื่อใช้ Oracle คุณอาจต้องการระบุ:

  • ตารางของคุณอยู่ในพื้นที่ใด
  • ค่า PCTFREE ของเธอคืออะไร
  • ขนาดแคชในลำดับของคุณคือเท่าใด (หลังรหัส)

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

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

แล้วโมเดลลูกค้าล่ะ?

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

ฐานข้อมูลทั้งหมดให้ข้อมูลเมตาผ่าน SQL ต่อไปนี้เป็นวิธีรับตารางทั้งหมดในภาษาถิ่น SQL ที่ต่างกันจากฐานข้อมูลของคุณ:

	-- H2, HSQLDB, MySQL, PostgreSQL, SQL Server
SELECT table_schema, table_name
FROM information_schema.tables
 
-- DB2
SELECT tabschema, tabname
FROM syscat.tables
 
-- Oracle
SELECT owner, table_name
FROM all_tables
 
-- SQLite
SELECT name
FROM sqlite_master
 
-- Teradata
SELECT databasename, tablename
FROM dbc.tables

ข้อความค้นหาเหล่านี้ (หรือคำที่คล้ายกัน ขึ้นอยู่กับว่าคุณต้องพิจารณามุมมอง มุมมองที่เป็นวัตถุ DatabaseMetaData.getTables() จาก JDBC หรือใช้เมตาโมดูล jOOQ

จากผลลัพธ์ของแบบสอบถามดังกล่าว มันค่อนข้างง่ายที่จะสร้างการแสดงโมเดลฐานข้อมูลของคุณในฝั่งไคลเอ็นต์ ไม่ว่าคุณจะใช้เทคโนโลยีใดบนไคลเอ็นต์ก็ตาม

  • หากคุณใช้ JDBC หรือ Spring คุณสามารถสร้างชุดค่าคงที่ของสตริงได้
  • หากคุณใช้ JPA คุณสามารถสร้างเอนทิตีได้เอง
  • หากคุณใช้ jOOQ คุณสามารถสร้าง jOOQ meta model ได้

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

ตอนนี้การเพิ่มฐานข้อมูลใด ๆ จะอัปเดตรหัสไคลเอนต์โดยอัตโนมัติ ลองนึกภาพตัวอย่าง:

ALTER TABLE book RENAME COLUMN title TO book_title;

คุณต้องการทำงานนี้สองครั้งหรือไม่? ไม่ว่าในกรณีใด เราเพียงแค่ยอมรับ DDL รันผ่านขั้นตอนการสร้างของคุณ และรับเอนทิตีที่อัปเดต:

@Entity
@Table(name = "book", indexes = {
 
  // Вы об этом задумывались?
  @Index(name = "i_book_title", columnList = "book_title")
})
class Book {
  @Id
  @GeneratedValue(strategy = IDENTITY)
  int id;
 
  @Column("book_title")
  String bookTitle;
}

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

ความจริงเท่านั้น

ไม่ว่าคุณจะใช้เทคโนโลยีใด มักจะมีโมเดลเดียวที่เป็นแหล่งความจริงเพียงแหล่งเดียวสำหรับระบบย่อยบางระบบ หรืออย่างน้อยที่สุดเราควรพยายามอย่างเต็มที่เพื่อสิ่งนี้และหลีกเลี่ยงความสับสนในองค์กรที่ซึ่ง "ความจริง" มีอยู่ทุกหนทุกแห่งและไม่มีที่ไหนเลยในคราวเดียว ทุกอย่างจะง่ายขึ้นมาก หากคุณเพียงแค่แลกเปลี่ยนไฟล์ XML กับระบบอื่น ให้ใช้ XSD ดูเมตาโมเดล INFORMATION_SCHEMA ของ jOOQ ในรูปแบบ XML:
https://www.jooq.org/xsd/jooq-meta-3.10.0.xsd

  • XSD เป็นที่เข้าใจกันดี
  • XSD ทำเครื่องหมายเนื้อหา XML ได้เป็นอย่างดีและอนุญาตให้มีการตรวจสอบในภาษาไคลเอ็นต์ทั้งหมด
  • XSD เป็นเวอร์ชันที่ดีและเข้ากันได้แบบย้อนกลับสูง
  • XSD สามารถแปลเป็นโค้ด Java โดยใช้ XJC

ข้อสุดท้ายมีความสำคัญ เมื่อสื่อสารกับระบบภายนอกโดยใช้ข้อความ XML เราต้องการแน่ใจว่าข้อความของเราถูกต้อง สิ่งนี้ทำได้ง่ายมากด้วย JAXB, XJC และ XSD คงเป็นเรื่องบ้ามากที่จะคิดว่าในแนวทางการออกแบบ Java-first ที่เราสร้างข้อความของเราเป็นออบเจกต์ Java ข้อความเหล่านั้นอาจถูกแสดงผลอย่างชาญฉลาดเป็น XML และส่งไปยังระบบอื่นเพื่อใช้งาน XML ที่สร้างขึ้นด้วยวิธีนี้จะมีคุณภาพต่ำมาก ไม่มีเอกสาร และพัฒนาได้ยาก หากมีข้อตกลงเกี่ยวกับระดับคุณภาพบริการ (SLA) บนอินเทอร์เฟซดังกล่าว เราจะทำข้อตกลงทันที

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

ฐานข้อมูล: เหมือนกัน

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

เมื่อการอัปเดตแหล่งที่มาเกิดขึ้น ไคลเอนต์ทั้งหมดจะต้องอัปเดตสำเนาของโมเดลด้วย ไคลเอนต์บางตัวอาจเขียนด้วยภาษาจาวาโดยใช้ jOOQ และ Hibernate หรือ JDBC (หรือทั้งสองอย่าง) ลูกค้ารายอื่นอาจเขียนด้วยภาษา Perl (ขอให้พวกเขาโชคดี) ส่วนลูกค้ารายอื่นอาจเขียนด้วยภาษา C# มันไม่สำคัญ โมเดลหลักอยู่ในฐานข้อมูล โมเดลที่สร้างโดย ORM มักจะมีคุณภาพต่ำ มีการจัดทำเป็นเอกสารไม่ดี และยากต่อการพัฒนา

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

อย่าเพิ่งขอบคุณฉันในภายหลัง

การอธิบาย

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

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

ข้อยกเว้น

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

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

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

ที่มา: will.com

เพิ่มความคิดเห็น