• No results found

Jämförelse av Mysql och MongoDb

N/A
N/A
Protected

Academic year: 2021

Share "Jämförelse av Mysql och MongoDb"

Copied!
40
0
0

Loading.... (view fulltext now)

Full text

(1)

Kandidatavhandling i Programvaruteknik 06 2012

Jämförelse av Mysql och MongoDb

Alfred Wester

Olof Fredriksson

Kontaktinformation: Författare: Alfred Wester E-mail: alfredwester@gmail.com Olof Fredriksson E-mail: fredriksson@olof.nu Handledare: Nina D. Fogelström School of Computing

Sektionen för datavetenskap och kommunikation

Blekinge Tekniska Högskola Internet : www.bth.se/com

371 79 Karlskrona Phone : +46 455 38 50 00

(2)

Abstract. Speed is a very important factor in websites and other types of applications and almost all applications stores some type of data, normally in a database. For an example a blog typically saves users, posts and comments. There’s a high risk that as the amount of data in the database grows, the time for inserting and requesting specific data increases. If it takes more than some seconds to view a specific page, a user will normally leave the site. However, it’s a fact that the database will grow while the application will become more popular but it’s possible to save a lot of time if using right database, and structure. In this thesis MongoDB and MySQL will be compared with focus on time consumption.

SQL (Structured Query Language) is the language which most databases use. This kind of database stores data in structured tables and noting can be added to them if the type of data is incorrect. SQL also support relations between tables. MySQL is a very popular relational database management system (RDBMS) which for example websites frequently makes use of.

NoSQL is a new type of databases where the data is stored in collections without any kind of structure, unlike the well known SQL databases where the data is stored in structured tables. Because of the non-structure, these types of databases are designed to be fast and scalable over multiple machines. Mongodb is a such kind of NoSql-database.

(3)

Innehåll

1 Introduktion . . . 5 1.1 Målgrupp . . . 5 2 Bakgrund . . . 5 2.1 Data . . . 5 2.2 MySql . . . 5 2.3 MongoDb . . . 6 2.3.1 Gridfs . . . 7 2.4 Multiinsättning . . . 7 2.5 Json . . . 7 2.6 PHP . . . 7

3 Forskningsfrågor och metodik . . . 8

3.1 Frågeställningar . . . 8

3.2 Utformining av litteraturstudie . . . 8

4 Resultat från litteraturstudie . . . 8

4.1 Beskrivning av litteratur . . . 9

4.2 Resultat och diskussion . . . 9

4.2.1 RQ1. Vilka jämförelser av Sql och NoSql-databaser finns redan och hur utformades de? 10 4.2.2 RQ2. Vilken databas presterar snabbast när det gäller att sätta in och filtrera data? . . 11

4.2.3 RQ3. Blir det några skillnader på resultatet vid annan uppsättning av miljö? . . . 11

5 Utformining av experiment . . . 12

5.1 Mål. . . 12

5.2 Faktorer . . . 12

5.2.1 PHP . . . 12

5.2.2 Operativsystem & Hårdvara . . . 12

5.2.3 Olika datamodeller . . . 13

5.2.4 Datamängder . . . 13

5.2.5 Vad för typ av data . . . 13

5.2.6 Sätta in all data samtidigt . . . 13

5.3 Testmiljö . . . 13 5.3.1 Systeminformation . . . 14 5.4 Datamodell . . . 14 6 Utförande . . . 14 6.1 Testfall . . . 14 6.2 Insättning . . . 15 6.3 Filtrering . . . 16 7 Resultat . . . 17 7.1 Insättning . . . 17 7.1.1 Ubuntu 64 . . . 17 7.1.2 Ubuntu 32 . . . 18 7.2 Filtrering . . . 18 7.2.1 Ubuntu 64 . . . 18 7.2.2 Ubuntu 32 . . . 19

8 Analys och diskussion . . . 19

8.1 Tester som inte kunde genomföras . . . 19

8.2 Analys av resultatet . . . 20

8.3 Olika sätt att hantera resultatet . . . 20

(4)

8.4.1 MongDb är snabbare . . . 20

8.4.2 MongoDb på ett 32-bitars system . . . 21

8.5 Validering av resultat . . . 21

8.6 Kopplingar till tidigare arbeten . . . 21

8.7 Framtida arbete . . . 21

9 Sammanfattning . . . 22

A Datamodeller . . . 26

A.1 MySql - Insättning . . . 26

A.2 MongoDb - Insättning . . . 26

A.3 MySql - Filtrering . . . 27

A.4 MongoDb - Filtrering . . . 28

A.4.1 Med relationer . . . 28

A.4.2 Utan relationer . . . 28

B Källkod . . . 29

C Diagram . . . 39

C.1 Insättning av data Ubuntu 64 . . . 39

C.2 Insättning av data Ubuntu 32 . . . 39

C.3 Filtrering av data Ubuntu 64 . . . 40

(5)

1

Introduktion

Dagens populära webbtjänster som till exempel Facebook[1] och Twitter[2] sparar undan en stor mängd data kring användarna och de aktiviteter som görs. Samtidigt som det hela tiden växer med information som ska lagras är det fortfarande en hög prioritet att datan ska gå att ladda snabbt, en fördröjning på endast några sekunder kan resultera till i en förlorad användare som i sin tur kan vara förödande för tjänsten. Det finns idag ett flertal olika databastyper där grundprincipen är samma, att skriva och läsa ut data. Det som däre-mot skiljer dem är deras sätt att hantera datan och hastigheterna att läsa ut från databasen varierar kraftigt. I detta arbete har vi tänkt att testa och jämföra två olika typer av databaser, SQL och NoSql. Vi ska generera ett par tester och mäta vilken av dem som presterar snabbast. Testerna ska, i så stor grad som möjligt, återspegla verkliga scenarion, för att ta reda på hur mycket snabbare MongoDb är istället för MySql och hur strukturen på databasen förändras.

Valet av dessa två är dels för att MySql är en av de populäraste databaserna och som många faktiskt känner till. MongoDb är däremot relativt ny och släpptes 2009 så troligtvis är det inte alls lika många som känner till den. I en tidigare uppsats[3] som skrivits jämförs CouchDb och MongoDb där MongoDb vinner i snabbhet på de flesta testerna vilket gör det ännu mer spännande att göra jämförelser med MySql.

1.1 Målgrupp

Målgruppen för detta arbete riktar sig till alla som är intresserade eller jobbar med olika typer av databaser. Den grundläggande informationen kring respektive typ finns under sektion 2 bakgrund, men vi rekommen-derar ändå att man har några tidigare erfarenheter antingen genom att ha jobbat med databaser eller kan grundprinciperna om hur de fungerar.

2

Bakgrund

2.1 Data

Data, eller information kan innehålla till exempel uppgifter kring en användare, som namn och lösenord. I vårt fall finns denna information tillgänglig i databaser och hämtas sedan fram med hjälp av anrop. Beroende på hur mycket data man ska hämta hem, och ifall någon filtrering görs så kommer detta ta en viss tid, vilket vi kommer jämföra mellan två de olika typerna.

2.2 MySql

Sql är ett språk som hanterar kommunikationen med en relationsdatabas. Språket utvecklades under 70-talet och idag finns det ett flertal databaser som stödjer Sql. MySql[4] är en av dessa och släpptes redan 1995 av MySql AB. Populäriteten ökade snabbt och idag är det ett vanligt alternativ på både hemsidor och andra typer av applikationer. Kortfattat så är en relationsdatabas uppbyggd med tabeller, fält och poster. Anta att det är en tabell med medlemmar, där fälten är namn och lösenord så kommer varje medlem på en separat rad i tabellen. Sql-kommandot för att hämta ut alla medlemmar och dess information görs med en Select[5] som då blir:

SELECT * FROM members

För att sedan filtrera informationen och bara hämta ut vissa data, används WHERE, LIKE och liknan-de operationer.

(6)

kommentarer kan detta sparas i två separata tabeller. Givetvis är det möjligt att spara användarinformatio-nen i tabellen för inläggen, men då utnyttjar man inte styrkan med relationsdatabaser. Det rekommenderade sättet att strukturera det är att i tabellen för inlägg, endast spara ned id-nummret till användaren, och sedan koppla ihop detta till Member där denna information endast behövs sparas ned på en rad. Samma princip gäller tabellen för kommentarer.

Sql-koden för att nu hämta hem alla artiklar som användaren Simba skapat kan nu se ut såhär: SELECT ∗ FROM `Post ` as P INNER JOIN Member as M

ON P. idMember = M. idMember AND M. name = ' Simba '

Figur 1: Exempel på en relationsdatabas för medlemmar, blogginlägg och kommentarer

