---
term: 'Modellazione dei dati (Pointer e Relation)'
seoTitle: 'Modellazione dei dati: relazioni, Pointer e Relation'
headline: 'Che cos''è la modellazione dei dati?'
slug: modellazione-dei-dati
category: database
shortDefinition: 'La modellazione dei dati è un processo che mappa entità, attributi e relazioni prima di decidere come un database le archivierà.'
relatedTerms:
  - database-schema
  - relational-queries-document-databases
  - n-plus-one-query-problem
  - auto-generated-database-apis
contrastsWith:
  - database-schema
faq:
  - question: 'Che cos''è la modellazione dei dati?'
    answer: 'Il processo che traduce l''informazione di un''applicazione – le sue entità, i loro attributi e le relazioni tra esse – in una progettazione che un database può archiviare. Attraversa di norma tre livelli di dettaglio: un modello concettuale che nomina le entità, un modello logico che aggiunge attributi e chiavi, e un modello fisico che si impegna su tabelle, colonne e indici in un motore preciso.'
  - question: 'Quali sono i tre tipi di modelli di dati?'
    answer: 'Concettuale, logico e fisico – la stessa progettazione a uno zoom crescente. Il concettuale risponde a "che cosa esiste e come si collega" per gli interlocutori di business. Il logico aggiunge attributi, tipi e chiavi restando indipendente dalla tecnologia. Il fisico si impegna su un motore reale: tabelle o collezioni, indici, vincoli. Ogni livello è il precedente più una serie di decisioni.'
  - question: 'Che cos''è una relazione uno-a-molti?'
    answer: 'Un record genitore collegato a molti figli, dove ogni figlio appartiene a esattamente un genitore – un cliente e i suoi ordini, un autore e i suoi libri. È la relazione più comune in qualunque schema. I database relazionali la implementano con una chiave esterna sul lato "molti"; i database documentali usano un array incorporato per insiemi piccoli e limitati, oppure un pointer verso il genitore per tutto il resto.'
  - question: 'Che cos''è una relazione molti-a-molti e perché richiede una tabella di collegamento?'
    answer: 'Entrambi i lati si collegano a molti elementi dell''altro – studenti e corsi, libri e generi. Una sola colonna di chiave esterna può puntare a una riga sola, quindi i database relazionali scompongono il molti-a-molti in due relazioni uno-a-molti attraverso una tabella di collegamento che contiene le due chiavi (e spesso attributi della relazione, come la data di iscrizione). I database documentali fanno a meno della tabella di collegamento: array di riferimenti, o un tipo relation dedicato, portano l''arco direttamente.'
  - question: 'Come si distingue uno-a-molti da molti-a-molti?'
    answer: 'Conviene porre la domanda di appartenenza nei due sensi. "Un autore può avere molti libri?" Sì. "Un libro può avere molti autori?" Se no – uno-a-molti, chiave esterna sul libro. Se sì – molti-a-molti, tabella di collegamento o relation. Sbagliare qui è l''errore di modellazione classico: un molti-a-molti modellato come uno-a-molti duplica righe oppure perde archi in silenzio.'
  - question: 'Che cos''è la cardinalità in un diagramma entità-relazione?'
    answer: 'Il numero di istanze di un''entità che possono collegarsi alle istanze di un''altra – uno-a-uno, uno-a-molti, molti-a-molti. I diagrammi la esprimono in una di tre notazioni: numeri e lettere sulle linee di collegamento, i simboli a zampa di gallina (crow''s foot) – una barra per uno, una forchetta a tre punte per molti – oppure intervalli di molteplicità come 1 e asterisco. Stessa semantica, convenzioni di disegno diverse.'
  - question: 'Come modellano le relazioni i database documentali, senza chiavi esterne?'
    answer: 'Con tre strumenti: l''incorporamento (annidare i dati collegati nel documento genitore – adatto quando si leggono insieme, appartengono a un solo genitore e sono limitati), i pointer o riferimenti (archiviare l''ID del documento collegato in un campo tipizzato – adatto a cicli di vita indipendenti e a cardinalità alta) e gli oggetti relation o array di ID per il molti-a-molti. La regola guida passa dalla normalizzazione ai pattern di accesso: ciò che si legge insieme deve vivere insieme.'
  - question: 'Quali sono gli errori di modellazione dei dati più comuni?'
    answer: 'Una top five stabile: modellare un molti-a-molti come uno-a-molti; dimenticare gli indici sui campi di chiave esterna e di pointer (ogni join e ogni lookup ne paga il prezzo); array incorporati senza limiti negli schemi documentali; la denormalizzazione prematura, prima che una query si sia rivelata lenta; e modellare dalle sole entità senza elencare le query – i pattern di accesso – che il modello deve servire.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'MongoDB — Embedding vs. References'
    url: 'https://www.mongodb.com/docs/manual/data-modeling/concepts/embedding-vs-references/'
  - name: 'Many-to-many data model (Wikipedia)'
    url: 'https://en.wikipedia.org/wiki/Many-to-many_(data_model)'
  - name: 'Entity–relationship model (Wikipedia)'
    url: 'https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model'
  - name: 'SDK relational data guide'
    url: 'https://docs.parseplatform.org/js/guide/#relational-data'
