Domanda

Object-relational mapping è stato ben discusso, tra cui qui.Ho esperienza con un paio di approcci e le insidie e i compromessi.Vero risoluzione sembra che non richiede modifiche alle OO o relazionale stessi modelli.

Se si utilizza un linguaggio funzionale, fa lo stesso problema si presenti?Mi sembra che questi due paradigmi dovrebbe combaciare meglio di OO e RDBMS.L'idea di pensare in set in un RDBMS sembra la maglia con il parallelismo automatico che approcci funzionali sembrano promettere.

Qualcuno ha qualche interessanti opinioni o riflessioni?Qual è la situazione nel settore?

È stato utile?

Soluzione

I duri problemi di estendere il database relazionale sono estese operazioni, il tipo di dati non corrispondenti query automatici di traduzione e cose del genere N+1 Selezionare che sono i problemi fondamentali di lasciare il sistema relazionale e-a mio parere-non cambia cambiando la ricezione di paradigma di programmazione.

Altri suggerimenti

Qual è lo scopo di un ORM?

Lo scopo principale dell'utilizzo di un ORM è il ponte tra la rete modello (oggetto di orientamento, grafici, etc.) e il modello relazionale.E la differenza principale tra i due modelli è sorprendentemente semplice.Ma se i genitori indicano i bambini (in rete modello), o figli, punto di genitori (modello relazionale).

Con questa semplicità in mente, credo non c'è nessuna tale cosa come un "impedance mismatch" tra i due modelli.I problemi che la gente di solito eseguire in sono puramente attuazione specifiche, e dovrebbe essere risolvibile, se non ci fosse di meglio protocolli di trasferimento dei dati tra client e server.

Come si può SQL affrontare i problemi che abbiamo con Orm?

In particolare, il terzo manifesto cerca di affrontare le carenze del linguaggio SQL e algebra relazionale, consentendo nidificati collezioni, che sono stati realizzati in una varietà di database, tra cui:

  • Oracle (probabilmente il più sofisticato di attuazione)
  • PostgreSQL (in qualche misura)
  • Informix
  • SQL Server, MySQL, etc.(attraverso "emulazione" via XML o JSON)

A mio parere, se tutti i database implementato lo standard SQL MULTISET() operatore (es.Oracle fa), la gente sarebbe più utilizzare Orm per la mappatura (forse ancora per l'oggetto grafico persistenza), perché essi potrebbero concretizzarsi nidificati raccolte direttamente dall'interno del database, ad esempioquesta query:

SELECT actor_id, first_name, last_name,
  MULTISET (
    SELECT film_id, title
    FROM film AS f
    JOIN film_actor AS fa USING (film_id)
    WHERE fa.actor_id = a.actor_id
  ) AS films
FROM actor AS a

Sarebbe resa a tutti gli attori e i loro film annidamento di raccolta, piuttosto che un denormalised join (in cui gli attori sono ripetuti per ogni film).

Paradigma funzionale al lato client

La questione se un linguaggio di programmazione funzionale al lato client è più adatto per le interazioni di database è davvero ortogonali.Orm aiutare con oggetto grafico persistenza, quindi, se il vostro client side modello è riportato un grafico, e si vuole essere un grafico, è necessario un ORM, a prescindere se si sta modificando quel grafico utilizzando un linguaggio di programmazione funzionale.

Tuttavia, poiché oggetto di orientamento è meno idiomatiche in linguaggi di programmazione funzionale, si hanno meno probabilità di calzascarpe ogni elemento di dati in un oggetto.Per qualcuno la scrittura SQL, progettazione arbitrario tuple è molto naturale.SQL abbraccia strutturali di battitura.Ogni query SQL definisce il proprio tipo di riga senza dover precedentemente assegnato un nome.Che risuona molto bene funzionali e programmatori, soprattutto quando il tipo di inferenza è sofisticato, nel caso in cui non si pensa mai di mappatura SQL risultato di alcuni definito in precedenza oggetto / classe.

Un esempio in Java utilizzando jOOQ da questo post del blog potrebbe essere:

// Higher order, SQL query producing function:
public static ResultQuery<Record2<String, String>> actors(Function<Actor, Condition> p) {
    return ctx.select(ACTOR.FIRST_NAME, ACTOR.LAST_NAME)
              .from(ACTOR)
              .where(p.apply(ACTOR)));
}

Questo approccio porta ad una migliore composizionalità di istruzioni SQL che se il linguaggio SQL sono stati estratti da alcuni ORM o se SQL naturale "stringa" natura sono stati utilizzati.La funzione di cui sopra può ora essere utilizzato ad es.come questa:

// Get only actors whose first name starts with "A"
for (Record rec : actors(a -> a.FIRST_NAME.like("A%")))
    System.out.println(rec);

FRM astrazione su SQL

Alcune Imprese tenta di astratto sul linguaggio SQL, di solito per questi motivi:

  • Essi sostengono SQL non è componibile abbastanza (jOOQ smentisce tutto questo, è solo molto difficile da ottenere).
  • Essi sostengono che le API gli utenti sono più abituati a "nativo" collezione di Api, quindi ad es. JOIN è tradotto flatMap() e WHERE è tradotto filter(), etc.