I relationsdatabaser används nycklar för att koppla ihop tabellerna. Begreppet kallas för främmande nycklar[6] och kan se till så att datan är konsistent. Ett exampel är att det är möjligt att förhindra att en medlem inte går att radera sålänge det finns artiklar kopplade till användaren, nackdelen är att detta kan leda till att databasen blir slöare för att sätta in och proccessera data.

2.3 MongoDb

MongoDb[7] är en slags NoSql-databas som egentligen inte är någon ny teknik, men det är på senare år som det växt otroligt och är idag ett hett ämne när man pratar om stora och skalbara lösningar till sina databaser. Precis som med SQL finns det även flera NoSql-databaser, där de skiljer sig lite från varandra. MongoDb sparar undan informationen i Json-liknande format, BSON. Det är en binär serialisering av Json och är utformat för att vara lättviktigt, enkelt att traversera i samt effektivt[8]. Grunderna kring Json finns i sektion 2.5 Json. Sättet att kommunicera med databasen och hur informationen lagras skiljer sig alltså en hel del i jämförelse med relationsdatabaserna.

(7)

Varje objekt som sätts in i databasen kommer få ett unikt id som bland annat baseras på tiden samt process-id[9].

{

" _id ": O b j e c t I d (" 4 f d 2 3 0 2 6 6 8 0 3 f a 9 d 1 0 0 0 0 3 e 7 ") , " title ": " Awesome post ",

" content ": " Lorem ipsum dolor sit amet , c o n s e c t e t u r a d i p i s c i n g elit . [...] ", " tags ": { " 0 ": " dummy post ", " 1 ": " tag ", " 2 ": " Mufasa ", } }

Listing 1: En relationsfri Collection med inlägg och dess taggar 2.3.1 Gridfs

MongoDb har i den senaste versionen (2.0.5) en begränsning på 16MB[10] per objekt och vid insättning av stora filer i databasen kan det därför finnas en risk att filen helt enkelt inte får plats. För att komma runt detta finns GridFs[10] implementerat och skillnaden är att filen automatiskt delas upp i mindre bitar vid behov och begräsningen på en maximal filstorlek försvinner. Det är nu möjligt att spara ned betydligt större filer som till exempel filmer.

2.4 Multiinsättning

För både MySql och MongoDb finns ett alternativt sätt att sätta in data: multi-insert för MySql och bulk-insert[11] för MongoDb. Istället för att sätta in ett element i taget, sätts då alla element in med ett enda kommando. Detta är speciellt användbart när många element ska sättas in på samma gång eftersom data-basen då endast behöver hantera en request.

2.5 Json

JavaScript Object Notation, Json[12] är ett textformat som används till att lagra och skicka data, och har blivit ett alternativ till eXtensible Markup Language, XML. Ett användningsområde där kommunikation med Json används är mellan en server och webbläsare, till exempel om man vill ladda ned innehåll dyna-miskt med hjälp av Javascript.

{ " f ir st Na me ": " John ", " lastName ": " Doe ", " phoneNo ": " +4600012 ", " active ": true }

Listing 2: Ett exempel på hur ett Json-objekt kan se ut

2.6 PHP

(8)

3

Forskningsfrågor och metodik

3.1 Frågeställningar

Arbetet ska försöka att besvara följande frågor:

RQ1. Vilka jämförelser av Sql och NoSql-databaser finns redan och hur utformades de? RQ2. Vilken databas presterar snabbast när det gäller att sätta in och filtrera data? RQ3. Blir det några skillnader på resultatet vid annan uppsättning av miljö? Listan nedan visar vilka metoder respektive fråga kommer att besvaras med: RQ1. Forskning i litteratur

RQ2. Experiment/tester RQ3. Experiment/tester

3.2 Utformining av litteraturstudie

Sökning efter lämplig litteratur genomfördes under ett antal dagar och resulterade i en lista med artiklar av olika slag, men även guider och länkar till givande webbsidor hittades. Resultaten hittades uteslutande på internet med hjälp av följande sökmotorer:

Google schoolar BTH Summon Google

De söktermer som användes var: Nosql

nosql, mysql vs nosql

Comparison between NoSQL and mysql paper nosql mysql

nosql performance mysql performance

mysql nosql php perspective prestandaskillnader nosql mysql

De kriterier som fanns för att godkänna en artikel var att den måste vara publicerad senare än 2008 och att artikeln ska innehålla något som rör någon av databastyperna. Anledningen till att de inte ska vara äldre än från 2008 beror på att även om Nosql funnits länge, är det de senaste åren som det blivit ett väldigt hett ämne och blivit ett alternativ för tjänster med stora mängder data. Äldre artiklar kan även innehålla irrelevanta saker, till exempel funktionalitet som då inte fanns tillgänglig men gör det nu.

4

Resultat från litteraturstudie

(9)

4.1 Beskrivning av litteratur

Tabell 1 visar artiklarna från litteraturstudien där blått symboliserar arbeten skrivna av studenter(33%), grönt är papper som publicerats i konferenser(42%) och de som är markerade med orange är övriga artiklar såsom guider eller artiklar publicerade på internet(25%).

Det som är gemensamt för alla artiklar är att de handlar om MySql, NoSql eller något som relaterar till dem. Vi har försökt finna och välja ut de som antingen handlar om prestanda eller de som jämför databasty-perna på något sätt och som inte är utgivna tidigare än 2008. Som sökmetod för att hitta artiklar användes internet, genom de sökmotorer som nämnts i sektion 3.2. Den funna artikelns sammanfatting låg till grund för att avgöra om den var relevant eller inte.

Artikel Rubrik Ref.

P1 Document Oriented NoSQL Databases - A comparison of performance in MongoDB and CouchDB using a Python interface

[3]

P2 Utredning av NoSQL-databaser för Sogeti i Gävle [15]

P3 Data modeling with NoSQL: how, when and why [16]

P4 Building blocks of a scalable web crawler [17]

P5 Will NoSQL databases live up to their promise? [18]

P6 Debunking the NoSQL Hype [19]

P7 Security Issues in NoSQL Databases [20]

P8 Using MongoDB to Implement Textbook Management System instead of MySQL [21] P9 MySQL Performance Analysis on a Limited Resource Server: Fedora vs. Ubuntu Linux [22]

P10 MySQL & NoSQL from a PHP Perspective [23]

P11 Getting Started with MongoDB and PHP [24]

P12 Schema-Free MySQL vs NoSQL [25]

Tabell 1: Funna artiklar i litteraturstudie

4.2 Resultat och diskussion

(10)

Fråga Relaterade artiklar

RQ1. P1[3], P2[15], P4[17], P5[18], P8[21], P12[25] RQ2. P1[3], P2[15], P8[21]

RQ3. P2[15], P9[22]

Tabell 2: Artiklar relaterade till forskningsfrågor

4.2.1 RQ1. Vilka jämförelser av Sql och NoSql-databaser finns redan och hur utformades de?

Tabell 2 visar att det finns ganska många artiklar som på något sätt jämför Sql med NoSql. De flesta ar-tiklar som jämför databaser handlar om samma databastyp, dvs NoSql vs NoSql eller SQL vs SQL. I de flesta av de artiklar som hittats ligger inte fokus på själva jämförelsen mellan SQL och NoSql men den är oftast nödvändig för att ge läsaren tillräkligt med bakgrundskunskap om skillnaderna mellan dem. I sådana artiklar görs heller inga detaljerade experiment mellan databastyperna utan jämförelsen består mestadels av ren fakta. Henricsson[3] jämför de två NoSql-databaserna MongoDb och CouchDB och för att göra det krävs att läsaren har viss kunskap kring både NoSql och Sql. Därför ges detta som bakgrund innan experimenten genomförs.

Söderberg och Eriksson[15] utför inte heller några experiment när det gäller jämförelse av Sql och NoSql. Arbetet är främst utformat som en litteraturgranskning där de tar upp skillnader mellan NoSql-databaser men även mellan NoSql och Sql. De tar upp för och nackdelar för de olika databaserna och diskuterar vilka användningsområden som lämpar sig för respektive typ. Arbetet innehåller även information om skalbarhet mellan de olika databaserna, detta är dock inte något som detta arbete kommer att lägga fokus på. MySql’s styrka med relationer skapar en svaghet för bland annat webbapplikationer, där hög prioritet är att man kan hämta ned data snabbt ur databasen. Till detta ändamål kan en NoSql-databas vara mer lämpligt att använda. I vårt arbete är det viktigt att testerna inte är “partiska” till en viss databastyp.