cta:
  title: 'Modella una volta, interroga da ogni parte'
  text: 'Su Back4app il modello è il backend: classi nella dashboard, Pointer per l''uno-a-molti, Relation per il molti-a-molti – e ogni arco che dichiari è subito interrogabile tramite API REST e GraphQL generate automaticamente e SDK con include() integrato.'
  linkText: 'Inizia gratis'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-10-09'
translationKey: data-modeling
---

**La modellazione dei dati è un processo che mappa entità, attributi e relazioni prima di decidere come un database le archivierà.** Le entità sono la parte facile – ogni prodotto conosce i propri utenti, ordini e post. Il mestiere sta nelle *relazioni*: quali record puntano a quali, quanti, e dove quell'arco vive fisicamente. Con gli archi giusti le query si scrivono da sole; con quelli sbagliati ogni feature combatte contro lo schema.

## Punti chiave

| Domanda | Risposta |
| --- | --- |
| I tre livelli | Concettuale (che cosa) → logico (struttura) → fisico (motore) |
| I tre archi | Uno-a-uno · uno-a-molti · molti-a-molti |
| Strumenti relazionali | Chiavi esterne; tabelle di collegamento per il molti-a-molti |
| Strumenti documentali | Incorporamento, Pointer (riferimenti), Relation/array di ID |
| La regola moderna | Modellare per i pattern di accesso – ciò che si legge insieme vive insieme |

## Le stesse relazioni, in entrambi i mondi

Prima il relazionale – la chiave esterna porta l'uno-a-molti, e il molti-a-molti deve scomporsi attraverso una tabella di collegamento:

```sql
-- 1:N – la chiave esterna vive sul lato "molti"
CREATE TABLE books (
  id        bigint PRIMARY KEY,
  title     text   NOT NULL,
  author_id bigint NOT NULL REFERENCES authors(id) ON DELETE CASCADE
);

-- M:N – nessuna FK da sola lo esprime; una tabella di collegamento tiene le due chiavi
CREATE TABLE book_genres (
  book_id  bigint REFERENCES books(id),
  genre_id bigint REFERENCES genres(id),
  added_at timestamptz DEFAULT now(),     -- le tabelle di collegamento portano attributi
  PRIMARY KEY (book_id, genre_id)         -- chiave composita: un arco, una volta sola
);
```

Lato documentale, stesso modello: l'arco uno-a-molti è un **Pointer** tipizzato, l'arco molti-a-molti è una **Relation** – nessuna tabella di collegamento da inventare, e l'arco si dichiara nel codice applicativo:

**JavaScript:**

