• No results found

Utv¨ ardering av CouchDB

In document En utredning av NoSQL för iipax (Page 37-63)

3.4 ObjectBase

5.5.4 Utv¨ ardering av CouchDB

CouchDB har den absolut b¨asta communityn. Den finns mycket p˚a bloggar och liknande. Det finns till och med en hel gratis bok p˚a internet [16].

L˚agniv˚a APIet best˚ar av JSON och javascript fungerar v¨aldigt bra. Det ¨

ar v¨aldigt flexibelt och det finns m˚anga funktioner som om det utnyttjas r¨att kan skapa en v¨aldigt kraftfull databas. Den kan till och med ers¨atta mycket annan kod. S¨okningarna ¨ar n˚agot begr¨ansade n¨ar Lucene pluginen inte anv¨ands. Det ¨ar ett v¨aldigt annorlunda s¨att att t¨anka p˚a j¨amf¨ort med SQL kan det ta tid att f¨orst˚a hur allt fungerar. Det finns ¨aven en hel del funktionalitet i designdokumenten.

Ektorps officiella dokumentation ¨ar bra. Den har bra Javadoc och en utf¨orlig referensdokumentation. Men det finns inte s˚a m˚anga exempel p˚a

5.5. COUCHDB API KAPITEL 5. COUCHDB

kod. APIet f¨orekommer inte s˚a ofta p˚a bloggar och liknande vilket g¨or att det kan vara sv˚art att hitta l¨osningar p˚a sina problem.

Ektorp ¨ar beroende p˚a flera andra bibliotek, det kan d¨arf¨or vara v¨aldigt bekv¨amt att anv¨anda sig av exempelvis maven f¨or att l¨osa beroenden. Maven ¨

ar ett verkyg f¨or att hantera Java projekt.

Att ge sig i kast med CouchDB ¨ar v¨aldigt l¨att vid f¨orsta anblick men visar sig vara v¨aldigt sv˚art vid mer komplicerade till¨ampningar. Att f¨orst˚a sig p˚a CouchDB p˚a en l˚ag niv˚a k¨anns v¨aldigt viktigt. Det k¨anns l¨attare att skapa saker genom l˚agniv˚a och sedan kalla p˚a dem genom Ektorp, f¨or de g¨or den bra.

Kapitel 6

Cassandra

Cassandra ¨ar enligt dem sj¨alva en strukturerad key/value databas, en bland- ning av Google Bigtable och Amazons Dynamo[17]. Cassandra skapades f¨orst av Facebook f¨or deras inkorgs¨okning och sl¨apptes som ¨oppen k¨allkod 2008. Systemet ¨ar skrivet i Java och sl¨appt i version 0.7.4. Cassandera ¨ar en stor akt¨or inom NoSQL och anv¨ands av flera stora webbtj¨anster som Face- book, Digg och Twitter d¨ar den har gjort bra ifr˚an sig. F¨oretaget DataStax st˚ar idag bakom Cassandra.

Apache Cassandra ¨ar en databas som v¨aldigt ofta n¨amns i NoSQL sam- manhang. Cassandra har inte valts f¨or att den ser ut att kunna l¨osa de problemen iipax har idag utan i ett rent orienterande syfte. Det kan mycket v¨al bli en databas som kan vara ett bra val f¨or n˚agon av iipax framtida funktioner. Med tanke p˚a egenskaperna att kunna hantera stora m¨angder data och att Cassandra satsar h˚art p˚a D i ACID, att skriven data ska best˚a, skulle det kunna vara ett v¨aldigt bra alternativ f¨or l˚angtidslagring av data. Det finns ett flertal olika bibliotek som tillhandah˚aller ett abstraherat API. Kundera som ¨ar vald h¨ar har som m˚al att ha JPA helt implementerad. JPA ¨ar en standard f¨or Java mellan objekt och databas. Den ¨ar framf¨orallt avsedd f¨or att fungera med SQL, d¨arf¨or kan ¨overg˚angen g˚a smidigt. Den har idag kommit en bra bit p˚a v¨agen och ¨ar kompatibel med JPA 1.0. Det som ¨ar h¨ar n¨ast att implementera ¨ar relationer, @transactional och pre- och postpersist. Ett API som i stor utstr¨ackning, och mer ska komma, implementerar ett k¨ant API ¨ar l¨attare att konvertera till. Det ¨ar just d¨arf¨or som Kundera har valts att unders¨okas lite n¨armare.

