Domanda

Ho fatto immersioni in Erlang di recente, e ho deciso di usare mnesia a fare il mio lavoro di database dato può memorizzare qualsiasi tipo di struttura dati Erlang senza un problema, scala con facilità, da utilizzare con list comprehension, ecc

Per chi proviene da database SQL standard, la maggior parte delle righe possono e devono essere identificati da una chiave primaria, di solito un intero incremento automatico. Per default mnesia considera il primo campo di una riga per essere la chiave. Si dà anche modo di avere una chiave intero incremento automatico per quanto ne so.

Dato che ho questi record fittizi che rappresentano le mie tabelle:

-record(user, {name, salt, pass_hash, email}).
-record(entry, {title, body, slug}).
-record(user_entry, {user_name, entry_title}).

Immagino utilizzando il nome utente può essere abbastanza buono per alcuni scopi, come con il titolo di ingresso, al fine di identificare la risorsa, ma come posso fare per mantenere l'integrità?

Di 'l'utente cambia il suo nome, o che le modifiche del titolo del entrata dopo una modifica. Come posso assicurarmi che la mia tecnica è ancora correttamente legato? Aggiornamento ogni tavolo utilizzando il nome utente quando cambia suona come una pessima idea, non importa quanto è messo.

Quale sarebbe il modo migliore per attuare una sorta di sistema chiave primaria in mnesia?

Inoltre, come sarebbe una tabella intermedia come 'user_entry' fare se il primo campo è di solito la chiave? In caso contrario, quale sarebbe il modo migliore è quello di rappresentare una relazione molti-a-molti in mnesia?

È stato utile?

Soluzione

Io preferisco utilizzare GUID al posto di int incremento automatico come chiavi esterne artificiali. C'è un modulo uuid Erlang disponibili presso GitHub, oppure è possibile utilizzare {now(), node()}, visto che now/0 dottore dice: "E 'anche garantito che le chiamate successive a questa BIF restituisce in continuo aumento i valori".

Usando qualcosa che può cambiare come chiave primaria mi sembra essere una cattiva idea indipendente dal sistema di database.

Non dimenticare che non è necessario per normalizzare i dati in mnesia anche alla prima forma normale; nel tuo esempio, vorrei prendere in considerazione la seguente struttura:

-record(user, {id, name, salt, pass_hash, email, entries}).
-record(entry, {id, title, body, slug, users}).

dove entries e users sono liste di ID. Naturalmente, questo dipende dalle query che si desidera.

EDIT:. Fissata per essere molti-a-molti, invece di molti-a-uno

Altri suggerimenti

mnesia fa sequenze di supporto (interi incremento automatico) in forma di mnesia:dirty_update_counter(Table, Key, Increment). Per utilizzarlo è necessario un tavolo con due attributi chiave e contare. Nonostante il nome, dirty_update_counter è atomico, anche se non viene eseguito all'interno di una transazione.

Ulf Wiger ha fatto un certo lavoro sulla fornitura di caratteristiche tipiche RDBMS in cima mnesia nel suo RDBMS . Il suo codice prevede vincoli di stranieri chiave, gli indici parametized, i vincoli di valore di campo e così via. Purtroppo questo codice non è stato aggiornato in due anni e probabilmente sarà difficile ottenere l'esecuzione senza un po 'di esperienza Erlang.

Quando si progetta per l'utilizzo e mnesia si dovrebbe ricordare che mnesia non è un database relazionale. Si tratta di una chiave / valore negozio transazionale ed è molto più facile da usare quando non si normalizzare.

Se i nomi utente sono unici, è possibile utilizzare lo schema:

-record(user, {name, salt, pass_hash, email}).
-record(entry, {posted, title, body, slug, user_name}).

Dove posted è l'Erlang: ora () momento in cui viene caricato l'articolo. user_name potrebbe essere necessario un indice secondario, se spesso è necessario prelevare un elenco di tutti gli articoli per un utente. Poiché questi dati è suddiviso su due tavoli, si dovrà rispettare eventuali vincoli di integrità nel codice dell'applicazione (per esempio, non accettando le voci senza un nome utente valido).

Ogni valore di campo in mnesia può essere un qualsiasi termine Erlang, quindi se siete a corto di una chiave univoca su qualsiasi particolare campo, spesso è possibile combinare alcuni campi per darvi un valore che sarà sempre unica - forse {nome utente, DatePosted, TimePosted}. Mnesia ti permette di cercare le chiavi parziali via mnesia:select(Table, MatchSpec). MatchSpecs sono abbastanza difficili da scrivere a mano, in modo da ricordare che ets:fun2ms/1 può convertire una funzione pseudo Erlang in un matchspec per voi.

In questo esempio, noi fun2ms genera una matchspec per la ricerca di un tavolo -record(entry, {key, title, slug, body}). blog in cui chiave è {Username, {Year, Month, Day}, {Hour, Minute, Second}} - il nome utente dell'autore e la data e l'ora l'articolo è stato pubblicato. L'esempio seguente recupera i titoli di tutti i post nel blog di TargetUsername nel mese di dicembre del 2008.

ets:fun2ms(fun (#entry{key={U, {Y,M,_D}, _Time}, title=T})
             when U=:=TargetUsername, Y=:=2008, M=:=12 ->
               T
           end).
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top