หน้านี้ได้รับการแปลโดย Cloud Translation API
Switch to English

จัดโครงสร้างฐานข้อมูลของคุณ

ก่อนที่คุณจะเริ่ม

ก่อนที่คุณจะสามารถใช้ ฐานข้อมูลแบบเรียลไทม์ คุณต้อง:

  • ลงทะเบียนโครงการ Unity ของคุณและกำหนดค่าให้ใช้ Firebase

    • หากโครงการ Unity ของคุณใช้ Firebase อยู่แล้วแสดงว่ามีการลงทะเบียนและกำหนดค่าสำหรับ Firebase แล้ว

    • หากคุณไม่มีโปรเจ็กต์ Unity คุณสามารถดาวน์โหลด แอปตัวอย่าง ได้

  • เพิ่ม Firebase Unity SDK (โดยเฉพาะ FirebaseDatabase.unitypackage ) ในโครงการ Unity ของคุณ

โปรดทราบว่าการเพิ่ม Firebase ในโปรเจ็กต์ Unity นั้นเกี่ยวข้องกับงานทั้งใน คอนโซล Firebase และในโปรเจ็กต์ Unity ที่เปิดอยู่ (เช่นคุณดาวน์โหลดไฟล์การกำหนดค่า Firebase จากคอนโซลจากนั้นย้ายไฟล์เหล่านั้นไปยังโปรเจ็กต์ Unity ของคุณ)

การจัดโครงสร้างข้อมูล

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

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

ข้อมูลมีโครงสร้างอย่างไร: เป็นโครงสร้าง JSON

ข้อมูล Firebase Realtime Database ทั้งหมดจะจัดเก็บเป็นออบเจ็กต์ JSON คุณสามารถคิดว่าฐานข้อมูลเป็นโครงสร้าง JSON ที่โฮสต์บนคลาวด์ แตกต่างจากฐานข้อมูล SQL ไม่มีตารางหรือระเบียน เมื่อคุณเพิ่มข้อมูลลงในแผนผัง JSON ข้อมูลจะกลายเป็นโหนดในโครงสร้าง JSON ที่มีอยู่พร้อมคีย์ที่เกี่ยวข้อง คุณสามารถระบุคีย์ของคุณเองเช่น ID ผู้ใช้หรือชื่อความหมายหรือสามารถระบุให้คุณได้โดยใช้วิธีการ Push()

หากคุณสร้างคีย์ของคุณเองคีย์จะต้องเข้ารหัส UTF-8 สามารถมีขนาดได้สูงสุด 768 ไบต์และไม่สามารถมี . , $ , # , [ , ] , / หรืออักขระควบคุม ASCII 0-31 หรือ 127 คุณไม่สามารถใช้อักขระควบคุม ASCII ในค่าเองได้เช่นกัน

ตัวอย่างเช่นพิจารณาแอปพลิเคชันแชทที่อนุญาตให้ผู้ใช้จัดเก็บโปรไฟล์พื้นฐานและรายชื่อผู้ติดต่อ โปรไฟล์ผู้ใช้ทั่วไปจะอยู่ที่พา ธ เช่น /users/$uid ผู้ใช้ alovelace อาจมีรายการฐานข้อมูลที่มีลักษณะดังนี้:

{
  "users": {
    "alovelace": {
      "name": "Ada Lovelace",
      "contacts": { "ghopper": true },
    },
    "ghopper": { ... },
    "eclarke": { ... }
  }
}

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

แนวทางปฏิบัติที่ดีที่สุดสำหรับโครงสร้างข้อมูล

หลีกเลี่ยงการซ้อนข้อมูล

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

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

{
  // This is a poorly nested data architecture, because iterating the children
  // of the "chats" node to get a list of conversation titles requires
  // potentially downloading hundreds of megabytes of messages
  "chats": {
    "one": {
      "title": "Historical Tech Pioneers",
      "messages": {
        "m1": { "sender": "ghopper", "message": "Relay malfunction found. Cause: moth." },
        "m2": { ... },
        // a very long list of messages
      }
    },
    "two": { ... }
  }
}

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

แบนโครงสร้างข้อมูล

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

{
  // Chats contains only meta info about each conversation
  // stored under the chats's unique ID
  "chats": {
    "one": {
      "title": "Historical Tech Pioneers",
      "lastMessage": "ghopper: Relay malfunction found. Cause: moth.",
      "timestamp": 1459361875666
    },
    "two": { ... },
    "three": { ... }
  },

  // Conversation members are easily accessible
  // and stored by chat conversation ID
  "members": {
    // we'll talk about indices like this below
    "one": {
      "ghopper": true,
      "alovelace": true,
      "eclarke": true
    },
    "two": { ... },
    "three": { ... }
  },

  // Messages are separate from data we may want to iterate quickly
  // but still easily paginated and queried, and organized by chat
  // conversation ID
  "messages": {
    "one": {
      "m1": {
        "name": "eclarke",
        "message": "The relay seems to be malfunctioning.",
        "timestamp": 1459361875337
      },
      "m2": { ... },
      "m3": { ... }
    },
    "two": { ... },
    "three": { ... }
  }
}

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

สร้างข้อมูลที่ปรับขนาด

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

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

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

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

// An index to track Ada's memberships
{
  "users": {
    "alovelace": {
      "name": "Ada Lovelace",
      // Index Ada's groups in her profile
      "groups": {
         // the value here doesn't matter, just that the key exists
         "techpioneers": true,
         "womentechmakers": true
      }
    },
    ...
  },
  "groups": {
    "techpioneers": {
      "name": "Historical Tech Pioneers",
      "members": {
        "alovelace": true,
        "ghopper": true,
        "eclarke": true
      }
    },
    ...
  }
}

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

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

วิธีนี้การกลับข้อมูลโดยแสดง ID เป็นคีย์และตั้งค่าเป็น true ทำให้การตรวจสอบคีย์ทำได้ง่ายเพียงแค่อ่าน /users/$uid/groups/$group_id และตรวจสอบว่าเป็น null หรือไม่ ดัชนีเร็วกว่าและมีประสิทธิภาพมากกว่าการค้นหาหรือสแกนข้อมูล

ขั้นตอนถัดไป