Webapps kan deles i to hovedkomponenter: en frontend som viser og samler informasjon, og en back-end for lagring av informasjonen. I denne artikkelen vil jeg demonstrere hva en relasjonsdatabase er, og hvordan du skal designe databasen din riktig for å lagre appens informasjon.
En database lagrer data på en organisert måte slik at den kan søges og hentes senere. Den skal inneholde en eller flere tabeller. Et bord er som et regneark, fordi det består av rader og kolonner. Alle rader har de samme kolonnene, og hver kolonne inneholder dataene i seg selv. Hvis det hjelper, tenk på bordene dine på samme måte som du ville ha et bord i Excel.
Figur 1
Data kan settes inn, hentes, oppdateres og slettes fra en tabell. Ordet, opprettet, brukes vanligvis i stedet for innsatt, så samlet sett er disse fire funksjonene kjærlig forkortet som CRUD.
En relasjonsdatabase er en type database som organiserer data i tabeller, og lenker dem, basert på definerte relasjoner. Disse forholdene gjør at du kan hente og kombinere data fra en eller flere tabeller med en enkelt spørring.
Men det var bare en masse ord. For å virkelig forstå en relasjonsdatabase, må du lage en selv. La oss begynne med å få noen virkelige data som vi kan jobbe med.
I ånden til Nettuts + Twitter klonartikler (PHP, Ruby on Rails, Django), la oss få noen Twitter-data. Jeg søkte Twitter på "#databases" og tok følgende utvalg av ti tweets:
Tabell 1
fullt navn | brukernavn | tekst | created_at | following_username |
---|---|---|---|---|
"Boris Hadjur" | "_DreamLead" | "Hva synes du om #emailing #campaigns #traffic i #USA? Er det et godt marked i dag? Har du # databaser?" | "Tirsdag, 12 feb 2013 08:43:09 +0000" | "Scootmedia", "MetiersInternet" |
"Gunnar Svalander" | "GunnarSvalander" | "Bill Gates Talks Databaser, Gratis Programvare på Reddit http://t.co/ShX4hZlA #billgates #databases" | "Tirsdag, 12 feb 2013 07:31:06 +0000" | "klout", "zillow" |
"GE-programvare" | "GEsoftware" | "RT @ KirkDBorne: Lesinger i #Databaser: utmerket leseliste, mange kategorier: http://t.co/S6RBUNxq via @rxin Fascinerende." | "Tirsdag, 12 feb 2013 07:30:24 +0000" | "DayJobDoc", "byosko" |
"Adrian Burch" | "Adrianburch" | "RT @tisakovich: @NimbusData på @Barclays Big Data konferansen i San Francisco i dag, snakker #virtualization, #databases og #flash minne." | "Tirsdag, 12 feb 2013 06:58:22 +0000" | "CindyCrawford", "Arjantim" |
"Andy Ryder" | "AndyRyder5" | "http://t.co/D3KOJIvF artikkel om Madden 2013 ved hjelp av AI til prodict super bowl #databases # bus311" | "Tirsdag, 12 feb 2013 05:29:41 +0000" | "MichaelDell", "Yahoo" |
"Andy Ryder" | "AndyRyder5" | "http://t.co/rBhBXjma en artikkel om personverninnstillinger og facebook #databases # bus311" | "Tirsdag, 12 feb 2013 05:24:17 +0000" | "MichaelDell", "Yahoo" |
"Brett Englebert" | "Brett_Englebert" | "# BUS311 University of Minnesota NCFPD skaper #databases for å hindre" mat svindel. "Http://t.co/0LsAbKqJ" | "Tirsdag, 12 feb 2013 01:49:19 +0000" | "RealSkipBayless", "stephenasmith" |
Brett Englebert | "Brett_Englebert" | "# BUS311 selskaper kan beskytte sin produksjon #databaser, men hva med deres backupfiler? Http://t.co/okJjV3Bm" | "Tirsdag, 12 feb 2013 01:31:52 +0000" | "RealSkipBayless", "stephenasmith" |
"Nimbus Data Systems" | "NimbusData" | "@NimbusData CEO @tisakovich @BarclaysOnline Big Data konferanse i San Francisco i dag, snakker #virtualization, # databaser, og # flash minne" | "Ma, 11 feb 2013 23:15:05 +0000" | "dellock6", "rohitkilam" |
"SSWUG.ORG" | "SSWUGorg" | "Ikke glem å registrere deg for vår GRATIS utstilling denne fredag: #Databases, #BI og #Sharepoint: Hva du trenger å vite! Http://t.co/Ijrqrz29" | "Ma, 11 feb 2013 22:15:37 +0000" | "drsql", "steam_games" |
Her er hva hvert kolonnens navn betyr:
MySQL brukes på omtrent alle Internett-selskaper du har hørt om.
Dette er alle ekte data; du kan søke på Twitter og faktisk finne disse tweets.
Dette er bra. Dataene er alt på ett sted; så det er lett å finne, ikke sant? Ikke akkurat. Det er et par problemer med dette bordet. For det første er det repeterende data på tvers av kolonner. Kolonnene "brukernavn" og "following_username" er gjentagende, fordi begge inneholder samme type data - Twitter-håndterer. Det er en annen form for gjentakelse i kolonnen "following_username". Feltene skal bare inneholde en verdi, men hvert av feltene "following_username" inneholder to.
For det andre er det repeterende data på tvers av rader.
@ AndyRyder5 og @Brett_Englebert hver tweeted to ganger, så resten av deres informasjon er duplisert.
Duplikater er problematiske fordi det gjør CRUD-operasjonene mer utfordrende. For eksempel vil det ta lengre tid å hente data fordi tiden skulle bli bortkastet gjennom dupliserte rader. Også oppdatering av data ville være et problem; Hvis en bruker endrer sin Twitter-håndtak, må vi finne hver duplikat og oppdatere den.
Gjentatte data er et problem. Vi kan løse dette problemet ved å splitte Tabell 1 inn i separate tabeller. La oss fortsette med å først løse repetisjonen på tvers av kolonneproblemet.
Som nevnt ovenfor, kolonner "brukernavn" og "following_username" i Tabell 1 er repeterende. Denne repetisjonen oppstod fordi jeg prøvde å uttrykke det følgende forholdet mellom brukerne. La oss forbedre oss Tabell 1s design ved å dele den opp i to tabeller: en bare for følgende relasjoner og en for resten av informasjonen.
Fig. 2
Fordi @Brett_Englebert følger @RealSkipBayless, den følgende Tabellen vil uttrykke dette forholdet ved å lagre @Brett_Englebert som "from_user" og @RealSkipBayless som "to_user." La oss gå videre og splitte Tabell 1 inn i disse to tabellene:
Tabell 2: Den følgende bord
FROM_USER | to_user |
---|---|
_DreamLead | Scootmedia |
_DreamLead | MetiersInternet |
GunnarSvalander | Klout |
GunnarSvalander | Zillow |
GEsoftware | DayJobDoc |
GEsoftware | byosko |
adrianburch | Cindy Crawford |
adrianburch | Arjantim |
AndyRyder | MichaelDell |
AndyRyder | Yahoo |
Brett_Englebert | RealSkipBayless |
Brett_Englebert | stephenasmith |
NimbusData | dellock6 |
NimbusData | rohitkilam |
SSWUGorg | drsql |
SSWUGorg | steam_games |
Tabell 3: Den brukere bord
fullt navn | brukernavn | tekst | created_at |
---|---|---|---|
"Boris Hadjur" | "_DreamLead" | "Hva synes du om #emailing #campaigns #traffic i #USA? Er det et godt marked i dag? Har du # databaser?" | "Tirsdag, 12 feb 2013 08:43:09 +0000" |
"Gunnar Svalander" | "GunnarSvalander" | "Bill Gates Talks Databaser, Gratis Programvare på Reddit http://t.co/ShX4hZlA #billgates #databases" | "Tirsdag, 12 feb 2013 07:31:06 +0000" |
"GE-programvare" | "GEsoftware" | "RT @ KirkDBorne: Lesinger i #Databaser: utmerket leseliste, mange kategorier: http://t.co/S6RBUNxq via @rxin Fascinerende." | "Tirsdag, 12 feb 2013 07:30:24 +0000" |
"Adrian Burch" | "Adrianburch" | "RT @tisakovich: @NimbusData på @Barclays Big Data konferansen i San Francisco i dag, snakker #virtualization, #databases og #flash minne." | "Tirsdag, 12 feb 2013 06:58:22 +0000" |
"Andy Ryder" | "AndyRyder5" | "http://t.co/D3KOJIvF artikkel om Madden 2013 ved hjelp av AI til prodict super bowl #databases # bus311" | "Tirsdag, 12 feb 2013 05:29:41 +0000" |
"Andy Ryder" | "AndyRyder5" | "http://t.co/rBhBXjma en artikkel om personverninnstillinger og facebook #databases # bus311" | "Tirsdag, 12 feb 2013 05:24:17 +0000" |
"Brett Englebert" | "Brett_Englebert" | "# BUS311 University of Minnesota NCFPD skaper #databases for å hindre" mat svindel. "Http://t.co/0LsAbKqJ" | "Tirsdag, 12 feb 2013 01:49:19 +0000" |
Brett Englebert | "Brett_Englebert" | "# BUS311 selskaper kan beskytte sin produksjon #databaser, men hva med deres backupfiler? Http://t.co/okJjV3Bm" | "Tirsdag, 12 feb 2013 01:31:52 +0000" |
"Nimbus Data Systems" | "NimbusData" | "@NimbusData CEO @tisakovich @BarclaysOnline Big Data konferanse i San Francisco i dag, snakker #virtualization, # databaser, og # flash minne" | "Ma, 11 feb 2013 23:15:05 +0000" |
"SSWUG.ORG" | "SSWUGorg" | "Ikke glem å registrere deg for vår GRATIS utstilling denne fredag: #Databases, #BI og #Sharepoint: Hva du trenger å vite! Http://t.co/Ijrqrz29" | "Ma, 11 feb 2013 22:15:37 +0000" |
Dette ser bedre ut. Nå i brukere bord (Tabell 3), er det bare en kolonne med Twitter-håndtak. I følgende bord (Tabell 2), er det bare ett Twitter-håndtak per felt i kolonnen "to_user".
Edgar F. Codd, datavitenskaperen som lagde ned det teoretiske grunnlaget for relasjonsdatabaser, kalte dette trinnet for å fjerne repeterende data på tvers av kolonner den første normale form (1NF).
Nå som vi har faste repetisjoner på tvers av kolonner, må vi reparere repetisjoner på tvers av rader. Siden brukerne @ AndyRyder5 og @Brett_Englebert hver tweeted to ganger, blir deres informasjon duplisert i brukere bord (Tabell 3). Dette indikerer at vi må trekke ut tweets og plassere dem i sitt eget bord.
Fig. 3
Som tidligere lagrer "tekst" tweetet selv. Siden kolonnen "created_at" lagrer tidsstempel for tweet, er det fornuftig å trekke det inn i dette bordet også. Jeg inkluderer også en referanse til kolonnen "brukernavn", så vi vet hvem som publiserte tweetet. Her er resultatet av å plassere tweets i sitt eget bord:
Tabell 4: Den tweets bord
tekst | created_at | brukernavn |
---|---|---|
"Hva synes du om #emailing #campaigns #traffic i #USA? Er det et godt marked i dag? Har du # databaser?" | "Tirsdag, 12 feb 2013 08:43:09 +0000" | "_DreamLead" |
"Bill Gates Talks Databaser, Gratis Programvare på Reddit http://t.co/ShX4hZlA #billgates #databases" | "Tirsdag, 12 feb 2013 07:31:06 +0000" | "GunnarSvalander" |
"RT @ KirkDBorne: Lesinger i #Databaser: utmerket leseliste, mange kategorier: http://t.co/S6RBUNxq via @rxin Fascinerende." | "Tirsdag, 12 feb 2013 07:30:24 +0000" | "GEsoftware" |
"RT @tisakovich: @NimbusData på @Barclays Big Data konferansen i San Francisco i dag, snakker #virtualization, #databases og #flash minne." | "Tirsdag, 12 feb 2013 06:58:22 +0000" | "Adrianburch" |
"http://t.co/D3KOJIvF artikkel om Madden 2013 ved hjelp av AI til prodict super bowl #databases # bus311" | "Tirsdag, 12 feb 2013 05:29:41 +0000" | "AndyRyder5" |
"http://t.co/rBhBXjma en artikkel om personverninnstillinger og facebook #databases # bus311" | "Tirsdag, 12 feb 2013 05:24:17 +0000" | "AndyRyder5" |
"# BUS311 University of Minnesota NCFPD skaper #databases for å hindre" mat svindel. "Http://t.co/0LsAbKqJ" | "Tirsdag, 12 feb 2013 01:49:19 +0000" | "Brett_Englebert" |
"# BUS311 selskaper kan beskytte sin produksjon #databaser, men hva med deres backupfiler? Http://t.co/okJjV3Bm" | "Tirsdag, 12 feb 2013 01:31:52 +0000" | "Brett_Englebert" |
"@NimbusData CEO @tisakovich @BarclaysOnline Big Data konferanse i San Francisco i dag, snakker #virtualization, # databaser, og # flash minne" | "Ma, 11 feb 2013 23:15:05 +0000" | "NimbusData" |
"Ikke glem å registrere deg for vår GRATIS utstilling denne fredag: #Databases, #BI og #Sharepoint: Hva du trenger å vite! Http://t.co/Ijrqrz29" | "Ma, 11 feb 2013 22:15:37 +0000" | "SSWUGorg" |
Tabell 5: Den brukere bord
fullt navn | brukernavn |
---|---|
"Boris Hadjur" | "_DreamLead" |
"Gunnar Svalander" | "GunnarSvalander" |
"GE-programvare" | "GEsoftware" |
"Adrian Burch" | "Adrianburch" |
"Andy Ryder" | "AndyRyder5" |
"Brett Englebert" | "Brett_Englebert" |
"Nimbus Data Systems" | "NimbusData" |
"SSWUG.ORG" | "SSWUGorg" |
Etter splittet, den brukere bord (Tabell 5) har unike rader for brukere og deres Twitter-håndterer.
Edgar F. Codd kalte dette trinnet for å fjerne repeterende data på tvers av radene den andre normale form (1NF).
Data kan settes inn, hentes, oppdateres og slettes fra en tabell.
Så langt, Tabell 1 har blitt delt inn i tre nye tabeller: følgende (Tabell 2), tweets (Tabell 4), og brukere (Tabell 5). Men hvordan er dette nyttig? Gjentatte data er fjernet, men nå er dataene spredt over tre uavhengige tabeller. For å hente dataene må vi tegne meningsfulle lenker mellom tabellene. På denne måten kan vi uttrykke spørsmål som "hva en bruker har tweeted og hvem en bruker følger".
Måten å tegne koblinger mellom tabeller er å først gi hver rad i et bord en unik identifikator, betegnet en primærnøkkel, og deretter referere til den primære nøkkelen i den andre tabellen du vil koble til.
Vi har faktisk allerede gjort dette i brukere (Tabell 5) og tweets (Tabell 4). I brukere, Den primære nøkkelen er kolonnen "brukernavn" fordi ingen to brukere vil ha det samme Twitter-håndtaket. I tweets, Vi refererer til denne nøkkelen i kolonnen "brukernavn", så vi vet hvem tweeted hva. Siden det er en referanse, er kolonnen "brukernavn" i tweets kalles en fremmednøkkel. På denne måten knytter "brukernavnet" nøkkelen til brukere og tweets bord sammen.
Er kolonnen "brukernavn" den beste ideen for en primærnøkkel for brukere bord?
På den ene siden er det en naturlig nøkkel - det er fornuftig å søke ved hjelp av et Twitter-håndtak i stedet for å tilordne hver bruker noen numerisk ID og søke på det. På den annen side, hva om en bruker ønsker å endre sitt Twitter-håndtak? Det kan føre til feil hvis primærnøkkelen og alle referanse utenlandske nøkler ikke oppdateres nøyaktig, feil som kan unngås hvis en konstant numerisk ID ble brukt. Til slutt avhenger valget av systemet ditt. Hvis du vil gi brukerne muligheten til å endre brukernavn, er det bedre å legge til en numerisk automatisk inkrementerende "id" -kolonne til brukere og bruk det som primærnøkkel. Ellers bør "brukernavn" gjøre det bra. Jeg vil fortsette å bruke "brukernavn" som primærnøkkel for brukere
La oss gå videre til tweets (Tabell 4). En primærnøkkel skal unikt identifisere hver rad, så hva skal primærnøkkelen være her? Feltet "created_at" virker ikke, fordi hvis to brukere tweet på samme tid, ville deres tweets ha en identisk tidsstempel. "Teksten" har det samme problemet ved at hvis to brukere begge tweet "Hei verden", kunne vi ikke skille mellom rader. Kolonnen "brukernavn" er den utenlandske nøkkelen som definerer lenken med brukere så la oss ikke rote med det. Siden de andre kolonnene ikke er gode kandidater, er det fornuftig her å legge til en numerisk automatisk inkrementerende "id" kolonne og bruke den som primærnøkkel.
Tabell 6: Den tweets bord med en "id" kolonne
id | tekst | created_at | brukernavn |
---|---|---|---|
1 | "Hva synes du om #emailing #campaigns #traffic i #USA? Er det et godt marked i dag? Har du # databaser?" | "Tirsdag, 12 feb 2013 08:43:09 +0000" | "_DreamLead" |
2 | "Bill Gates Talks Databaser, Gratis Programvare på Reddit http://t.co/ShX4hZlA #billgates #databases" | "Tirsdag, 12 feb 2013 07:31:06 +0000" | "GunnarSvalander" |
3 | "RT @ KirkDBorne: Lesinger i #Databaser: utmerket leseliste, mange kategorier: http://t.co/S6RBUNxq via @rxin Fascinerende." | "Tirsdag, 12 feb 2013 07:30:24 +0000" | "GEsoftware" |
4 | "RT @tisakovich: @NimbusData på @Barclays Big Data konferansen i San Francisco i dag, snakker #virtualization, #databases og #flash minne." | "Tirsdag, 12 feb 2013 06:58:22 +0000" | "Adrianburch" |
5 | "http://t.co/D3KOJIvF artikkel om Madden 2013 ved hjelp av AI til prodict super bowl #databases # bus311" | "Tirsdag, 12 feb 2013 05:29:41 +0000" | "AndyRyder5" |
6 | "http://t.co/rBhBXjma en artikkel om personverninnstillinger og facebook #databases # bus311" | "Tirsdag, 12 feb 2013 05:24:17 +0000" | "AndyRyder5" |
7 | "# BUS311 University of Minnesota NCFPD skaper #databases for å hindre" mat svindel. "Http://t.co/0LsAbKqJ" | "Tirsdag, 12 feb 2013 01:49:19 +0000" | "Brett_Englebert" |
8 | "# BUS311 selskaper kan beskytte sin produksjon #databaser, men hva med deres backupfiler? Http://t.co/okJjV3Bm" | "Tirsdag, 12 feb 2013 01:31:52 +0000" | "Brett_Englebert" |
9 | "@NimbusData CEO @tisakovich @BarclaysOnline Big Data konferanse i San Francisco i dag, snakker #virtualization, # databaser, og # flash minne" | "Ma, 11 feb 2013 23:15:05 +0000" | "NimbusData" |
10 | "Ikke glem å registrere deg for vår GRATIS utstilling denne fredag: #Databases, #BI og #Sharepoint: Hva du trenger å vite! Http://t.co/Ijrqrz29" | "Ma, 11 feb 2013 22:15:37 +0000" | "SSWUGorg" |
Til slutt la vi legge til en primærnøkkel til følgende bord. I denne tabellen identifiserer ikke kolonnen "from_user" eller "to_user" -kolonnen unike hver rad selv. Men "from_user" og "to_user" gjør sammen, siden de representerer et enkelt forhold. En primærnøkkel kan defineres i mer enn en kolonne, så vi bruker begge disse kolonnene som primærnøkkel for følgende bord.
Når det gjelder den utenlandske nøkkelen, er "from_user" og "to_user" hver utenlandske nøkkel, siden de kan brukes til å definere en kobling med brukere bord. Hvis vi spør om et Twitter-håndtak på kolonnen "from_user", får vi alle brukerne han følger. Tilsvarende, hvis vi spør om et Twitter-håndtak på kolonnen "to_user", får vi alle brukerne etter ham.
Vi har oppnådd mye så langt. Vi fjernet repetisjoner på tvers av kolonner og rader ved å skille data inn i tre forskjellige tabeller, og vi valgte meningsfulle primærnøkler for å koble tabellen sammen. Hele denne prosessen kalles normalisering, og dens utgang er data som er rent organisert i henhold til relasjonsmodellen. Konsekvensen av denne organisasjonen er at rader vil vises i databasen bare en gang fremover, noe som igjen gjør CRUD-operasjonen enklere.
Fig. 4 diagrammer det ferdige databaseskjemaet. De tre tabellene er koblet sammen og de primære tastene er uthevet.
Fig. 4
Det er små variasjoner i SQL mellom hver RDBMS-leverandør, betegnet SQL-dialekter.
Nå som vi vet hvordan vi skal designe en relasjonsdatabase, hvordan implementerer vi faktisk en? Relasjonsdatabasebehandlingssystemer (RDBMS) er programvare som lar deg lage og bruke relasjonsdatabaser. Det er flere kommersielle og åpen kildekode leverandører å velge mellom. På den kommersielle siden er Oracle Database, IBM DB2 og Microsoft SQL Server tre kjente løsninger. På den frie og åpne kildesiden er MySQL, SQLite og PostgreSQL tre brukte løsninger.
MySQL brukes på omtrent alle Internett-selskaper du har hørt om. I sammenheng med denne artikkelen bruker Twitter MySQL til å lagre brukerens tweets.
SQLite er vanlig i innebygde systemer. iOS og Android lar utviklere bruke SQLite til å administrere sin apps private database. Google Chrome bruker SQLite til å lagre nettlesingsloggen, informasjonskapslene og miniatyrbildene dine på siden "Mest besøkte".
PostgreSQL er også en mye brukt RDBMS. PostGIS-utvidelsen kompletterer PostgreSQL med geospatiale funksjoner som gjør det nyttig for kartlegging av applikasjoner. En bemerkelsesverdig bruker av PostgreSQL er OpenStreetMap.
Når du har lastet ned og satt opp en RDBMS på systemet ditt, er neste trinn å opprette en database og tabeller inne i det for å sette inn og administrere relasjonsdataene dine. Slik gjør du dette med Structured Query Language (SQL), som er standardspråket for å jobbe med RDBMSs.
Her er en kort oversikt over vanlige SQL-setninger som er relevante for eksempelet Twitter-data ovenfor. Jeg anbefaler at du sjekker ut SQL Cookbook for en mer komplett applikasjonsdrevet liste over SQL-spørringer.
CREATE DATABASE utvikling;
CREATE TABLE-brukere (fullt navn VARCHAR (100), brukernavn VARCHAR (100));
RDBMSs krever at hver kolonne i et bord får en datatype. Her har jeg tildelt datatypen "fullt navn" og "brukernavn" VARCHAR
som er en streng som kan variere i bredde. Jeg har vilkårlig satt en maksimal lengde på 100. En fullstendig liste over datatyper finner du her.
INSERT TIL brukere (full_name, brukernavn) VALUES ("Boris Hadjur", "_DreamLead");
VELG tekst, created_at FRA tweets WHERE brukernavn = "_ DreamLead";
UPDATE brukere SET full_name = "Boris H" WHERE brukernavn = "_ DreamLead";
SLETT FRA brukere WHERE brukernavn = "_ DreamLead";
SQL er ganske lik vanlig engelske setninger. Det er små variasjoner i SQL mellom hver RDBMS-leverandør, betegnet SQL-dialekter, men forskjellene er ikke dramatisk nok til at du ikke enkelt kan overføre SQL-kunnene fra den ene til den andre.
I denne artikkelen lærte vi å designe en relasjonsdatabase. Vi tok en samling av data og organisert den i relaterte tabeller. Vi så også kort på RDBMS løsninger og SQL. Så kom i gang ved å laste ned en RDBMS og normalisere noen av dataene dine i en relasjonsdatabase i dag.
Forhåndsvis bildekilde: FindIcons.com/Barry Mieny