```javascript
// JavaScript / Node.js — Back4app JS SDK
// One-to-many: a Pointer. Many-to-many: a Relation.
const author = await new Parse.Query('Author').get(authorId);

const book = new Parse.Object('Book');
book.set('title', 'Dune');
book.set('author', author);              // Pointer — typed one-to-many edge
await book.save();

const genres = book.relation('genres');  // Relation — many-to-many, unbounded
genres.add([sciFi, classics]);
await book.save();
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// One-to-many: a Pointer. Many-to-many: a Relation.
final book = ParseObject('Book')
  ..set('title', 'Dune')
  ..set('author', author.toPointer()); // Pointer — typed one-to-many edge
await book.save();

book.addRelation('genres', [sciFi, classics]); // Relation — many-to-many
await book.save();
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK
// One-to-many: a Pointer. Many-to-many: a Relation.
var book = Book()
book.title = "Dune"
book.author = try author.toPointer()   // Pointer — typed one-to-many edge
let saved = try await book.save()

let relation = try saved.relation("genres")
try await relation.add([sciFi, classics]).save() // Relation — many-to-many
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK
// One-to-many: a Pointer. Many-to-many: a Relation.
val book = ParseObject("Book").apply {
  put("title", "Dune")
  put("author", author)                 // Pointer — typed one-to-many edge
}
book.save()

val genres = book.getRelation<ParseObject>("genres") // Relation — many-to-many
genres.add(sciFi)
genres.add(classics)
book.save()
```

## Concettuale vs. logico vs. fisico: i tre livelli

```mermaid
flowchart LR
  accTitle: Modelli di dati concettuale, logico e fisico
  accDescr: Un modello concettuale nomina entità e relazioni per la discussione con il business; il modello logico aggiunge attributi, tipi e chiavi indipendentemente dalla tecnologia; il modello fisico si impegna su tabelle o collezioni, indici e vincoli in un motore di database preciso.
  C["Concettuale<br/>Autore —scrive→ Libro<br/>(che cosa esiste, per gli umani)"]
  L["Logico<br/>+ attributi, tipi, chiavi<br/>(struttura, indipendente dal motore)"]
  P["Fisico<br/>tabelle/collezioni, indici,<br/>vincoli in un solo motore"]
  C --> L --> P
```

| Dimensione | Concettuale | Logico | Fisico |
| --- | --- | --- | --- |
| Domanda a cui risponde | Che cosa esiste, come si collega | Quali campi, quali chiavi | Come è archiviato, quanto è rapido |
| Pubblico | Tutti | Chi progetta | Chi sviluppa + il motore |
| Contiene | Entità, relazioni | + attributi, tipi, cardinalità | + indici, vincoli, partizioni |
| Cambia quando | Cambia il business | Si affinano i requisiti | Cambiano il motore o la scala |

La disciplina che i livelli impongono: non si discute di indici finché il team non è d'accordo su che cosa sia un "ordine".

## Ogni relazione, ogni implementazione

La tabella che i risultati di ricerca non hanno mai costruito – ogni tipo di arco con la sua implementazione nei due mondi:

| Relazione | Esempio | Implementazione relazionale | Implementazione documentale |
| --- | --- | --- | --- |
| Uno-a-uno | Utente ↔ profilo | FK con UNIQUE, o la stessa riga | Incorporarlo – quasi sempre |
| Uno-a-pochi | Persona → indirizzi | Tabella figlia + FK | Array incorporato (limitato) |
| Uno-a-molti | Autore → libri | FK sul lato "molti" | **Pointer** sul lato "molti" |
| Uno-a-enormità | Dispositivo → eventi | FK + partizionamento | Pointer sul *figlio*; mai un array |
| Molti-a-molti | Libri ↔ generi | Tabella di collegamento, PK composita | **Relation** o array di pointer |
| Autoreferenziale | Dipendente → manager | FK verso la propria tabella | Pointer verso la propria classe |