Syftet med Seegers[17] arbete är att bygga en skalbar sökrobot för webben. För att kunna implemente-ra en sådan genomförs först en omfattande utvärdering av olika verktyg och även en mängd olika databaser. Bland dem finns både MongoDb och MySql, men det görs ingen direkt jämförelse mellan dem. Denna ut-värdering kan vara mycket relevant för vårt arbete. Alla utut-värderingar bygger på fakta ifrån andra studier som sedan ligger till grund för valet av de verktyg som ska användas för sökroboten. Segeer kommer fram till att MongoDb inte kan användas eftersom molnmiljön där applikationen är tänkt att köras använder ett 32-bitars operativsystem. MongoDb har nämligen en storleksbegränsning på 2Gb i ett 32-bitars system[26]. För att bygga sökroboten används istället MySql som databas. Detta är för att MySql lätt kan integreras mot andra system som är nödvändiga. Detta arbete kommer att utföra experiment med MongoDb på både 32 och 64-bitars os för att se vad skilladerna blir.

Artikel P5 är skriven av Neal Leavitt[18] och är utformad som en tidningsartikel. Inte heller denna arti-kel utför några experiment. Istället används intervjuer men även fakta och historia som huvudsakliga källor. Leavitt tar upp för och nackdelar med både Sql och NoSql-databaser. Sql-databaser kan bli långsamma om de använder komplex tabellstruktur och att använda sql där datatyper kan variera, är inte lämpligt eftersom sql är utformat för att användas med strukturerad data. Leavitt kommer fram till att NoSql-databaser inte kan ersätta relationsdatabaser men är ett bra alternativ för vissa typer av projekt, till exempel när skalbar-het är viktigt för databasen. Skalbarskalbar-het kommer inte att testas i vårt arbete.

(11)

med MongoDb i ett system för att hantera böcker[21]. Det är dock ett relativt litet arbete som utför tester för insättning och filtrering med en datamodell för MongoDb som har relationer likt modellen för MySql. Därmed missar de en del av poängen med NoSql-databaser som inte behöver använda relationer för att på så sätt öka snabbheten. De båda databaserna sätts upp med tabeller/samlingar med likvärdig data, sedan testas prestanda genom att sätta in 100000 element och filtrera ut 2000 element av dessa. Exemplet på hur MongoDB kan ersätta MySQL är relevant för våra tester så att resultaten kan jämföras.

Grigorik[25] visar att det går att använda MySql på liknande sätt som NoSql-databaser, d.v.s. utan för-definierad struktur. Detta är en intressant synvinkel som inte stötts på i någon tidigare artikel. Han menar att MySql har en väldig styrka med relationer, speciellt med databasmotorn InnoDB. Genom att använda MySql-databasen utan schema bevaras denna stryka samtidigt som den inte bryr sig om strukturen för de element som ska sättas in, likt NoSql.

4.2.2 RQ2. Vilken databas presterar snabbast när det gäller att sätta in och filtrera data? Fråga två kommer dels att besvaras genom de experiment som genomförs men litteraturen är också en viktig del för att förklara resultatet och eventuella skillnader samt att kunna stukturera upp detta arbetes experi-ment.

Henricsson[3] utför tester mellan de två databaserna CouchDb och MongoDb. För att ge MySql en vär-dig motståndare, är detta ett bra arbete för att hitta en snabb databas av typen NoSql. De tester som genomförts är insättning av data samt filtrering av olika slag. Testerna liknar, till stor del, de som kommer att genomföras i vårt arbete och ger därför en hel del relevant information hur experiment för databaser kan genomföras. Resultatet från Henricssons arbete visar att MongoDb var betydligt snabbare och vann i stort sett alla tester som genomfördes. Utifrån detta resultat har vi valt just MongoDb som motståndare till MySql. I den litteraturgranskning som Söderberg och Eriksson[15] genomfört vägs de bägge koncepten, NoSql och Sql, mot varandra ur olika perspektiv. Eftersom inga tester genomförs i arbetet går det inte rikitgt att avgöra vilken av databaserna som prestarar snabbast. De säger dock att NoSql är snabbare, speciellt vid filtrering. Eftersom vårt arbete kommer genomföra tester för detta kan vi kanske ge svar på om detta stämmer eller inte. En anledning till att NoSql är snabbare är att datamodellerna oftast är mycket simplare. De har även med lite benchmarking om prestanda där de bl.a. säger att Cassandra kan skriva till ett datalager som tar upp 50 GB på disken på 0,12 millisekunder, mer än 2 500 gånger snabbare än MySQL. Med detta som grund kan vi då fråga: är även MongoDb snabbare än MySql?

Wei-ping m.fl[21] kommer fram till att MongoDb är snabbare än MySql, även om testerna använder re-lationer. Detta visar att relationer i MongDb kanske kan vara bra att använda där det behövs. Arbetet är det enda vi hittat som jämför just MySql och MongoDb, dessutom är det ganska litet. I vårt arbete kommer vi genomföra fler tester och även testa MongoDb utan att använda relationer, för att se om det blir några uppenbara skillnader.

4.2.3 RQ3. Blir det några skillnader på resultatet vid annan uppsättning av miljö?

Precis som tidigare fråga så kommer fråga tre att besvaras med hjälp av experiment, men även att studera de artiklar som handlar om prestanda (se relaterade artiklar i tabell 2).

(12)

enklare att skala en NoSql-databas över flera datorer istället för att lägga pengar på en enda dator med extrem hårdvara. Självklart påverkas resultatet av vilken hårdvara som används. För att visa det kommer vi även att utföra alla tester på olika datorer, med olika hårdvara och opertivsystem.

Experimenten i artikel P9[22] testar prestanda i MySql och utfördes som en klient-server applikation. Tes-terna gick ut på att använda transaktioner för att utföra operationer med 10000, 50000 och 100000 rader i tabellerna. Under tiden mättes prestanda i TPS(Transactions Per Second). För varje test ökade de antalet trådar att använda för att på så sätt utreda hur stor påverkan det har på resultaten. De slutatser man kan dra utifrån arbetet är att val av operativsystem och inställningar påverkar prestandan mycket. MySql server presterar snabbare på Ubuntu 8.04 än Fedora 8 i de flesta situationer. Antalet trådar som används har stor inverkan på cpu och minnesanvändning. Resultaten kan vara värdefulla när vi utvärderar prestandaskillnader mellan MySQL och NoSQL.

5

Utformining av experiment

5.1 Mål

Målet med de experiment som ska genomföras är att ta reda på vilken databas som snabbast sätter in data samt filtrerar data. Givetvis täcker inte de definierade testerna alla olika scenarion som finns men kommer fortfarande att ge en bra bild över hastighetsskillnaderna mellan databaserna. Testerna kommer även att testas på två datorer för att se om ytterligare skillnader uppstår vid olika uppsättningar av miljö.

5.2 Faktorer

Nedan följer faktorer som kan påverka resultetet av experimenten och hur de hanteras.

5.2.1 PHP

Varje databas har sina egna funktioner för att beräkna tid för olika operationer. För att minimera risken att de mätningar som ska utföras blir till fördel för en viss databas har vi tagit beslutet att inte använda dessa funktioner. Istället kommer vi använda unix-kommandot time, men då krävs att experimenten kan köras som ett kommando ifrån en unixterminal där man undviker steget att först starta databasens administra-tionsgränssnitt. För att lösa detta problem kommer php att användas som scriptspråk. Därmed medförs också faktorn att scriptet i sig använder en viss tid, vilket i sin tur gör att databasens tid inte blir exakt. Att tillverka scriptet så att det inte använder någon tid alls är helt omöjligt. Därför kommer php-scriptet att göras så litet som möjligt och vi kommer att se till att scriptets tid varierar minimalt från gång till gång. Vi kommer även att köra varje test 5 gånger och sedan räkna ut medelvärdet för varje testfall och på så vis minimera scriptets påverkan på resultatet.

5.2.2 Operativsystem & Hårdvara

(13)

5.2.3 Olika datamodeller

Eftersom MySql är en relationsdatabas och MongoDb är en NoSql-databas utan relationer, finns risken att resultaten kan bli felaktiga och orättvisa eftersom datamodellen kommer att se olika ut för respektive da-tabas. MongoDb har dock ett sätt att hantera relationer, där man istället för att spara själva värdet i en array i objektet, sparar en referens till ett annat objekt i databasen i en likvärdig array. Eftersom dessa två varianter finns att bygga upp datamodeller på i MongoDb, kommer även relations-varianten att testas i detta arbete.

Exerimenten kommer innehålla att spara ned bilder i databaser, och MongoDb innehåller ett speciellt system för att spara ned filer som kallas för gridFs, och finns beskrivet i sektion GridFs 2.3.1. Tester kommer därför att genomföras både med och utan gridFs för att se ifall det har någon större påverkan.

5.2.4 Datamängder

En annan faktor som kan påverka resultatet vid insert är om databasen redan innehåller data när testerna körs. Det kan t.ex. vara så att det tar längre tid för databasen att sätta in ett nytt element om databasen inte är tom. Detta arbete kommer inte att utföra några experiment som tar hänsyn till denna faktor. Vi anser att påverkan är minimal och därför kommer denna typ av tester endast att utföras på tomma databaser. 5.2.5 Vad för typ av data