6.1

Modelleringsm¨ojligheter

Strukturerna som finns i Cassandra ¨ar Kolumner, Superkolumner, Kolumn- familjer och Superkolumnfamiljer. En kolumn ¨ar en tripplett best˚aende av namn, v¨arde och en tidst¨ampel. Alla v¨arden som ¨ar i en databas m˚aste tillh¨ora en kolumn och en kolumn m˚aste ha det n¨amnda formatet. Data i

6.1. MODELLERINGSM ¨OJLIGHETER KAPITEL 6. CASSANDRA

en kolumn lagras bin¨art, d¨arf¨or g˚ar det att lagra vad som helst i f¨alten. Exempel p˚a en kolumn kan vara figur 6.1.

{

name: "F¨ornamn", value: "Jonas", timestamp:123567 }

Figur 6.1: Ett exempel p˚a en kolumn i Cassandra.

I exemplet ¨ar namnet p˚a v¨ardet F¨ornamn, v¨ardet ¨ar Jonas och tiden n¨ar den skapades ¨ar 123567.

Superkolumner ¨ar en gruppering av kolumner. De ¨ar best¨amda till dub- bletter som best˚ar av namn och v¨arde. En superkolumn kan gruppera god- tyckligt m˚anga kolumner. Exempel p˚a superkolumn i figur 6.2.

{

name:"Fullst¨andigt namn", value:{

F¨ornamn: {name: "F¨ornamn",

value:"Jonas", timestamp:123567} Efternamn: {name: "Efternamn",

value:"Hesselryd", timestamp: 1252136 } Mellanmanm: {name: "Mellannamn",

value: "Karl", timestamp: 923713021} }

}

Figur 6.2: En superkolumn i Cassandra.

Superkolumnen ¨ar till f¨or att lagra ett fullst¨andigt namn som best˚ar av kolumnerna: F¨ornamn, Efternamn och Mellannamn.

Vidare kan data struktureras i familjer. De kan antingen vara standard- eller superkolumnfamiljer. De samlar flera kolumner respektive superkolum- ner p˚a ett s¨att som kan likna en HashMap. Exempel p˚a en kolumnfamilj i figur 6.3.

En familj kan lagra godtyckligt mycket data och ¨ar schemal¨osa. Nya fa- miljer kan skapas medan databasen anv¨ands. Nyckeln till de olika kolumner- na kommer att vara v¨ardet. P˚a samma s¨att fungerar superkolumner f¨orutom att entiteterna i familjen ¨aven kan vara superkolumner.

I modelleringen av en databas ¨ar det bra att strukturera familjer efter hur data ¨ar t¨ankt att h¨amtas ut. I familjerna kommer det att g˚a snabbt att h¨amta ut data efter nyckel, eftersom det byggs upp index efter dem. Data i familjer sorteras efter v¨arden i kolumnerna. Det ¨ar bra att g¨ora eftersom

F¨ornamnSamling = { jonas: { name: "F¨ornamn", value: "Jonas", timestamp:"123567" }, adam: { name: "F¨ornamn", value: "Adam", timestamp:"12334267" } }

Figur 6.3: En kolumnfamilj i Cassandra.

familjer kan liknas vid fr˚agor och man vill oftast ha en viss ordning p˚a data som kommer ut. Familjer lagras explicit i den ordning som specificerats och det g˚ar d¨arf¨or v¨aldigt fort att h¨amta ut data f¨or att de ligger seriellt p˚a h˚arddisk. Alla strukturer kan ses som en fullst¨andig denormalisering och leder till redundant data men det ¨ar v¨aldigt effektivt.

[default@Twissandra] get User[’jsmith’];

=> (column=age, value=3339, timestamp=1298504259386000) => (column=first, value=4a6f686e, timestamp=1298504239938000) => (column=last, value=536d697468, timestamp=1298504248570000) Returned 3 results.

Figur 6.4: Ett exempel p˚a hur data kan h¨amtas ut genom den textbaserade klienten.

Cassandra har ¨aven st¨od f¨or att specificera databaser genom yaml (yet another markup language). I filen Cassandra.yaml konfigureras hela syste- met.

Cassandra st¨odjer sedan senaste versionen, 0.7, map/reduce funktiona- litet genom Hadoop. Det g˚ar d˚a att skapa map/reduce funktioner f¨or att h¨amta ut specifika delar av data utan att lagra det explicit som strukturer- na (se Modelleringsm¨ojligheter) g¨or.