La notazione della cardinalità, per leggere i diagrammi: la zampa di gallina (crow's foot) disegna una barra per "uno" e una forchetta a tre punte per "molti"; la [tradizione entità-relazione](https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_model) scrive 1 e N sulle linee; UML scrive molteplicità come `1` e `*`. Tre dialetti, una sola grammatica.

## Normalizzare, denormalizzare o incorporare?

La modellazione relazionale parte dalla **normalizzazione** – dividere i dati perché ogni fatto esista una volta sola, il che protegge le scritture dalle anomalie. La modellazione analitica e documentale la piega di proposito: la **denormalizzazione** duplica i campi più letti per eliminare i join, e l'**incorporamento** è il cugino documentale della denormalizzazione. La [checklist incorporare o referenziare](https://www.mongodb.com/docs/manual/data-modeling/concepts/embedding-vs-references/) si riduce a tre domande: letti insieme? posseduti da un solo genitore? di dimensione limitata? Tre sì, si incorpora; un solo no, si referenzia. E sopra tutto il resto, la regola moderna che le guide generaliste saltano: **elencare prima le query**. Un modello è corretto quando i pattern di accesso che deve servire costano poco – le entità da sole non bastano a dirlo.

## Casi d'uso tipici

- **Progettare un nuovo backend.** Il passaggio classico: nominare le entità, tracciare gli archi, scegliere le implementazioni secondo la tabella qui sopra – prima della prima riga di codice.
- **La tabella di collegamento con attributi.** Iscrizioni, adesioni, righe d'ordine – quando l'*arco stesso* porta dati (data, quantità, ruolo), la tabella di collegamento (o una classe d'arco con due pointer) diventa un'entità di prima classe.
- **Districare uno schema cresciuto nel tempo.** I sintomi rimandano agli archi: righe duplicate rivelano un molti-a-molti mal modellato; documenti obesi rivelano un incorporamento senza limiti.
- **Migrare da un mondo all'altro.** Passare dal relazionale al documentale significa decidere di nuovo, per ogni FK, tra incorporamento e pointer; la tabella qui sopra è il dizionario di traduzione.
- **Alimentare AI e analytics.** I data warehouse vogliono archi espliciti e stabili – il debito di modellazione riemerge il giorno in cui si tenta un export.

## Come modellare ogni arco? Matrice decisionale

| Scegliere… | Quando… | Attenzione a… |
| --- | --- | --- |
| Incorporare | Letti insieme, posseduti, limitati | La crescita: i "pochi" di oggi sono le migliaia di domani |
| Pointer / FK | Ciclo di vita indipendente, cardinalità alta | Indicizzarlo – ogni lookup e ogni include ne paga il prezzo |
| Relation / tabella di collegamento | Molti-a-molti, o l'arco porta dati | La direzione della query: sapere da quale lato si interrogherà |
| Duplicare (denormalizzare) | Un campo molto letto che attraversa un arco | Il fan-out degli aggiornamenti – la duplicazione è un debito con gli interessi |

## Limiti e trade-off

- **I modelli congelano le ipotesi.** Le decisioni di cardinalità ("un utente ha un solo indirizzo") diventano schema; costano poco sulla carta, molto dopo il lancio – conviene modellare per la cardinalità di domani.
- **Entrambi i mondi puniscono l'arco non indicizzato.** Colonne FK e campi pointer sono percorsi di join; dimenticarne gli indici è il bug di prestazioni silenzioso più comune.
- **L'incorporamento scambia l'integrità con la località.** Nessun motore garantisce che una copia incorporata resti coerente con la sua sorgente – da quel momento è compito della logica di aggiornamento.
- **Le tabelle di collegamento moltiplicano i join; le Relation li nascondono.** Ogni lettura molti-a-molti attraversa l'archiviazione degli archi – conviene mettere a budget il percorso della query, in qualunque dei due mondi.
- **Anche modellare per pattern di accesso ha un costo.** Ottimizzare per le query di oggi può sposare lo schema al prodotto di oggi; conviene tenere il modello concettuale come riferimento neutro.

## La modellazione dei dati su Back4app

Back4app è una piattaforma open-source di Backend as a Service (BaaS) che combina database gestito, API REST e GraphQL generate automaticamente, autenticazione, archiviazione di file e funzioni serverless con Cloud Code. Il suo vocabolario di modellazione è la colonna documentale delle tabelle qui sopra, promossa al primo rango: i **[Pointer](https://docs.parseplatform.org/js/guide/#relational-data)** sono archi uno-a-molti tipizzati, le **Relation** portano il molti-a-molti senza una tabella di collegamento costruita a mano, e gli array coprono i piccoli insiemi limitati. Ogni arco dichiarato è subito percorribile – `include()` segue i pointer in una sola richiesta, GraphQL annida le Relation in una sola query – e lo schema resta visibile e modificabile nella dashboard, così il modello fisico non esce mai dal campo visivo del team che ha progettato quello concettuale.