Insättning av olika typer av data kan påverka tiden, och för att ta reda på skillnader det kommer tester att genomföras där både databasen får lagra nummer, strängar samt bilder i binär form.

5.2.6 Sätta in all data samtidigt

Både MySql och MongoDb har stöd för att sätta in all data i en enda förfrågning, istället för att göra en förfrågning per objekt som ska läggas till. Experiment kommer utföras både med och utan detta och se eventuella skillnader både mellan typerna och inom samma databas.

5.3 Testmiljö

Genereringen av testdatan kommer att skötas från en ny funktion i ett php-skript och den data som kommer att skapas finns definierad under sektionen Datamodell 5.4. Givetvis kommer detta att påverka den slutgiltiga tiden för exekveringen, men då båda databaserna kommer att få denna extratid, kan den ignoreras vid jäm-förelse av resultatet. För att alltid samma data ska genereras, har vi statiskt angett ett specifikt srand-värde. För att mäta tiderna kommer Unix-kommandot time att användas. Anledningen till att använda detta istället för tiden som man direkt kan få ut från MySql och MongoDb, är att vi vill kunna använda samma tidsfunktion till båda databas-typerna. Detta för att minimera felmarginaler för tiden man kan få fram från respektive databas, då vi inte kan säkerställa att tiden räknas ut på exakt samma sätt. Varje enskild mätning kommer att göras fem gånger, och sedan kommer medelvärdet att räknas ut.

Real: Den faktiskta tiden det tar att exekvera ett kommando, som att använda ett stoppur. User: Visar CPU-tiden, spenderad i "user mode".

Sys: Visar tiden, spenderad i kärnan, "Kernel".

(14)

5.3.1 Systeminformation

Mjukvaran är densamma för båda datorerna förutom operativsystemet: PHP: 5.3.5

MySql: 5.1.62 MongoDb: 2.0.5 Dator 1:

Operativsystem: Ubuntu GNU/Linux 11.04 64 bit Processor: AMD Dual Core 3GHz

Minne: 4 GB Dator 2:

Operativsystem: Ubuntu GNU/Linux 11.04 32 bit Processor: Intel Core 2 Duo 2.67GHz

Minne: 2 GB 5.4 Datamodell

Datamodellerna skiljer sig åt mellan de experiment som ska göras. För insättning kommer det finns två olika tabeller, en för Medlemmar där strängar kommer sparas, samt en bild-tabell där bilder i binär form lagras. MongoDb kommer även testas med gridFs som finns beskrivet under sektion GridFs 2.3.1. Vid testerna för filtrering kommer Mysql ha tabeller för produkter och kategorier, vilket skapar ett många till många-förhållande. Även här kommer MongoDb innehålla två olika lösningar, en helt fri från relationer med endast en tabell och en annan variant med två tabeller. Tabeller med en överblick hur databasmodellen ser ut både för insättning och filtrering finns i bilaga A.

6

Utförande

RQ2 och RQ3 kommer att besvaras genom experiment. Två datorer med olika hårdvara och operativsystem har satts upp för att kunna genomföra tester med både MySql och MongoDb. Under sektion 5.3.1 Syste-minformation, specificeras hårdvaran samt operativsystem som kommer att användas för respektive dator. Databaserna kommer att testas med hjälp av ett php-skript. Kommandot för att exekvera php-sriptet som gör en insättning på 10000 rader i MySql ser ut såhär:

time php insertMySql.php -n 10000 -t i

6.1 Testfall

(15)

6.2 Insättning

Tabell 3 visar testfallen för instättning där två olika datatyper kommer att användas: Member och Image (För mer inormation om datamodellerna se bilaga A.1 och A.2). Experiment kommer också att utföras med multiinsättning (sektion 2.4 Multiinsättning) för 100 000 members och fler. Anledningen till att färre antal inte kommer att testas med detta är att det handlar om så små mängder så multiinsättning inte anses relevant. Kolumnen “antal” anger hur många element som ska sättas in för varje test.

TestId Dator Datatyp Multiinsättning Antal

1 Ubuntu 64 Member nej 1000

2 Ubuntu 64 Image nej 1000

3 Ubuntu 64 Member nej 10 000

4 Ubuntu 64 Image nej 10 000

5 Ubuntu 64 Member nej 100 000

6 Ubuntu 64 Member ja 100 000

7 Ubuntu 64 Member nej 1 000 000

8 Ubuntu 64 Member ja 1 000 000

9 Ubuntu 32 Member nej 1000

10 Ubuntu 32 Image nej 1000

11 Ubuntu 32 Member nej 10 000

12 Ubuntu 32 Image nej 10 000

13 Ubuntu 32 Member nej 100 000

14 Ubuntu 32 Member ja 100 000

15 Ubuntu 32 Member nej 1 000 000

16 Ubuntu 32 Member ja 1 000 000

(16)

6.3 Filtrering

Tabell 4 visar alla testfall som ska köras för filtering. I dessa tester ska används datamodellerna för produkt och kategori som finns beskrivna i bilaga A.3 och A.4. I dessa tester ska alla produkter med en viss kategori filtreras ut. För MongoDb finns två sätt att hantera modellen, antingen med relation till en annan collection, eller att all data finns i en array direkt hos objektet. Tester kommer därför att utföras för båda varianterna. Kolumnen “antal” i tabellen nedan visar hur många element som finns i databasen, som därmed behöver sökas igenom för varje test.

TestId Dator Antal

17 Ubuntu 64 1000 18 Ubuntu 64 10 000 19 Ubuntu 64 100 000 20 Ubuntu 64 1 000 000 21 Ubuntu 64 4 000 000 22 Ubuntu 32 1000 23 Ubuntu 32 10 000 24 Ubuntu 32 100 000 25 Ubuntu 32 1 000 000 26 Ubuntu 32 4 000 000

(17)

7

Resultat

Nedan presenteras resultat från alla tester som genomförts. De tester som är rödmarkerade är sådana som av någon anledning inte kunde fullföljas. De tider som är skrivna med grön text visar den snabbaste tiden för testet. Varje test kördes fem gånger där tiden mättes varje gång, sedan räknades medelvärdet av dessa tider ut och det är den tiden som visas i tabellerna nedan. Alla tider är angivna i sekunder.

7.1 Insättning

Tabell 5 och 6 visar resultat för insättning av medlemmar och bilder på de olika datorerna. Kolumnen “Antal” anger hur många element som sattes in i databasen vid respektive test. Vid insättning av bilder genomfördes ett ytterligare test med GridFs för att se om det blev några skillnader. Tabellen visar att användandet av GridFs gjorde att tiden ökade med några sekunder. MongoDb visade sig vara snabbare på de flesta testerna förutom de som använde multiinsättning (sektion 2.4 Multiinsättning). Test nummer 8 och 16 kunde inte genomföras för MongoDb på grund av det finns en 16mb-spärr för objektens storlek. Denna spärr kunde inte heller konfigureras.

7.1.1 Ubuntu 64

TestId Datatyp Antal Multi MySql MongoDb GridFs

1 Member 1000 nej 0,146 0,122 2 Image 1000 nej 3,859 1,353 3,385 3 Member 10 000 nej 0,712 0,310 4 Image 10 000 nej 43,515 50,170 53,603 5 Member 100 000 nej 7,214 3,157 6 Member 100 000 ja 0,874 2,388 7 Member 1 000 000 nej 65,868 34,687 8 Member 1 000 000 ja 7,120 0

(18)

7.1.2 Ubuntu 32

Testerna med GridFs för bilder kunde inte slutföras på grund av storleksbegränsningen för lagring i MongoDb på 2Gb på ett 32-bitarssystem.

TestId Datatyp Antal Multi MySql MongoDb GridFs

9 Member 1000 nej 0,079 0,048 10 Image 1000 nej 4,693 0,788 0 11 Member 10 000 nej 0,479 0,299 12 Image 10 000 nej 47,207 18,327 0 13 Member 100 000 nej 4,432 1,720 14 Member 100 000 ja 0,544 1,763 15 Member 1 000 000 nej 43,965 17,745 16 Member 1 000 000 ja 5,138 0

Tabell 6: Resultat för testerna med insättning på Ubuntu 32 7.2 Filtrering

Tabell 7 och 8 visar resultat från experimenten med filtrering av data. Kolumnen “Antal” anger hur många element som fanns i databasen när testen utfördes och som därmed filtrerades. Eftersom det finns två varianter på att hantera datamodellen i MongoDb testades båda två. Kolumnen “MongoDb Relationer” visar resultaten från testerna med separata collections för relationer mellan produkt och kategori. Kolumnen “MongoDb” visar resultaten från testerna utan relationer. Även här visade det sig att MongoDb är snabbare än MySql och att använda MongoDb utan relationer är snabbast.