Det viktigaste att inse med Cassandra ¨ar att strukturerna eller map/reduce funktionaliteten ¨ar det som kan liknas vid fr˚agor i andra spr˚ak. Databasens struktur m˚aste d¨arf¨or designas efter hur det ¨ar t¨ankt att data ska h¨amtas ut. Men det kommer inte att inneb¨ara allt f¨or mycket jobb eftersom familjer ¨

6.2. ACID KAPITEL 6. CASSANDRA

6.2

ACID

Cassandra st¨odjer inte ACID utan g˚ar alltid efter BASE, en operation ¨

ar dock atom¨ar p˚a en kopia. Data kan dock h˚allas konsistent genom in- st¨allningar. Inst¨allningar f¨or l¨as- och skrivoperationer g˚ar fr˚an att en el- ler ingen nod ska svara till att alla ska svara p˚a beg¨aran. Det vill s¨aga l¨asoperationen v¨antar antingen p˚a f¨orsta b¨asta kopia att l¨asa fr˚an eller att v¨anta och j¨amf¨ora fr˚an flera kopior. Med flera kopior g˚ar det att ta reda p˚a vilken kopia som g¨aller. I fallet med skrivoperation beh¨over ingen ko- pia svara utan data l¨aggs p˚a k¨o f¨or att skrivas. I den ena ¨anden kommer operationer g˚a v¨aldigt fort och systemet kommer att f˚a bra responstid. F¨or l¨asning m˚aste minst en nod svara och f¨or skrivning g˚ar det att g¨ora ett asyn- kront anrop d˚a inget svar beh¨ovs. Nackdelen med att st¨alla in systemet p˚a det viset ¨ar att data kommer att riskera att bli inkonsistent. Uppdateringar kommer s˚a sm˚aningom att fortplanta sig genom hela systemet. I den andra ¨

anden g˚ar det att st¨alla in att en operation beh¨over svar fr˚an samtliga no- der f¨or att kunna forts¨atta. Det kommer att dra upp responstiden och om noder i ett kluster ¨ar otillg¨angliga kommer operationen att misslyckas. D¨ar emellan finns att antalet noder ska uppn˚a quorum. Quorum kan v¨aljas att antingen vara f¨or hela systemet eller bara den lokala noden.

N˚agot som Cassandra st¨odjer ¨ar D i ACID. Databasen ¨ar designad f¨or att data ska best˚a. Det skrivs loggar vid varje operation och Cassandra st¨odjer v¨aldigt avancerad replikering s˚a att data aldrig ska g˚a f¨orlorat.

6.3

Skalbarhet

Cassandra k¨ors idag p˚a stora kluster p˚a ¨over 400 maskiner(Digital Reaso- ning). Det ¨ar en av systemets starkaste punkter. Cassandra ¨ar feltolerant och klarar av att noder g˚ar ner. Det g¨or att kluster kan v¨axa och krympa dynamiskt. I ett distribuerat l¨age satsar Cassandra p˚a att uppfylla A och P fullt ut och har d¨arf¨or lite mindre konsistent data. Men det g˚ar att uppn˚a konsistent data med de olika alternativen f¨or l¨as- och skrivoperationer.

Systemet ¨ar uppbyggt som en DHT, distribuerad hash tabell, och adress- rymden ¨ar cirkul¨ar och ¨ar 128 bitar stor. En hashtabell ¨ar en stor tabell av nycklar och v¨arden. Nyckeln f˚as genom att ber¨akna ett v¨arde utifr˚an data med hj¨alp av en hashfunkton. Adresserna delas upp mellan de noder som finns i klustret. Ett kluster ¨ar decentraliserat och varje nod h˚aller bara reda p˚a de noder som kommer direkt f¨ore och efter med h¨ansyn till adresserna. Den decentraliserade arkitekturen g¨or att det inte finns n˚agon ensam nod som kan dra ner ett helt kluster. N¨ar Cassandra delar ut data till de olika adresserna g˚ar det att v¨alja om systemet ska v¨alja adresser slumpm¨assigt eller seriellt. Ett slumpm¨assigt s¨att kommer att balansera belastningen ¨over noderna medan det seriella kommer att ge en n˚agot skev belastning.

6.4

Index