Per rispondere alla tua domanda

FRM non è più "facile" di ORM, risolve un problema diverso.Infatti, FRM in realtà non risolvere alcun problema, perché SQL, essendo un linguaggio di programmazione dichiarativo (che non è poi così diverso dalla programmazione funzionale), è una partita molto buona per altre funzionale client, linguaggi di programmazione.Così, se una cosa, un FRM semplicemente colma il divario tra SQL, esterni, DSL, e la vostra lingua del client.

(Io lavoro per l'azienda dietro jOOQ, in modo che questa risposta è parziale)

Che dipende dalle tue esigenze

  1. Se si desidera concentrarsi sui dati-strutture di usare un ORM come JPA/Hibernate
  2. Se si desidera far luce sui trattamenti, dare un'occhiata a FRM librerie:QueryDSL o Jooq
  3. Se avete bisogno di regolare la vostra richieste SQL al database specifici, utilizzare JDBC e SQL nativo richieste

La forza dei vari "Relational Mapping" tecnologie è la portabilità:sei sicuro che la tua applicazione verrà eseguita sulla maggior parte dell'ACIDO database.In caso contrario, si farà fronte con differenze tra i vari dialetti SQL quando si scrivere manualmente le richieste SQL .

Naturalmente si può limitare se stessi per l'SQL92 standard (e quindi fare un po di Programmazione Funzionale) o è possibile riutilizzare alcuni concetti di functionnal di programmazione con framework ORM

L'ORM strenghs sono costruiti su un oggetto di sessione che può agire come un collo di bottiglia:

  1. gestisce il ciclo di vita degli oggetti, come lungo come sottostante transazione di database è in esecuzione.
  2. mantiene un one-to-one mapping tra gli oggetti java e database righe (e l'uso di una cache interna per evitare di duplicare gli oggetti).
  3. rileva automaticamente associazione aggiornamenti e gli orfani oggetti da eliminare
  4. gestisce concurrenty problemi con ottimista o pessimista di blocco.

Tuttavia, i suoi punti di forza sono anche i suoi punti deboli:

  1. La sessione deve essere in grado di confrontare oggetti quindi è necessario implementa equals/metodi hashCode.Ma gli Oggetti di uguaglianza deve essere radicato sul "Chiavi Business" e non l'id di database (nuovi oggetti transitori non hanno ID del database!).Tuttavia, alcuni reified concetti non hanno alcuna uguaglianza (un'operazione, per esempio).Una comune soluzione si basa sul Guid che tendono a sconvolgere gli amministratori di database.

  2. La sessione deve spia rapporto modifiche, ma le sue regole di mapping di spingere l'uso di collezioni inadatto per il business algoritmi.A volte che volete utilizzare un HashMap ma l'ORM richiederà la chiave per essere un altro "Ricco di Dominio Oggetto" invece di un'altra luce...Quindi è necessario implementare oggetto l'uguaglianza sul dominio ricco di oggetto che agisce come una chiave...Ma non è possibile, perché questo oggetto non ha riscontro nel mondo del lavoro.Così si ritorna a una semplice elenco che devi iterare (problemi di prestazioni e risultato).

  3. L'ORM API sono a volte inadatto per l'uso nel mondo reale.Per esempio, il mondo reale di applicazioni web tenta di imporre sessione di isolamento con l'aggiunta di alcune clausole "WHERE" quando si recuperare i dati...Quindi la "Sessione.get(id)" non è sufficiente ed è necessario attivare al più complesso DSL (HSQL, Criteri di API) o tornare al nativo di SQL

  4. Gli oggetti di database in conflitto con altri oggetti dedicati ad altri contesti (come OXM quadri = Oggetto/Mapping XML).Per esempio, se il RESTO di servizi utilizzo di jackson biblioteca per serializzare un oggetto di business.Ma questo Jackson esattamente mappe per una Sospensione di Uno.Quindi, è possibile unire entrambi e un forte accoppiamento tra le API e il database viene visualizzato O è necessario implementare una traduzione e tutto il codice è stato salvato dall'ORM è perso lì...

Dall'altro lato, FRM è un trade-off tra "Object Relational Mapping" (ORM) e nativo di query SQL (con JDBC)

Il modo migliore per spiegare le differenze tra FRM e ORM consiste nell'adozione di un approccio DDD.

  • Object Relational Mapping consente l'uso di "Ricco di Oggetti di Dominio", che sono classi Java, i cui stati sono modificabili durante la transazione di database
  • Functional Mapping Relazionale si basa sul "Poveri Oggetti di Dominio", che sono immutabili (tanto devi clonare una nuova ogni volta che si desidera modificare il suo contenuto)

Rilascia i vincoli di mettere sul ORM sessione e si basa la maggior parte del tempo su una DSL su SQL (in modo che la portabilità non importa) Ma, d'altra parte, è necessario guardare i dettagli della transazione, i problemi di concorrenza

List<Person> persons = queryFactory.selectFrom(person)
  .where(
    person.firstName.eq("John"),
    person.lastName.eq("Doe"))
  .fetch();

Immagino funzionale per la mappatura relazionale dovrebbe essere più facile creare e utilizzare rispetto OO di RDBMS.Finchè è solo una query al database, che è.Non vedo (ancora) come si potrebbe fare aggiornamenti del database senza effetti collaterali in un modo piacevole.

Il problema principale che vedo è la prestazione.Oggi RDMS non sono progettati per essere utilizzati con funzionalità di query, e probabilmente si comportano male in alcuni casi.

Non ho fatto funzionale-relational mapping di per sé, ma ho usato funzionante tecniche di programmazione per la velocità di accesso ad un RDBMS.

È abbastanza comune per iniziare con un set di dati, fare alcuni calcoli complessi su di esso, e memorizzare i risultati, i cui risultati sono un sottoinsieme dell'originale con altri valori, per esempio.L'approccio imperativo dettami che è possibile memorizzare i set di dati iniziale con possibilità di colonne NULL, fare il calcolo, quindi aggiornare i record con i valori calcolati.

Sembra ragionevole.Ma il problema è che si può ottenere molto lento.Se il vostro lavoro richiede un'altra istruzione SQL oltre la query di aggiornamento per sé, o addirittura deve essere fatto nel codice dell'applicazione, che letteralmente (re)ricerca per il record che si sta cambiando dopo il calcolo per memorizzare i risultati in diritto righe.

È possibile ottenere tutto questo con la semplice creazione di una nuova tabella per i risultati.In questo modo, si può semplicemente inserire sempre invece di aggiornamento.Si finisce per avere un'altra tabella, duplicazione chiavi, ma non è più necessario sprecare spazio sulle colonne di memorizzazione NULL – è solo conservare ciò che si ha.Poi si uniscono i risultati di selezionare.

I (ab)usato un RDBMS in questo modo e finito per scrivere le istruzioni SQL che sembrava per lo più come questo...

create table temp_foo_1 as select ...;
create table temp_foo_2 as select ...;
...
create table foo_results as
  select * from temp_foo_n inner join temp_foo_1 ... inner join temp_foo_2 ...;

Ciò è essenzialmente facendo è la creazione di un gruppo di immutabile associazioni.La cosa bella, però, è che si può lavorare su tutta la serie in una sola volta.Ricorda di lingue che ti permettono di lavorare con le matrici, come Matlab.

Immagino che questo consentirebbe anche per il parallelismo molto più facile.

Un extra vantaggio è che i tipi di colonne delle tabelle create in questo modo non è necessario essere specificato, in quanto essi vengono dedotti dalle colonne sono selezionati da.

Mi piacerebbe pensare che, come Sam menzionato, se il DB dovrebbe essere aggiornato, gli stessi problemi di concorrenza deve essere affrontato con OO mondo.Il carattere funzionale del programma potrebbe forse essere anche un po ' più problematico, più che l'oggetto, la natura, a causa dello stato di dati, transazioni, ecc RDBMS.

Ma per la lettura, il linguaggio funzionale potrebbe essere più naturale con qualche problema domini (come sembra essere indipendentemente dal DB)

Funzionale<->RDBMS mappatura dovrebbe avere grosse differenze di OO<->RDMBS mapping.Ma penso che questo dipende molto da che tipo di tipi di dati che si desidera utilizzare, se si desidera sviluppare un programma con un nuovo schema del DB o a fare qualcosa contro la legacy schema del DB, ecc..

Il pigro recupera ecc per le associazioni, per esempio, può probabilmente essere implementato molto bene, con qualche pigro valutazione dei concetti relativi.(Anche se può essere fatto molto bene con OO anche)

Edit :Con alcune ricerche con google ho trovato HaskellDB (Libreria SQL per Haskell) - che potrebbe essere la pena di provare?

Database e Programmazione Funzionale può essere fuso.

per esempio:

Clojure è un linguaggio di programmazione funzionale, basato sulla teoria dei database relazionali.

               Clojure -> DBMS, Super Foxpro
                   STM -> Transaction,MVCC
Persistent Collections -> db, table, col
              hash-map -> indexed data
                 Watch -> trigger, log
                  Spec -> constraint
              Core API -> SQL, Built-in function
              function -> Stored Procedure
             Meta Data -> System Table

Nota:Nell'ultima spec2, spec è più come RMDB.vedere: spec-alfa2 wiki:Schema-e-selezione

Io avvocato:La costruzione di un modello di dati relazionale in cima hash-mappa per raggiungere una combinazione di NoSQL e RMDB vantaggi.Questo è in realtà una inversione di attuazione del posgtresql.

Il Duck Typing:Se sembra come un'anatra e ciarlatani come un'anatra, deve essere un anatra.

Se clojure modello di dati come un RMDB, clojure strutture come un RMDB e clojure la manipolazione dei dati, come un RMDB, clojure, deve essere un RMDB.

Clojure è un linguaggio di programmazione funzionale, basato sulla teoria dei database relazionali

Tutto è RMDB

Implementare il modello di dati relazionale e di programmazione basato su hash-mappa (NoSQL)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top