7.2.1 Ubuntu 64

TestId Antal MySql MongoDb Relationer MongoDb

17 1000 0,085 0,081 0,076

18 10 000 0,136 0,135 0,120

19 100 000 0,486 0,457 0,416

20 1 00 000 20,616 3,009 2,344

21 4 000 000 82,427 11,826 8,546

(19)

7.2.2 Ubuntu 32

TestId Antal MySql MongoDb Relationer MongoDb

22 1000 0,040 0,036 0,036

23 10 000 0,080 0,051 0,049

24 100 000 0,500 0,208 0,181

25 1 000 000 23,490 1,874 1,600

26 4 000 000 96,136 16,061 14,898

Tabell 8: Resultat för filtrering med insättning på Ubuntu 32

8

Analys och diskussion

Experimentresultaten är väldigt intressanta, de flesta var väntade, men vid insättning var faktiskt MySql snabbare än MongoDb när multi-insert användes. Graferna nedan visar hur resultatet påverkades av antalet element som sätts in eller filtreras. Fler diagram och större format finns i bilaga C.

8.1 Tester som inte kunde genomföras

Tabellerna visar att det var några experiment som inte gick att fullfölja. Anledningen till att test 8 och 16 fal-lerade på MongoDb är att det finns en gräns för objektens storlek på 16mb. Dokumentationen för MongoDb säger att denna begränsning gäller på de enskilda objekten som sparas i databasen. Så verkar dock inte vara fallet utan beräkningen görs på den data som faktiskt skickas till socketen. Detta bekräftas i ett ärende[27] som finns publicerat på Github där MongoDb’s kod finns uppladdad. Experimentet som genomfördes i detta arbete, skulle sätta in ett visst antal element som en så kallad bulk-insert. Vilket betyder att alla element skickas till databasen i en enda request som MongoDb sedan hanterar och lagrar som många objekt. Två dagar innan testen genomfördes släpptes en fix för detta problem men den php-driver som detta arbete använder sig av, verkar inte ha lagt in stöd för detta ännu. Även MySql har en gräns på 16mb men denna kan lätt utökas via en konfigurationsfil, vilket gjordes för experimentet.

De två andra testerna som inte kunde genomföras var insättning av bilder i gridFs på datorn med Ubuntu 32. Alla de tidigare testerna hade slutförts men när dessa skulle köras, uppstod fel som:

MongoDb : can ' t map f i l e memory − mongo r e q u i r e s 64 b i t build f o r l a r g e r d a t a s e t s

(20)

8.2 Analys av resultatet 0 10 20 30 40 50 60 70 1000 10000 100000 10000000 Tid(s) Antal MySql MongoDb

Figur 2: Ubuntu 64, Insättning av data Figur 2 visar tidsskillnaderna mellan MySql och

MongdoDb vid insättning. Diagrammet visar tyd-ligt att MySql tar längre tid på sig än sin konkur-rent, speciellt vid insättningen av det högsta an-talet element som var 1000000st. MongoDb sätter in medlemmarna på drygt 35 sekunder där Mysql gör det på 66 vilket anses som en betydlig ök-ning.

Det är emellertid inte vanligt att databasen behö-ver hantera denna typ av insättning med så mycket samtidig data. Resultatet för insättning av, upp till drygt tiotusen members, ligger på mindre än en se-kund för båda databaserna vilket inte anses speciellt mycket.

Det som däremot går snabbare för MySql är om insättningen sker i en så kallad multiinsert(bulk-insert för MongoDb) där all data sätts in med ett anrop. MongoDb klarade inte ens av att genomföra båda tester-na på grund av den gräns som finns för objekten. Resultaten för 32-bitarsdatorn visar liktester-nande värden, med samma mönster där MySql tar betydligt längre tid på sig att sätta in större mängder data.

0 10 20 30 40 50 60 70 80 90 1000 10000 100000 10000000 40000000 Tid(s) Antal MySql MongoDb utan relationer MongoDb med relationer

Figur 3: Ubuntu 64 : Filtrering av data Även om det inte är vanligt att sätta in större

mäng-der data på en gång, så är det tvärt om när det gäller hämtning och filtrering av information. Den struktur för tabeller/collections som användes under experi-mentet var relativt enkel, men ändå kan man se att MongoDb är betydligt snabbare än MySql.

Vid filtrering av 4 miljoner produkter skiljer det un-gefär 70 sekunder, vilket är en enorm skillnad. Skill-naderna mellan MongoDb med och utan relationer är märkbar, men i detta fallet inte speciellt kritisk, på 4 miljoner data skiljer det sig cirka 3 sekunder vil-ket inte anses speciellt mycvil-ket i jämförelse till Mysql. 8.3 Olika sätt att hantera resultatet

MySql och MongoDb skiljer sig på många punkter,

bland annat hur de hanterar resultatet som skickas ned till klienten, i detta fall till php-scriptet som hanterar testerna. Det som händer när en sökning görs i MongoDb är att data inte skickas ned direkt till applikationen, istället skickas en pekare till resultatet. Fördelen är att klienten då slipper att spara all information i minnet och kan istället hantera varje enskilt dokument, ett i taget, när så önskas. MySql däremot skickar hela resultatet på en gång, vilket kan bli väldigt dyrt för minnet om det handlar om större mängder data. 8.4 Slutsatser

8.4.1 MongDb är snabbare

(21)

endast på 4 miljoner vilket kan ses som väldigt lite i jämförelse till Facebook[1] som i april detta året hade över 900 miljoner aktiva användare[28]. Att göra experiment på sådan stor mängd data skulle med stor sannolikhet styrka argumenten till att använda MongoDb istället för MySql.

8.4.2 MongoDb på ett 32-bitars system

Begränsningarna att köra MongoDb på ett 32-bitarssystem nämns kortfattat på MongoDb’s officiella hemsida[26]. De experiment som genomförts i detta arbete kan bekräfta att databasen inte bör användas på ett 32-bitars system. Databasen kraschade även om testerna höll sig inom gränserna och det finns egentligen inga garantier att det går att reparera eventuella fel som uppstår, så att datan kan återställas och fortfarande användas. Det finns många forum på internet med inlägg av personer som har haft liknande problem och den enda egentliga lösningen som de kommit fram till är att köra MongoDb på ett 64-bitarssystem.

8.5 Validering av resultat

Experimenten har inte körts i något realtidssystem och de tider som presenteras i tabellerna är ett medel-värde från fem körningar. Varje test körs aldrig exakt på lika lång tid utan det varierar från gång till gång. Här är det många faktorer som spelar in, till exempel den nuvarande belastningen på datorn. Även den php-kod som använts för att kommunicera med databaserna påverkar sluttiden då det alltid finns småsaker som aldrig går exakt lika fort. Detta uppstår för de båda databasernas tester och på så sätt är det ingen direkt fara att detta inträffar, det är fortfarande möjligt att jämföraMongoDb och MySql.

Resultaten mellan de olika datorerna kan vara missvisande då tiderna var allt för lika på de allra flesta experimenten. Det fanns ett antagande att dator två skulle genomföra testerna långsammare med tanke på halverat ram-minne, men troligtvis jämnade det ut sig med processorn som den hade och fick istället något snabbare resultat än den första datorn. Rent hårdvarumässigt vore det klokare att ha större skillnader på hårdvaran, för att kunna dra några slutsatser.

8.6 Kopplingar till tidigare arbeten

Litteraturstudien visar att intresset för NoSql-databaser är stort, dock visade det sig att rena jämförelser mellan SQL och NoSql inte förekom speciellt ofta. Anledningen till detta är antagligen att NoSql fortfarande är ett relativt nytt begrepp i databasvärden. Det märktes också i de tester som utfördes, att MongoDb inte är lika pålitiligt som MySql, vilket kan bero på att MongoDb är så pass nytt.

Resultaten i detta arbete kan bekräfta ett tidigare arbete som visar att MongoDb är snabbare än MySql[21], åtminstone i de fall som dessa experimenten täcker. Det stärker även påståenden om att NoSql-databaser generellt är snabbare än relationsdatabaser[18]. Detta arbete har dock inte alls fokuserat på säkerhet i data-baserna, men det finns svagheter i NoSql som är viktiga att ta i beaktning[20]. Oracle publicerade en artikel som vi trodde skulle ta upp och diskutera nackdelar med NoSql[19]. Det visade sig dock att artikeln mest handlade om att lyfta upp fördelar med Oracles lösningar och inte så mycket om generella brister med NoSql. 8.7 Framtida arbete

(22)

