Google cam kết thúc đẩy bình đẳng chủng tộc đối với cộng đồng đen. Xem cách.
Trang này được dịch bởi Cloud Translation API.
Switch to English

Cấu trúc dữ liệu với cơ sở dữ liệu căn cứ hỏa lực thời gian thực cho C ++

cấu trúc dữ liệu

Hướng dẫn này bao gồm một số khái niệm quan trọng trong kiến ​​trúc dữ liệu và thông lệ tốt nhất cho cấu trúc dữ liệu JSON trong Cơ sở dữ liệu căn cứ hỏa lực Realtime của bạn.

Xây dựng một cơ sở dữ liệu có cấu trúc đúng cách đòi hỏi khá nhiều sự suy tính trước. Quan trọng nhất, bạn cần phải kế hoạch về cách dữ liệu sẽ được lưu lại và sau đó lấy ra để làm cho quá trình dễ dàng như có thể.

Làm thế nào dữ liệu có cấu trúc: nó là một cây JSON

Tất cả các căn cứ hỏa lực Realtime Cơ sở dữ liệu dữ liệu được lưu giữ như JSON đối tượng. Bạn có thể nghĩ đến cơ sở dữ liệu như là một cây JSON đám mây lưu trữ. Không giống như một cơ sở dữ liệu SQL, không có bảng hoặc hồ sơ. Khi bạn thêm dữ liệu vào cây JSON, nó trở thành một nút trong cấu trúc JSON hiện với một chìa khóa có liên quan. Bạn có thể cung cấp chìa khóa riêng của bạn, chẳng hạn như ID người dùng hoặc tên ngữ nghĩa, hoặc họ có thể được cung cấp cho bạn cách sử dụng Push() phương pháp.

Nếu bạn tạo các phím riêng của bạn, họ phải UTF-8 mã hóa, có thể tối đa là 768 byte, và không thể chứa . , $ , # , [ , ] , / , Hay ký tự điều khiển ASCII 0-31 hoặc 127. Bạn không thể sử dụng ký tự điều khiển ASCII trong các giá trị bản thân, một trong hai.

Ví dụ, hãy xem xét một ứng dụng chat cho phép người dùng lưu trữ một danh sách hồ sơ và liên hệ cơ bản. Một lý lịch thành viên tiêu biểu tọa lạc tại một con đường, chẳng hạn như /users/$uid . Người dùng alovelace có thể có một mục cơ sở dữ liệu mà trông giống như sau:

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

Mặc dù cơ sở dữ liệu sử dụng một cây JSON, dữ liệu được lưu trữ trong cơ sở dữ liệu có thể được biểu diễn như các loại có nguồn gốc chắc chắn rằng tương ứng với loại JSON sẵn để giúp bạn viết mã dễ bảo trì hơn.

Thực hành tốt nhất cho cấu trúc dữ liệu

Tránh dữ liệu làm tổ

Bởi vì cơ sở dữ liệu căn cứ hỏa lực Realtime cho phép dữ liệu làm tổ lên đến 32 cấp độ sâu, bạn có thể bị cám dỗ để nghĩ rằng đây sẽ là cấu trúc mặc định. Tuy nhiên, khi bạn lấy dữ liệu tại một vị trí trong cơ sở dữ liệu của bạn, bạn cũng lấy tất cả các nút con của nó. Ngoài ra, khi bạn cấp một ai đó đọc hoặc ghi vào tại một nút trong cơ sở dữ liệu của bạn, bạn cũng cấp cho họ quyền truy cập vào tất cả dữ liệu dưới nút đó. Vì vậy, trong thực tế, nó là tốt nhất để giữ cấu trúc dữ liệu của bạn như là bằng phẳng càng tốt.

Đối với một ví dụ về lý do tại sao dữ liệu lồng nhau là xấu, xem xét cấu trúc nhân-lồng nhau như sau:

{
  // 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": { ... }
  }
}

Với thiết kế lồng nhau này, lặp lại thông qua các dữ liệu trở nên có vấn đề. Ví dụ, liệt kê các tiêu đề của cuộc hội thoại trò chuyện đòi hỏi toàn bộ chats cây, bao gồm tất cả các thành viên và tin nhắn, để được tải về cho khách hàng.

cấu trúc dữ liệu Flatten

Nếu dữ liệu là thay vì chia thành những con đường riêng biệt, hay còn gọi là denormalization, nó có thể được tải một cách hiệu quả trong các cuộc gọi riêng biệt, vì nó là cần thiết. Xem xét cấu trúc phẳng này:

{
  // 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": { ... }
  }
}

Đó là bây giờ có thể lặp qua danh sách các phòng bằng cách tải về chỉ có một vài byte cho mỗi cuộc trò chuyện, nhanh chóng lấy siêu dữ liệu cho danh sách hoặc hiển thị các phòng trong một giao diện người dùng. Tin nhắn có thể được lấy riêng và hiển thị như họ đến, cho phép giao diện người dùng ở lại đáp ứng và nhanh chóng.

Tạo dữ liệu quy mô

Khi xây dựng các ứng dụng, nó thường tốt hơn để tải về một tập hợp con của một danh sách. Điều này đặc biệt phổ biến nếu danh sách chứa hàng ngàn hồ sơ. Khi mối quan hệ này là tĩnh và một chiều, bạn có thể chỉ đơn giản là tổ đối tượng trẻ em dưới phụ huynh.

Đôi khi, mối quan hệ này là năng động hơn, hoặc nó có thể là cần thiết để denormalize dữ liệu này. Nhiều lần bạn có thể denormalize dữ liệu bằng cách sử dụng một truy vấn để lấy một tập hợp con của dữ liệu, như đã thảo luận trong lấy dữ liệu .

Nhưng ngay cả điều này có thể không đủ. Xem xét, ví dụ, một mối quan hệ hai chiều giữa người dùng và nhóm. Người dùng có thể thuộc về một nhóm, và nhóm bao gồm một danh sách người dùng. Khi nói đến thời gian để quyết định nhóm người dùng thuộc về, mọi thứ bị phức tạp.

Điều cần thiết là một cách thanh lịch để liệt kê các nhóm người dùng thuộc về và chỉ lấy dữ liệu cho những nhóm. Một chỉ số của nhóm có thể giúp rất nhiều ở đây:

// 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
      }
    },
    ...
  }
}

Bạn có thể nhận thấy rằng đây là bản sao một số dữ liệu bằng cách lưu trữ các mối quan hệ dưới kỷ lục cả của Ada và dưới nhóm. Bây giờ alovelace được lập chỉ mục theo một nhóm, và techpioneers được liệt kê trong hồ sơ của Ada. Vì vậy, để xóa Ada khỏi nhóm, nó phải được cập nhật ở hai nơi.

Đây là một dự phòng cần thiết cho mối quan hệ hai chiều. Nó cho phép bạn nhanh chóng và hiệu quả lấy thành viên Ada, ngay cả khi danh sách người dùng hoặc nhóm quy mô vào hàng triệu hoặc khi Realtime quy tắc bảo mật cơ sở dữ liệu ngăn chặn truy cập đến một số các hồ sơ.

Cách tiếp cận này, đảo ngược các dữ liệu bằng cách liệt kê các ID như phím và thiết lập giá trị là true, làm kiểm tra cho một phím đơn giản như đọc /users/$uid/groups/$group_id và kiểm tra nếu nó là null . Chỉ số này là nhanh hơn và một thỏa thuận tốt hơn hiệu quả hơn so với truy vấn hoặc quét dữ liệu.

Bước tiếp theo