আপনার ডাটাবেস গঠন

আপনি শুরু করার আগে

আপনি Realtime Database ব্যবহার করার আগে, আপনাকে করতে হবে:

  • আপনার ইউনিটি প্রজেক্ট নিবন্ধন করুন এবং Firebase ব্যবহার করতে কনফিগার করুন।

    • আপনার ইউনিটি প্রোজেক্ট যদি আগে থেকেই Firebase ব্যবহার করে, তাহলে এটি ইতিমধ্যেই Firebase-এর জন্য নিবন্ধিত এবং কনফিগার করা আছে।

    • আপনার যদি ইউনিটি প্রজেক্ট না থাকে, আপনি একটি নমুনা অ্যাপ ডাউনলোড করতে পারেন।

  • আপনার ইউনিটি প্রকল্পে Firebase Unity SDK (বিশেষ করে, FirebaseDatabase.unitypackage ) যোগ করুন।

মনে রাখবেন যে আপনার ইউনিটি প্রোজেক্টে ফায়ারবেস যোগ করার জন্য Firebase কনসোল এবং আপনার ওপেন ইউনিটি প্রোজেক্ট উভয়েরই কাজ জড়িত থাকে (উদাহরণস্বরূপ, আপনি কনসোল থেকে Firebase কনফিগার ফাইলগুলি ডাউনলোড করেন, তারপর সেগুলিকে আপনার ইউনিটি প্রোজেক্টে নিয়ে যান)।

স্ট্রাকচারিং ডেটা

এই নির্দেশিকাটি ডেটা আর্কিটেকচারের কিছু মূল ধারণা এবং আপনার Firebase Realtime Database JSON ডেটা গঠনের জন্য সর্বোত্তম অনুশীলনগুলিকে কভার করে৷

একটি সঠিকভাবে স্ট্রাকচার্ড ডাটাবেস তৈরি করতে বেশ কিছুটা পূর্বচিন্তা প্রয়োজন। সবচেয়ে গুরুত্বপূর্ণ, কীভাবে ডেটা সংরক্ষণ করা হবে এবং সেই প্রক্রিয়াটিকে যতটা সম্ভব সহজ করার জন্য পরবর্তীতে পুনরুদ্ধার করা হবে তার জন্য আপনাকে পরিকল্পনা করতে হবে।

ডেটা কীভাবে গঠন করা হয়: এটি একটি JSON গাছ

সমস্ত Firebase Realtime Database ডেটা JSON অবজেক্ট হিসাবে সংরক্ষণ করা হয়। আপনি ডাটাবেসটিকে একটি ক্লাউড-হোস্টেড JSON গাছ হিসাবে ভাবতে পারেন। একটি SQL ডাটাবেসের বিপরীতে, কোন টেবিল বা রেকর্ড নেই। আপনি যখন JSON ট্রিতে ডেটা যোগ করেন, তখন এটি একটি যুক্ত কী সহ বিদ্যমান JSON কাঠামোর একটি নোডে পরিণত হয়। আপনি আপনার নিজস্ব কীগুলি প্রদান করতে পারেন, যেমন ব্যবহারকারী আইডি বা শব্দার্থিক নাম, অথবা সেগুলি আপনার জন্য 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 Realtime Database 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 ট্রি ক্লায়েন্টের কাছে ডাউনলোড করা প্রয়োজন।

ডেটা স্ট্রাকচার সমতল করুন

যদি ডেটা পরিবর্তে আলাদা পাথগুলিতে বিভক্ত করা হয়, যাকে ডিনরমালাইজেশনও বলা হয়, তবে এটি প্রয়োজন অনুযায়ী আলাদা কলে দক্ষতার সাথে ডাউনলোড করা যেতে পারে। এই সমতল কাঠামো বিবেচনা করুন:

{
  // 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 এর সদস্যপদগুলি আনতে দেয়, এমনকি যখন ব্যবহারকারী বা গোষ্ঠীর তালিকা লক্ষাধিক হয়ে যায় বা যখন Realtime Database সুরক্ষা নিয়ম কিছু রেকর্ডে অ্যাক্সেস বাধা দেয়।

এই পদ্ধতিটি, আইডিগুলিকে কী হিসাবে তালিকাভুক্ত করে এবং মানটিকে সত্যে সেট করে ডেটা উল্টে দেয়, একটি কী পরীক্ষা করাকে /users/$uid/groups/$group_id পড়ার মতো সহজ করে দেয় এবং এটি null কিনা তা পরীক্ষা করে। তথ্য অনুসন্ধান বা স্ক্যান করার চেয়ে সূচকটি দ্রুত এবং একটি ভাল চুক্তি আরও দক্ষ।

পরবর্তী পদক্ষেপ