60 dagar så finns totalt 300000 raders historik. Ett testfall skulle då kunna vara att lista alla produkter med dess kategorier och det senaste priset, eller visa prisutveckling för produkterna den senaste månaden. Tiden borde, rent teoretiskt sett, öka drastiskt.

Figur 4: Exempel hur en relation mellan produkter, kategorier och pris kan se ut.

Det hade även varit intressant att göra ytterligare tester mellan olika datorer, men då med större skillnader på hårdvara än de system som detta arbete använt sig av. Att det inte rekommenderas att köra ett 32-bitars system för MongoDb är ett faktum, som även de tester som genomförts i detta arbete kan bekräfta. Det vore därför bättre om man använder 64-bitar på alla de system som ska jämföras. Mer fokus bör läggas på den faktiska hårdvaran och inte bara ta hänsyn till hur mycket minne utan även hastigheten på dem. Förutom ram och processor bör även hastighet och vilket filsystem som håddiskarna använder sig av, tas hänsyn till. Ett annat experiment skulle kunna vara att testa databaserna på 32 vs 64-bitarssystem som har exakt samma hårdvara för att på så sätt redogöra alla skillnader som enbart beror på denna faktor. Dock lämpar sig detta inte för stora mängder data eftersom MongoDb då inte kan testas fullt ut.

9

Sammanfattning

I de fallen som detta arbetet täcker visar att vid byte från MySql till MongoDb är det möjligt att få en betydligt snabbare databas, med en relativt lik struktur. Tiden för filtrering av 4 miljoner produkter för Ubuntu 64 (tabell 7) skiljer sig drygt 70 sekunder mellan databaserna och sedan är den helt relationsfria lösningen för MongoDb några sekunder snabbare.

Testerna visar dock att skillnaderna mellan lösningen med och utan relationer för MongoDb inte är nämnvärt stor så i detta fallet vinner man nog mer att köra alternativet med relationer, då det till exempel räcker att byta kategori-namn på ett ställe istället för på varje enskild produkt tack vare kopplingen med id-nummer. Det är dessutom väldigt lätt att komma igång med MongoDb, precis som för Mysql finns det stöd till de allra flesta populära programspråken[29].

(23)

en av idéerna med en icke relationsdatabas. Det kan finnas de fall då det är nödvändigt att använda sig av bland annat främmande nycklar för att säkerhetsställa att databasen är konsistent, och då är det fortfarande MySql som bör användas.

(24)

Referenser

1. Facebook.

http://facebook.com. 2. Twitter.

http://twitter.com.

3. Robin Henricsson. Document Oriented NoSQL Databases - A comparison of performance in MongoDB and CouchDB using a Python interface.

http://www.bth.se/fou/cuppsats.nsf/all/32737dee280f07ddc12578b200454a24/$file/ BTH2011Henricsson.pdf, 2011.

4. Oracle Corporation. http://www.mysql.com/.

5. Oracle Corporation. SELECT Syntax.

http://dev.mysql.com/doc/refman/5.6/en/select.html. 6. Oracle Corporation. FOREIGN KEY Constraints.

http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html. 7. 10gen, MongoDb. MongoDb.

http://www.mongodb.org/. 8. Bsonspec.org. Bson.

http://bsonspec.org/. 9. 10gen, MongoDb. Object IDs.

http://www.mongodb.org/display/DOCS/Object+IDs. 10. 10gen, MongoDb. GridFs.

http://www.mongodb.org/display/DOCS/GridFS. 11. 10gen, MongoDb. Bulk inserts.

http://www.mongodb.org/display/DOCS/Inserting#Inserting-Bulkinserts.

12. D. Crockford. The application/json Media Type for JavaScript Object Notation (JSON). http://www.ietf.org/rfc/rfc4627.txt, 2006.

13. The PHP group. http://php.net.

14. The PHP group. Using PHP from the command line. http://php.net/manual/en/features.commandline.php.

15. Natalja Söderberg/Jan Eriksson. Utredning av NoSQL-databaser för Sogeti i Gävle. http://juseknew.episerverhotell.net/upload/PDF/diverse/NoSQLdatabaser.pdf, 2010.

16. Carlos André Reis Fernandes Oliveira da Silva. Data Modeling with NoSQL: How, When and Why. http://repositorio-aberto.up.pt/bitstream/10216/61586/1/000148158.pdf, 2011.

17. Marc Seeger. Building blocks of a scalable webcrawler.

http://blog.marc-seeger.de/assets/papers/thesis_seeger-building_blocks_of_a_scalable_ webcrawler.pdf, 2010.

18. Neal Leavitt. Will NoSQL databases live up to their promise? 2010. http://www.leavcom.com/pdf/NoSQL.pdf.

19. Alan Downing. Debunking the NoSQL Hype. 2011.

http://ftp-developpez.com/gordon-fowler/Debunking%20the%20NoSQL%20Hype%20Oracle.pdf.

20. Lior Okman, Nurit Gal-Oz, Yaron Gonen, Ehud Gudes, Jenny Abramov. Security Issues in NoSQL Databases. 2011 IEEE 10th International Conference on Trust, Security and Privacy in Computing and Communications (TrustCom 2011), 2011.

21. Zhu Wei-ping, Li Ming-xin, Chen Huan. Using MongoDB to implement textbook management system instead of MySQL. 2011 IEEE 3rd International Conference on Communication Software and Networks (ICCSN 2011), 2011.

22. Mohiuddin Ahmed, Mohammad Moshee Uddin, Md. Saiful Azad, Shariq Haseeb. MySQL performance analysis on a limited resource server: Fedora vs. Ubuntu Linux. SpringSim ’10 Proceedings of the 2010 Spring Simulation Multiconference, 2010.

23. Tim Juravich. MySQL & NoSQL from a PHP perspective.

http://www.slideshare.net/timjuravich/mysql-nosql-from-a-php-perspective, 2011. 24. Vikram Vaswani. Getting Started with MongoDB and PHP.

(25)

25. Ilya Grigorik. Schema-Free MySQL vs NoSQL.

http://www.igvita.com/2010/03/01/schema-free-mysql-vs-nosql/, 2010. 26. 10gen, MongoDb. 32 bit limitations.

http://blog.mongodb.org/post/137788967/32-bit-limitations. 27. Github. maxBsonSize checked on command, not individual documents.

https://github.com/mongodb/node-mongodb-native/issues/609.

28. Mark Hachman. Facebook Now Totals 901 Million Users, Profits Slip. 2012. http://www.pcmag.com/article2/0,2817,2403410,00.asp.

29. 10gen, MongoDb. Drivers.

(26)

A

Datamodeller

A.1 MySql - Insättning

Member

Fält Typ Värdemängd

firstName Varchar(15) En Sträng mellan 2 och 12 tecken

lastName Varchar(15) En Sträng mellan 2 och 12 tecken

username Varchar(15) En Sträng mellan 2 och 12 tecken

age Int 10-99

Image

Fält Typ Värdemängd

id Int 1 till MAX id

image MediumBlob Bild i binär form

A.2 MongoDb - Insättning

Member

Fält Typ Värdemängd

firstName Sträng En Sträng mellan 2 och 12 tecken

lastName Sträng En Sträng mellan 2 och 12 tecken

username Sträng En Sträng mellan 2 och 12 tecken

age Int 10-99

Image

Fält Typ Värdemängd

(27)

A.3 MySql - Filtrering

Product

Fält Typ Värdemängd

id Int 1 till MAX id

title Varchar(15) En Sträng mellan 2 och 12 tecken

description Text En Sträng mellan 0 och 200 tecken

quantity Int Nummer mellan 0 och 1000

Category

Fält Typ Värdemängd

id Int 1 till MAX id

title Varchar(15) En Sträng mellan 2 och 12 tecken

ProductCategory

Fält Typ Värdemängd

productId Int Id till en existerande produkt

(28)

A.4 MongoDb - Filtrering

A.4.1 Med relationer Product

Fält Typ Värdemängd

id Int 1 till MAX id

title Varchar(15) En Sträng mellan 2 och 12 tecken

description Text En Sträng mellan 0 och 200 tecken

quantity Int Nummer mellan 0 och 1000

productCategory Array Array med kategorier som

innehål-ler objektId’n till rader som finns i kategori-tabellen

Category

Fält Typ Värdemängd

title Varchar(15) En Sträng mellan 2 och 12 tecken

A.4.2 Utan relationer Product

Fält Typ Värdemängd

title Varchar(15) En Sträng mellan 2 och 12 tecken

description Text En Sträng mellan 0 och 200 tecken

quantity Int Nummer mellan 0 och 1000

(29)

B

Källkod