Cassandra ¨ar en form av key/value databas och har d¨arf¨or nycklar till alla sina v¨arden som kan h¨amtas ut i konstant hastighet, O(1). I kluster f˚ar givetvis n¨atverkets begr¨ansningar tas till h¨ansyn. Det g˚ar ¨aven att skapa index ¨over m¨angder av data med familjer. Index byggs efter databasdesignen. Fulltextindexering i Cassandra anv¨ander sig av Lucene med en plugin som kallas Lucandra. Den har de funktioner som kan v¨antas av en s˚adan integration i ¨ovrigt. En f¨orb¨attring av Lucandra ¨ar under utveckling och baseras p˚a Solr. Det ¨ar ett indexeringsverktyg som bygger vidare p˚a Lucene och har d¨armed mer funktionalitet. Pluginen kallas f¨or Solandra.

6.5

API

Cassandra har st¨od f¨or att kommunicera med m˚anga olika spr˚ak. Det ¨ar framf¨or allt tack vare att den kommunicerar p˚a l˚ag niv˚a via Apache Thrift. Thrift ¨ar ett projekt f¨or att kommunicera mellan olika spr˚ak och det finns st¨od f¨or en hel del spr˚ak. Vidare har Cassandra en textbaserad klient som kan utf¨ora n˚agra grundl¨aggande administrativa uppgifter. Till sist finns det flertalet projekt som kapslar in Thrift till en h¨ogniv˚a API. Det som ¨ar valt att unders¨oka n¨armare h¨ar ¨ar Kundera.

6.5.1

Cassandra-cli

Cassandra har en textbaserad klient d¨ar anv¨andaren har tillg˚ang till ett API som ¨ar p˚a en l˚ag niv˚a. Det liknar en vanlig textbaserad klient, som den f¨or MySQL. Den kopplar upp mot en k¨orande instans av Cassandra. D¨ar ¨

ar det m¨ojligt att skapa nyckelrymder(eng. keyspaces) och behandla data. Dokumentationen ¨ar bristf¨allig.

¨

Aven om dokumentationen kan anses vara bristf¨allig g˚ar det att komma l˚angt med programmets hj¨alpfunktion. Kolumnfamiljer skapas som i figu- ren 6.5 och i deklareringen g˚ar det att specificera typen till super om det beh¨ovs. D¨arefter skapas kolumner implicit genom kommandot set.

6.5.2

Thrift

Thrift anv¨ands f¨or att kommunicera med en Cassandradatabas ifr˚an ett externt spr˚ak, exempelvis Java. Thrift APIet ¨ar p˚a v¨aldigt l˚ag niv˚a. Det ¨ar inte rekommenderat att bygga applikationer med Thirft API[17], utan det rekommenderas att v¨alja ett h¨ogniv˚a bibliotek.

Thrift kommunicerar med Cassandra genom egna n¨atverkssockets som kopplas till en klient. Genom klienten g˚ar det att utf¨ora en hel del mani- pulering av data och inst¨allningar i databasen. APIet ¨ar p˚a ungef¨ar samma niv˚a som den textbaserade klienten.

6.5. API KAPITEL 6. CASSANDRA

connect localhost/9160;

[default@unknown] create keyspace ks1; [default@unknown] use ks1;

Authenticated to keyspace: ks1

[default@ks1] create column family Manager with comparator = UTF8Type;

[default@ks1] set Manager[’jhesselryd’][’name’] = ’Jonas’; Value inserted.

[default@ks1] set Manager[’jhesselryd’][’surname’] = ’Hesselryd’;

Value inserted.

[default@ks1] get Manager[’jhesselryd’]; => (column=name, value=4a6f6e6173,

timestamp=1304326675056000) => (column=surname, value=48657373656c727964,

timestamp=1304326688382000)

Figur 6.5: En session i cassandera-cli.

6.5.3

Kundera

Kundera ¨ar som n¨amnt ett Java API f¨or Cassandra och ¨ar kompatibel med JPA 1.0. Den ser till stor del ut som JPA men har n˚agra extra notationer f¨or super kolumner, kolumnfamiljer och super kolumnfamiljer. Det anv¨ander sig av JPAs EntityManager.

@Entity

