---
title: Data modeling
nav: Data modeling
group: Build your app
updated: 2026-11-13
description: Design your SashiDo app's classes. Field types, pointers, relations and arrays, when to denormalize, counters, and modeling for permissions and fast queries.
keywords: parse server data modeling, parse pointer vs relation, parse schema design, parse server relations, mongodb schema parse, parse field types
---

Each Parse class is a MongoDB collection; each object, a document. Good models come from the screens you'll build: model for how you read the data, not only for how you store it.

## Field types

| Type | For |
|---|---|
| String, Number, Boolean, Date | Plain values |
| Object, Array | Nested JSON: small, read together with the object |
| Pointer | A reference to one other object |
| Relation | A many-to-many link, stored apart from the object |
| File | An uploaded [file](/en/docs/developers/files) |
| GeoPoint | A location, for "near me" queries |
| ACL | Who may read and write the object |

Define the schema in **Core › Browser** (or with the API) rather than letting clients create fields, and keep **Add field** off for clients ([Secure your app](/en/docs/developers/security)).

## Linking objects

| | Pointer | Array of pointers | Relation |
|---|---|---|---|
| Shape | One-to-one, many-to-one | One-to-few | Many-to-many, many-to-lots |
| Example | A comment's `post` | A post's 3 `tags` | A user's `followers` |
| Read with the object | `include('post')`, same request | `include('tags')` | A separate query |
| Size | 1 | Keep it small (tens) | Unbounded |

```javascript
const comment = new Parse.Object('Comment', { text: 'Nice!', post });
await comment.save();

// comments of a post, with the post itself in one request
const comments = await new Parse.Query('Comment')
  .equalTo('post', post)
  .include('post')
  .descending('createdAt')
  .limit(20)
  .find();
```

Prefer a pointer from the "many" side (the comment points to its post) over an array on the "one" side: it grows without limit, and it queries and indexes well.

## Denormalize what you show often

Reading related objects on every screen costs requests. Copy what you need where you read it:

- a `commentCount` on the post, kept up to date in an `afterSave` of `Comment`;
- the author's name next to the author pointer, if lists show it;
- the latest message's text on the conversation.

Copies get stale, so update them in [cloud code](/en/docs/developers/cloud-code#triggers), not from clients.

## Model for permissions

Permissions apply per class and per object, so split data by who may see it:

- public profile fields in a `Profile` class readable by everyone; email and settings stay in `_User`, readable only by the user;
- one object per owner, with the owner's ACL, rather than a shared object that everyone updates.

## Model for speed

- Query by fields you can [index](/en/docs/developers/performance#queries), and sort by them.
- Avoid huge objects: big arrays and nested objects are read and rewritten in full on every save.
- Keep large data (images, documents, exports) in [files](/en/docs/developers/files), not in fields.

Parse's [JavaScript guide](https://docs.parseplatform.org/js/guide/#relations) covers every relation API in detail.
