0Pricing
TypeScript Academy · บทเรียน

ความสัมพันธ์และการรวมตารางด้วยชนิดข้อมูล

จำลองความสัมพันธ์เพื่อให้ผลลัพธ์จากการรวมตารางมีชนิดข้อมูลถูกต้อง

ความสัมพันธ์และการรวมตารางด้วยชนิดข้อมูล เป็นบทเรียน TypeScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน TypeScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน

ความสัมพันธ์ที่มีชนิดข้อมูลและผลลัพธ์แบบซ้อน

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

การประกาศความสัมพันธ์

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

import { relations } from "drizzle-orm";

export const usersRelations = relations(users, ({ many }) => ({
  posts: many(posts),
}));

export const postsRelations = relations(posts, ({ one }) => ({
  author: one(users, {
    fields: [posts.authorId],
    references: [users.id],
  }),
}));

คิวรีเชิงความสัมพันธ์

ส่วนติดต่อคิวรีช่วยให้คุณขอแถวที่เกี่ยวข้องด้วย with ผลลัพธ์จะซ้อนข้อมูลที่เกี่ยวข้องไว้ใต้ชื่อความสัมพันธ์

const result = await db.query.users.findMany({
  with: { posts: true },
});
// result: (User & { posts: Post[] })[]

one เทียบกับหลายรายการกำหนดรูปร่างของชนิดข้อมูล

ความสัมพันธ์แบบ many ให้ผลเป็นอาร์เรย์ ส่วนความสัมพันธ์แบบ one ให้ผลเป็นออบเจ็กต์เดียว (หรือค่าว่าง) ชนิดข้อมูลที่ซ้อนอยู่จะตรงกับจำนวนสมาชิกที่คุณประกาศ

const r = await db.query.posts.findMany({
  with: { author: true },
});
// r: (Post & { author: User })[]   // author is a single object

การเลือกคอลัมน์ภายในความสัมพันธ์

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

const r = await db.query.users.findMany({
  columns: { id: true, name: true },
  with: {
    posts: { columns: { title: true } },
  },
});
// r: { id: number; name: string; posts: { title: string }[] }[]

การเชื่อมตารางด้วยคอลัมน์ที่มีชนิดข้อมูลด้วยตนเอง

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

const rows = await db
  .select({ author: users.name, title: posts.title })
  .from(posts)
  .innerJoin(users, eq(users.id, posts.authorId));
// rows: { author: string; title: string }[]

การเชื่อมแบบ LEFT JOIN นำความเป็นค่าว่างเข้ามา

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

const rows = await db
  .select({ name: users.name, title: posts.title })
  .from(users)
  .leftJoin(posts, eq(posts.authorId, users.id));
// rows: { name: string; title: string | null }[]

ผลลัพธ์แบบซ้อนเทียบกับแบบแบน

คิวรีเชิงความสัมพันธ์ (findMany + with) ให้ผลเป็นออบเจ็กต์แบบซ้อน ส่วนการเชื่อมตารางด้วยตนเองให้ผลเป็นแถวแบบแบน เลือกแบบซ้อนเมื่อต้องการกราฟออบเจ็กต์ และเลือกแบบแบนเมื่อต้องการการฉายข้อมูลแบบตาราง

การกำหนดชนิดของการซ้อนทำงานอย่างไร

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

type WithPosts = User & { posts: Post[] };
// "many" -> Post[], "one" -> User (or User | null for optional)

ความสัมพันธ์ที่ซ้อนกันหลายระดับ

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

await db.query.users.findMany({
  with: { posts: { with: { comments: true } } },
});
// User & { posts: (Post & { comments: Comment[] })[] }

เหตุใดเรื่องนี้จึงสำคัญ

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

ตรวจสอบความเข้าใจอย่างรวดเร็ว

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

สรุป

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

คำถามที่พบบ่อย

บทเรียน “ความสัมพันธ์และการรวมตารางด้วยชนิดข้อมูล” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ความสัมพันธ์และการรวมตารางด้วยชนิดข้อมูล” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส TypeScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ความสัมพันธ์และการรวมตารางด้วยชนิดข้อมูล”

จำลองความสัมพันธ์เพื่อให้ผลลัพธ์จากการรวมตารางมีชนิดข้อมูลถูกต้อง คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน TypeScript Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน TypeScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “ความสัมพันธ์และการรวมตารางด้วยชนิดข้อมูล” ใช้เวลานานแค่ไหน

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

ฉันเขียนและรันโค้ดในบทเรียน TypeScript Academy นี้ได้ไหม

ได้ บทเรียน TypeScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การแมปจากสคีมาเป็นชนิดข้อมูล
  2. การสร้างการสืบค้นที่ปลอดภัยด้านชนิดข้อมูล
  3. การอนุมานโครงสร้างผลลัพธ์การสืบค้น
  4. ความสัมพันธ์และการรวมตารางด้วยชนิดข้อมูล
← กลับไปที่ TypeScript Academy