Listing 3: generateData.php <?php define("MIN_AGE",10) ; define("MAX_AGE",99) ; define("MIN_QUANTITY",0) ; define("MAX_QUANTITY",1000) ; define("VARCHAR_MIN", 2) ; define("VARCHAR_MAX", 12) ; define("TEXT_MIN", 0) ; define("TEXT_MAX", 200) ; define("CATEGORIES_MIN", 1) ; define("CATEGORIES_MAX", 10) ; define("CATEGORY", "Ee") ; define("NROFCATEGORIES", 200) ; define('FILE', 'data.txt') ;

define('IMAGE', 'bth-logga.jpg') ;

$chars = "0123456789 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

srand(1234) ;

// Generate random string with an exaclty length f u n c t i o n rand_string($length) { g l o b a l $chars; $ s t r = ""; $ s i z e = s t r l e n($chars) ; f o r($ i = 0 ;$ i < $length; $ i++ ) { $ s t r .= $chars[rand(0 ,$ s i z e − 1) ] ; } return $ s t r; }

// Generate random string between min and max f u n c t i o n rand_string_between($min,$max) {

$length = rand($min,$max) ;

return rand_string($length) ; }

// Generate Member

f u n c t i o n generate_member( ) { $member = array( ) ;

$member["firstName"] = rand_string_between(VARCHAR_MIN,VARCHAR_MAX) ; $member["username"] = rand_string_between(VARCHAR_MIN,VARCHAR_MAX) ; $member["lastName"] = rand_string_between(VARCHAR_MAX,VARCHAR_MAX) ; $member["age"] = rand(MIN_AGE,MAX_AGE) ;

return $member; }

(30)

$category = array( ) ;

$category["title"] = rand_string_between(VARCHAR_MIN, VARCHAR_MAX) ; return $category; } f u n c t i o n g e n e r a t e _ c a t e g o r i e s( ) { $ c a t e g o r i e s = array( ) ; f o r($ i = 0 ; $ i < NROFCATEGORIES; $ i++) { array_push($ c a t e g o r i e s ,generate_category( ) ) ; } return $ c a t e g o r i e s; } f u n c t i o n g e ner a te _ c at e g o rie s_ i d s( ) {

$nrOfCats = rand(CATEGORIES_MIN, CATEGORIES_MAX) ;

$ c a t e g o r i e s I d s = array( ) ;

$count = 0 ;

while($count < $nrOfCats ) { $id = rand(1 ,NROFCATEGORIES) ;

i f ( !in_array($id, $ c a t e g o r i e s I d s) ) { array_push($ c a t e g o r i e s I d s ,$id) ; $count++; } } return $ c a t e g o r i e s I d s; } // Generate product f u n c t i o n generate_product( ) { $product = array( ) ;

$product["title"] = rand_string_between(VARCHAR_MIN, VARCHAR_MAX) ;

$product["description"] = rand_string_between(TEXT_MIN,TEXT_MAX) ; $product["quantity"] = rand(MIN_AGE,MAX_AGE) ;

return $product; } ?> Listing 4: insertMysql.php <?php require_once("generateData.php") ;

define('DB_HOST', 'localhost') ; define('DB_NAME', 'thesis') ; define('DB_USER', 'thesis') ; define('DB_PASSWORD', 'wip') ;

(31)

die("ERROR: Database Connection failed , Mysql Message: ".$this−>db−> connect_error) ;

}

// Force Utf -8 communication $db−>set_charset('utf8') ;

// Get parameters from commandline $options = getopt("t:n:") ;

i f ( !i s s e t($options["n"] ) | | !i s s e t($options["t"] ) | | !is_numeric($options["n"

] ) ) {

die("ERROR: Optionsparameters is invalid!\n") ;

}

define("TYPE",$options["t"] ) ; define("NROFLOOPS",$options["n"] ) ;

// Generate data and save to file i f(TYPE == "g") {

i f (f i l e _ e x i s t s(FILE) ) {

unlink(FILE) ; }

$handle = fopen(FILE, 'w') or die('Cannot open file: '.FILE) ; f o r($ i=0;$ i < NROFLOOPS; $ i++ ) {

$member = generate_member( ) ;

$query = "INSERT INTO Member (firstName , lastName , username , age) VALUES('".$member["firstName"] ."', '".$member["lastName"] ."', '". $member["username"] ."', '".$member["age"] ."');";

f w r i t e($handle, $query."\n") ; } f c l o s e($handle) ; } i f(TYPE == "gm") { i f (f i l e _ e x i s t s(FILE) ) { unlink(FILE) ; }

$handle = fopen(FILE, 'w') or die('Cannot open file: '.FILE) ;

$query = "INSERT INTO Member (firstName , lastName , username , age) VALUES";

f o r($ i=0;$ i < NROFLOOPS; $ i++ ) {

$member = generate_member( ) ;

$query.="('".$member["firstName"] ."', '".$member["lastName"] ."', '". $member["username"] ."', '".$member["age"] ."'),";

}

$query = substr($query, 0 , −1) ; f w r i t e($handle, $query."\n") ; f c l o s e($handle) ;

}

(32)

e l s e i f(TYPE == "i") {

i f ( !f i l e _ e x i s t s(FILE) ) {

die("ERROR: Please run setup first to create data file!") ;

}

$handle = fopen(FILE, "r") ;

i f($handle) {

while( ($ b u f f e r = f g e t s($handle, 4096) ) !== f a l s e) {

$db−>query($ b u f f e r) or die($db−>e r r o r) ; }

i f ( !f e o f($handle) ) {

echo "Error: unexpected fgets() fail\n";

}

f c l o s e($handle) ;

// Clear data file

echo "Insert complete!";

unlink(FILE) ; }

}

e l s e i f(TYPE == "im") {

i f ( !f i l e _ e x i s t s(FILE) ) {

die("ERROR: Please run setup first to create data file!") ;

}

$ b u f f e r=file_get_contents(FILE) ;

$db−>query($ b u f f e r) or die($db−>e r r o r) ; // Clear data file

echo "Insert complete!";

}

// Save images

e l s e i f(TYPE == "img") { i f( !f i l e _ e x i s t s(IMAGE) ) {

die("ERROR: Image not found!") ;

}

$image = chunk_split(base64_encode(file_get_contents(IMAGE) ) ) ; f o r($ i=0;$ i < NROFLOOPS; $ i++ ) {

$query = "INSERT INTO Image (image) VALUES('$image ')"; $db−>query($query) or die($db−>e r r o r) ;

(33)

// select a collection

$ c o l l e c t i o n = $db−>Members; $ c o l l e c t i o n I m a g e = $db−>image;

$grid = $db−>getGridFS( ) ; // Get parameters from commandline $options = getopt("t:n:") ;

i f ( !i s s e t($options["n"] ) | | !i s s e t($options["t"] ) | | !is_numeric($options["n"

] ) ) {

die("ERROR: Optionsparameters is invalid!\n") ;

}

define("NROFLOOPS",$options["n"] ) ; define("TYPE",$options["t"] ) ;

// Generate data and save to file i f(TYPE == "g") {

i f (f i l e _ e x i s t s(FILE) ) {

unlink(FILE) ; }

$handle = fopen(FILE, 'w') or die('Cannot open file: '.FILE) ; f o r($ i=0;$ i < NROFLOOPS; $ i++ ) { $member = generate_member( ) ; f w r i t e($handle, s e r i a l i z e($member) ."\n") ; } f c l o s e($handle) ; }

// Read from file and insert data to database e l s e i f(TYPE == "i") {

i f ( !f i l e _ e x i s t s(FILE) ) {

die("ERROR: Please run setup first to create data file!") ;

}

$handle = fopen(FILE, "r") ;

i f($handle) {

while( ($ b u f f e r = f g e t s($handle, 4096) ) !== f a l s e) {

$ c o l l e c t i o n−>i n s e r t(u n s e r i a l i z e($ b u f f e r) ) ; }

i f ( !f e o f($handle) ) {

echo "Error: unexpected fgets() fail\n";

}

f c l o s e($handle) ;

// Clear data file

echo "Insert complete!";

unlink(FILE) ; } } // BatchInsert eq MultiQuery e l s e i f(TYPE == "im") { i f ( !f i l e _ e x i s t s(FILE) ) {

(34)

}

$handle = fopen(FILE, "r") ;

$members = array( ) ; i f($handle) { while( ($ b u f f e r = f g e t s($handle, 4096) ) !== f a l s e) { array_push($members, u n s e r i a l i z e($ b u f f e r) ) ; } i f ( !f e o f($handle) ) {

echo "Error: unexpected fgets() fail\n";

}

f c l o s e($handle) ;

// Insert all members

$ c o l l e c t i o n−>b a t c h I n s e r t($members) ; // Clear data file

echo "batchInsert complete!";

unlink(FILE) ; } } // Save image e l s e i f(TYPE == "img") { i f( !f i l e _ e x i s t s(IMAGE) ) {

die("ERROR: Image not found!") ;

}

$arr = array( ) ;