@ColumnFamily(keyspace ="keyspace1", family = "Managers") public class Manager {

@Id // row identifier String username;

@Column(name = "email") // override column-name String emailAddress;

Figur 6.6: En entitet i Kundera API

I exemplet figur 6.6 ¨ar en klass som kommer sparas ner i Cassandra. Det ¨

ar bara ColumnFamily som ¨ar speciell f¨or Kundera alla andra ¨ar fr˚an Javas Persistence API.

I Kundera indexeras allt om annat inte specificeras. Indexeringen till- handah˚alls med pluginen Lucandra i bakgrunden. N¨ar indexering inte ¨onskas specificeras det med @Index(index=false). Kundera ¨ar till och med tillr¨ackligt kompatibelt f¨or att den kan s¨oka med hj¨alp av fr˚agor som ¨ar st¨allda i SQL.

Det finns inte tillg˚ang till all funktionalitet som SQL har eftersom allt inte ¨

annu ¨ar implementerat i Kundera.

6.5.4

Kommentarer p˚a API

Dokumentationen f¨or m˚anga delar ¨ar bristf¨allig. Det ¨ar sv˚art att hitta in- formation och den som finns ¨ar i m˚anga fall utdaterad. Det textbaserade administrationsverktyget som finns ¨ar d˚aligt dokumenterat men efter att ha spenderat tid med det och anv¨andning av hj¨alpkommandot s˚a uppt¨acks mycket funktionalitet.

Thrift APIn ¨ar p˚a en v¨aldigt l˚ag niv˚a och saknar d¨arf¨or mycket av den funktionalitet som beh¨ovs f¨or att ha i ett faktiskt projekt.

H¨ogniv˚a APIerna har bra id´eer och kommer f¨ormodligen att bli bra. Idag ¨

Kapitel 7

Exempel

Kapitlet tar upp och diskuterar hur en eventuell implementation skulle f¨orverkligas. Det ¨ar framf¨orallt de delar som visat sig passande vid utv¨arderingen av respektive databas som diskuteras. Det ¨ar till f¨or att st¨arka slutsatserna och ge l¨asaren en st¨orre insikt i vad en implementation skulle inneb¨ara. Det som tas upp ¨ar kod och designm¨onster som finns f¨or att l¨osa problemen.

7.1

Hierarkisk grafmodellering

F¨oljande stycke tar upp ett designm¨onster f¨or att skapa hierarkiska struktu- rer i en grafdatabas. Exemplet kommer att modellera en f¨orenklad version av ett ¨arende i en hierarkisk struktur och hur den kan traverseras.

Det faller sig naturligt att representera en hierarkisk struktur som en graf. Ett exempel p˚a hur det skulle kunna representeras i Neo4J ¨ar:

En sak att notera med modellen i figur 7.1 ¨ar att strukturen har en rotnod och att det finns olika relationer. Rotnoden blir den naturliga ing˚angen till ¨

arendet. Alla delar av ett ¨arende ¨ar relaterade till rotnoden och alla delar kan n˚as fr˚an den genom traversering.

Node casex = graphDb.createNode(); Node journal = graphDb.createNode(); Node attachments = graphDb.createNode();

journal.createRelationshipTo( casex, Rels.BELONGS_TO); attachments.createRelationshipTo( casex, Rels.BELONGS_TO); Node att1 = graphDb.createNode();

...

att1.createRelationshipTo(attachments, Rels.ATTACHED_TO); ...

Node event1 = graphDb.createNode(); ...

event1.createRelationshipTo(journal, Rels.IN_JOURNAL); ...

Figur 7.2: Exempel p˚a hur figur 7.1 kan representeras i kod.

Figur 7.2 visar hur ¨arendet representeras i det inb¨addade Java APet. F¨orst deklareras noder f¨or den ¨oversta biten av hierarkin. Att s¨atta attribut p˚a noderna utl¨amnades p˚a grund av brist p˚a utrymme. Efter det skapas rela- tioner mellan de ¨oversta noderna. Riktningen blir implicit satt fr˚an den nod som vars metod anv¨ands, riktningarna f¨oljer figur 7.2. Efter det f¨oljer sam- ma procedur f¨or n¨asta niv˚a av hirarkin. De olika relationerna som anv¨ands skapas genom en Java enum som implementerar gr¨anssnittet Relationship-

Type.

Node node = getNode("case\_x"); Traverser traverser = node.traverse(

Traverser.Order.BREADTH_FIRST, StopEvaluator.END_OF_GRAPH,

ReturnableEvaluator.ALL_BUT_START_NODE, Rels.BELONGS_TO, Direction.INCOMING, Rels.ATTACHED_TO, Direction.INCOMING);

Figur 7.3: Kod f¨or en traverser.

I figur 7.3 beskrivs det hur en s¨okning efter bifogade dokument skulle kunna ˚astadkommas. Listan f¨or hur m˚anga par av relationer och riktningar som kan finnas i argumentlistan ¨ar inte begr¨ansad. Det ¨oppnar m¨ojligheter

7.2. MAP/REDUCE F ¨OR JOIN KAPITEL 7. EXEMPEL

att s¨oka i en eller flera grenar av strukturen. Traverseraren anv¨ands sedan genom att anv¨anda Javakonstruktionen for-each; Traverser implementerar

Iterable gr¨anssnittet.

De andra parametrarna StopEvaluator och ReturnableEvaluatior ¨ar pa- rametrar som det g˚ar att skapa egna varianter av. Det ¨okar kraften i kon- struktionen f¨or att StopEvaluator best¨ammer hur l˚angt traverseringen ska g˚a och ReturnableEvaluatior best¨ammer vilka noder som ska returneras ut f¨or behandling vid iterering ¨over noderna.

Detta ¨ar ett bra exempel f¨or att visa hur kraftfull graftraversering kan vara. Det finns stora m¨ojligheter att behandla exempelvis ¨arenden p˚a smarta s¨att. Neo4J har ett ramverk f¨or att kunna traversera i databasen i sitt API, det g¨or att det finns m˚anga m¨ojligheter att p˚a enkla s¨att behandla graferna.

7.2

Map/Reduce f¨or join

Detta exempel ¨ar baserat p˚a en bloggpost,[19], men data ¨ar anpassat. Data som anv¨ands h¨ar ¨ar ett ¨arende och journalh¨andelser.

F¨or att skapa en join i CouchDB finns det minst tre s¨att att g¨ora det p˚a: denormalisering, flera h¨amtningar eller genom komplexa nycklar.

7.2.1

Denormalisering

En fullst¨andig denormalisering skulle inneb¨ara att dokumentet f¨or ett ¨arende har ett n¨astlat f¨alt f¨or en journal och i f¨altet placeras alla h¨andelser. L¨osningen kan anses lite f¨or enkel och den extra datam¨angden som m˚aste h¨amtas varje g˚ang ett ¨arende eller en h¨andelse ska hanteras kan bli on¨odigt stor. I fallet n¨ar en join beh¨ovs ¨ar det v¨aldigt bra, men ska de olika entiteterna behandlas separat blir det on¨odigt arbete.

En map-funktion skulle i detta fall bara beh¨ova se till att ett dokument ¨

ar av typen ¨arende och skicka ut den: function(doc){

if(doc.type == ’case’) emit(doc._id, doc); }

Figur 7.4: En map-funktion f¨or denormaliserad data.

I figur 7.4 tas ett dokument i taget in fr˚an databasen. D¨arefter kollar funktionen om f¨altet type har v¨ardet case. Att ha ett f¨alt f¨or dokumentets typ ¨ar v¨aldigt vanligt i designen av dokument. Om det visar sig att doku- mentet har r¨att typ kommer det att skickas ut med id som nyckel och hela dokumentet som v¨arde. ¨Over detta kommer ett index att byggas s˚a att det g˚ar fortare n¨asta g˚ang vyn kallas. Indexet kommer att ut¨okas allt eftersom

nya dokument anl¨ander, tills exempelvis funktionen ovan ¨andras. D˚a m˚aste ett nytt index skapas.

Det g˚ar att med designen av en vy g¨ora s˚a att det v¨arde som skickas som resultat exkluderar h¨andelserna. Det vill s¨aga i emit -funktionen skickas inte

doc ut som v¨arde utan bara de valda delarna som beh¨ovs. Det skulle leda till att n¨atverket inte skulle beh¨ova belastas lika mycket. Men behandlingen i databasen skulle fortfarande behandla lika mycket data. Det kommer att ta lite extra tid och ber¨akning de g˚anger d˚a ett f¨ardigt index ¨over resultatet inte finns redo.

7.2.2

Flera h¨amtningar

En smartare l¨osning ¨ar att normalisera ¨arendet och h¨andelserna till tv˚a entiteter. I likhet med tv˚a tabeller i en relationsdatabas. Koden nedan visar

In document En utredning av NoSQL för iipax (Page 37-63)

Related documents