$ r e f = &$arr;

$arr["image"] = chunk_split(base64_encode(file_get_contents(IMAGE) ) ) ; f o r($ i=0;$ i < NROFLOOPS; $ i++ ) {

$ s t a t u s = $ c o l l e c t i o n I m ag e−>i n s e r t($ r e f) ; }

}

// Save image grid fs e l s e i f(TYPE == "fsimg") {

i f( !f i l e _ e x i s t s(IMAGE) ) {

die("ERROR: Image not found!") ;

}

//$image = chunk_split(base64_encode(file_get_contents(IMAGE))); $fileName = "Image";

f o r($ i=0;$ i < NROFLOOPS; $ i++ ) {

// Note metadata field & filename field $ s t o r e d f i l e = $grid−>s t o r e F i l e(IMAGE,

array("metadata" => array("filename" => $fileName) ,

"filename" => $fileName) ) ; }

} ?>

(35)

<?php

require_once("generateData.php") ;

define('DB_HOST', 'localhost') ; define('DB_NAME', 'thesis') ; define('DB_USER', 'thesis') ; define('DB_PASSWORD', 'wip') ;

$db = new mysqli(DB_HOST,DB_USER,DB_PASSWORD,DB_NAME) ; i f ($db−>connect_errno) {

die("ERROR: Database Connection failed , Mysql Message: ".$this−>db−> connect_error) ;

}

// Force Utf -8 communication $db−>set_charset('utf8') ;

// Get parameters from commandline $options = getopt("t:n:") ;

i f ( !i s s e t($options["n"] ) | | !i s s e t($options["t"] ) | | !is_numeric($options["n"

] ) ) {

die("ERROR: Optionsparameters is invalid!\n") ;

}

define("TYPE",$options["t"] ) ; define("NROFLOOPS",$options["n"] ) ;

i f(TYPE == "q") {

$query = "SELECT Product . * , Category . * FROM ProductCategory

INNER JOIN Product ON ProductCategory.productId = Product.id

LEFT OUTER JOIN Category ON ProductCategory.categoryId = Category.id WHERE Category.title = '" .CATEGORY."'";

$db−>query($query) or die($db−>e r r o r) ; }

// Generate data

e l s e i f(TYPE == "g") { //Insert all categories

$ c a t e g o r i e s = g e n e r a t e _ c a t e g o r i e s( ) ;

foreach ($ c a t e g o r i e s as $category) {

$query = "INSERT INTO Category (title) VALUES('".$category["title"] ."');"; $db−>query($query) or die($db−>e r r o r) ; }

// Generate products

f o r($ i=0;$ i < NROFLOOPS; $ i++ ) {

(36)

$query = "INSERT INTO Product (title , description , quantity)

VALUES('".$product["title"] ."', '".$product["description"] ."', '". $product["quantity"] ."');";

$db−>query($query) or die($db−>e r r o r) ;

$productId = $db−>i n s e r t _ i d;

$ c a te g o r y I ds = g e ne r ate_ c at eg or ie s_id s( ) ;

foreach ($ c a t e go r y I ds as $categoryId) {

$query = "INSERT INTO ProductCategory (productId , categoryId) VALUES('".$productId."', '".$categoryId."');";

$db−>query($query) or die($db−>e r r o r) ; }

} }

//Clear data

e l s e i f(TYPE == "c") {

$db−>query("TRUNCATE TABLE Product") or die($db−>e r r o r) ;

$db−>query("TRUNCATE TABLE ProductCategory") or die($db−>e r r o r) ; $db−>query("TRUNCATE TABLE Category") or die($db−>e r r o r) ;

} ?> Listing 7: queryMongoDb.php <?php require_once("generateData.php") ; // connect $m = new Mongo( ) ; // select a database $db = $m−>t h e s i s; // select a collection $ c o l l e c t i o n C a t e g o r y = $db−>Category; $ c o l l e c t i o n P r o d u c t = $db−>Product; // Get parameters from commandline $options = getopt("t:n:") ;

i f ( !i s s e t($options["n"] ) | | !i s s e t($options["t"] ) | | !is_numeric($options["n"

] ) ) {

die("ERROR: Optionsparameters is invalid!\n") ;

}

(37)

// Generate data with relations and insert into database i f(TYPE == "g") { $ i n s e r t e d C a t e g o r i e s = array( ) ; $ c a t e g o r i e s = g e n e r a t e _ c a t e g o r i e s( ) ; foreach($ c a t e g o r i e s as $cat) { $ c o l l e c t i o n C a t e g o r y−>i n s e r t($cat) ; array_push($ i n s e r t e d C a t e g o r i e s , $cat) ; } f o r($ i=0; $ i < NROFLOOPS; $ i++ ) { $product = generate_product( ) ; $productCategoryIds = g e ne ra te _ ca te go ri e s_i ds( ) ; $productCategoryArray = array( ) ;

foreach($productCategoryIds as $catId) {

$currentCat = $ i n s e r t e d C a t e g o r i e s[$catId−1];

array_push($productCategoryArray, $currentCat['_id'] ) ;

}

$product['productCategory'] = $productCategoryArray; $ c o l l e c t i o n P r o d u c t−>i n s e r t($product) ;

} }

// Generate data for noqsl standard way and insert inte database i f(TYPE == "g2") {

$ i n s e r t e d C a t e g o r i e s = array( ) ;

$ c a t e g o r i e s = g e n e r a t e _ c a t e g o r i e s( ) ;

f o r($ i=0; $ i < NROFLOOPS; $ i++ ) {

$product = generate_product( ) ;

$productCategoryIds = ge ne r at e _cat e go rie s_ ids( ) ; $productCategoryArray = array( ) ;

foreach($productCategoryIds as $catId) {

$currentCat = $ c a t e g o r i e s[$catId−1];

array_push($productCategoryArray, $currentCat['title'] ) ;

}

$product['productCategory'] = $productCategoryArray; $ c o l l e c t i o n P r o d u c t−>i n s e r t($product) ;

} }

// clear all data in database e l s e i f(TYPE == "c") {

$ c o l l e c t i o n P r o d u c t−>remove( ) ; $ c o l l e c t i o n C a t e g o r y−>remove( ) ; }

// query database relational e l s e i f(TYPE == "q") {

$categoryObject = $ c o l l e c t i o n C a t e g o r y−>f i n d(array('title' =>CATEGORY) ) ; foreach ($categoryObject as $doc) {

$cursor = $ c o l l e c t i o n P r o d u c t−>f i n d(array('productCategory' => $doc['

(38)

}

$result Ar r ay = iterator_to_array($cursor) ; }

// query database not relational e l s e i f(TYPE == "q2") {

$cursor = $ c o l l e c t i o n P r o d u c t−>f i n d(array('productCategory' =>CATEGORY) ) ;

$ resul t Ar r ay = iterator_to_array($cursor) ; }

(39)

C

Diagram

C.1 Insättning av data Ubuntu 64

0 10 20 30 40 50 60 70 1000 10000 100000 10000000 Tid(s) Antal MySql MongoDb

C.2 Insättning av data Ubuntu 32

(40)

C.3 Filtrering av data Ubuntu 64 0 10 20 30 40 50 60 70 80 90 1000 10000 100000 10000000 40000000 Tid(s) Antal MySql MongoDb utan relationer MongoDb med relationer

C.4 Filtrering av data Ubuntu 32

References

Related documents

Vår reflektion kring detta kan kopplas till den studie Adamson (1999) gjort där hon talar om att den separation från vuxna Eriksson benämner inte haft så stor betydelse för de unga

Experimentet görs för att påvisa vilken databas, MySQL eller MongoDB som uppdaterar data snabbast när det kommer till en realtidsbaserad kollaborativ

Vad uppfattar vi då som återkommande strategier hos Pia under det egna arbetet? När Pia talar med enskild elev, finns det vissa samtalsområden som återkommer. Ett av dem handlar

Diagnosis Clinical Prediction Guide Broad Narrow Broad Narrow Broad Narrow Broad Narrow Broad Narrow deep vein thrombosis 12166 3333 28459 2227 26308 3268 22434 1110 9529 253 deep

MongoDB beat MySQL Document Store when selecting multiple documents with different amounts of data in the database.. Selecting 10 3 -10 5 documents MySQL actually

Undersökningen visar att eleverna inte tycker att de fått bestämma särskilt mycket i arbetet med föreställningen, men är trots detta ganska nöjda - endast en elev skulle ha

Det visade sig vara svårt för exempelvis en bibliotekarie som inte besitter digital kompetens eller intresse för digital delaktighet att se sin roll i arbetet med den

vården (Leininger &amp; MacFarland, 2002, s. I litteraturstudiens resultat framkom att den största utmaningen sjuksköterskor stötte på i den transkulturella omvårdnaden