Webapps kan delas upp i två huvudkomponenter: ett front-end som visar och samlar in information och ett back-end för att lagra informationen. I den här artikeln ska jag visa vad en relationsdatabas är och hur du utformar din databas korrekt för att lagra din apps information.
En databas lagrar data på ett organiserat sätt så att det kan sökas och hämtas senare. Den ska innehålla en eller flera tabeller. Ett bord är ungefär som ett kalkylblad, eftersom det består av rader och kolumner. Alla rader har samma kolumner, och varje kolumn innehåller själva data. Om det hjälper, tänk på dina bord på samma sätt som du skulle ha en tabell i Excel.
figur 1
Data kan infogas, hämtas, uppdateras och raderas från en tabell. Ordet, skapad, används i allmänhet istället för införd, så kollektivt är dessa fyra funktioner förkortat som CRUD.
En relationsdatabas är en typ av databas som organiserar data i tabeller och länkar dem, baserat på definierade relationer. Dessa relationer gör att du kan hämta och kombinera data från en eller flera tabeller med en enda fråga.
Men det var bara en massa ord. För att verkligen förstå en relationsdatabas måste du göra en själv. Låt oss börja med att få några riktiga uppgifter som vi kan arbeta med.
I andan av Nettuts + Twitter klonartiklar (PHP, Ruby on Rails, Django), låt oss få lite Twitter-data. Jag sökte Twitter för "#databases" och tog följande urval av tio tweets:
bord 1
fullständiga namn | Användarnamn | text | skapad vid | following_username |
---|---|---|---|---|
"Boris Hadjur" | "_DreamLead" | "Vad tycker du om #emailing #campaigns #traffic i #USA? Är det en bra marknad idag? Har du #databaser?" | "Tis 12 feb 2013 08:43:09 +0000" | "Scootmedia", "MetiersInternet" |
"Gunnar Svalander" | "GunnarSvalander" | "Bill Gates Talks databaser, fri programvara på Reddit http://t.co/ShX4hZlA #billgates #databases" | "Tis, 12 feb 2013 07:31:06 +0000" | "klout", "zillow" |
"GE-programvara" | "GEsoftware" | "RT @ KirkDBorne: Läsningar i #Databaser: utmärkt läslista, många kategorier: http://t.co/S6RBUNxq via @rxin Fascinating." | "Tis 12 feb 2013 07:30:24 +0000" | "DayJobDoc", "byosko" |
"Adrian Burch" | "Adrianburch" | "RT @tisakovich: @NimbusData vid @Barclays Big Data-konferensen i San Francisco idag, pratar #virtualization, #databases och #flash memory." | "Tis 12 feb 2013 06:58:22 +0000" | "CindyCrawford", "Arjantim" |
"Andy Ryder" | "AndyRyder5" | "http://t.co/D3KOJIvF artikel om Madden 2013 med AI för att prodicera super bowl #databases # bus311" | "Tis 12 feb 2013 05:29:41 +0000" | "MichaelDell", "Yahoo" |
"Andy Ryder" | "AndyRyder5" | "http://t.co/rBhBXjma en artikel om integritetsinställningar och facebook #databases # bus311" | "Tis 12 feb 2013 05:24:17 +0000" | "MichaelDell", "Yahoo" |
"Brett Englebert" | "Brett_Englebert" | "# BUS311 University of Minnesota NCFPD skapar #databaser för att förhindra" matbedrägerier ". Http://t.co/0LsAbKqJ" | "Tis 12 feb 2013 01:49:19 +0000" | "RealSkipBayless", "stephenasmith" |
Brett Englebert | "Brett_Englebert" | "# BUS311 företag kan skydda sin produktion #databaser, men hur är deras backupfiler? Http://t.co/okJjV3Bm" | "Tis 12 feb 2013 01:31:52 +0000" | "RealSkipBayless", "stephenasmith" |
"Nimbus Data Systems" | "NimbusData" | "@NimbusData VD @tisakovich @BarclaysOnline Big Data-konferensen i San Francisco idag, pratar #virtualization, # databaser, och #flashminne" | "Mån, 11 feb 2013 23:15:05 +0000" | "dellock6", "rohitkilam" |
"SSWUG.ORG" | "SSWUGorg" | "Glöm inte att anmäla dig till vår GRATIS expo denna fredag: #Databases, #BI och #Sharepoint: Vad du behöver veta! Http://t.co/Ijrqrz29" | "Mån, 11 feb 2013 22:15:37 +0000" | "drsql", "steam_games" |
Här är vad varje kolumnnamn betyder:
MySQL används på nästan alla Internetföretag du har hört talas om.
Detta är alla verkliga data; du kan söka Twitter och hitta faktiskt dessa tweets.
Det här är bra. Uppgifterna är alla på ett ställe; så det är lätt att hitta, eller hur? Inte exakt. Det finns några problem med den här tabellen. För det första finns det repeterande data över kolumnerna. Kolumnen "användarnamn" och "following_username" är repetitive, eftersom båda innehåller samma typ av data - Twitter-handtag. Det finns en annan form av upprepning i kolumnen "following_username". Fält bör bara innehålla ett värde, men varje fält "following_username" innehåller två.
För det andra finns det repeterande data över raderna.
@ AndyRyder5 och @Brett_Englebert varje tweeted två gånger, så resten av deras information har duplicerats.
Duplicates är problematiska eftersom det gör CRUD-operationerna mer utmanande. Det skulle till exempel ta längre tid att hämta data eftersom tiden skulle gå förlorad genom dubbla rader. Uppdatering av data skulle också vara ett problem. Om en användare ändrar sitt Twitter-handtag, skulle vi behöva hitta varje dubblett och uppdatera det.
Upprepande data är ett problem. Vi kan åtgärda problemet genom att dela upp bord 1 i separata tabeller. Låt oss fortsätta med att först lösa upprepningen över kolumnproblemet.
Som noterat ovan, kolumnerna "användarnamn" och "following_username" i bord 1 är repetitiva. Denna upprepning inträffade eftersom jag försökte uttrycka följande förhållande mellan användarna. Låt oss förbättra på bord 1s design genom att dela upp den i två tabeller: en bara för följande relationer och en för resten av informationen.
Fig. 2
Eftersom @Brett_Englebert följer @RealSkipBayless, den följande tabellen kommer att uttrycka det förhållandet genom att lagra @Brett_Englebert som "from_user" och @RealSkipBayless som "to_user." Låt oss fortsätta och dela upp bord 1 in i dessa två tabeller:
Tabell 2: Den följande tabell
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 användare tabell
fullständiga namn | Användarnamn | text | skapad vid |
---|---|---|---|
"Boris Hadjur" | "_DreamLead" | "Vad tycker du om #emailing #campaigns #traffic i #USA? Är det en bra marknad idag? Har du #databaser?" | "Tis 12 feb 2013 08:43:09 +0000" |
"Gunnar Svalander" | "GunnarSvalander" | "Bill Gates Talks databaser, fri programvara på Reddit http://t.co/ShX4hZlA #billgates #databases" | "Tis, 12 feb 2013 07:31:06 +0000" |
"GE-programvara" | "GEsoftware" | "RT @ KirkDBorne: Läsningar i #Databaser: utmärkt läslista, många kategorier: http://t.co/S6RBUNxq via @rxin Fascinating." | "Tis 12 feb 2013 07:30:24 +0000" |
"Adrian Burch" | "Adrianburch" | "RT @tisakovich: @NimbusData vid @Barclays Big Data-konferensen i San Francisco idag, pratar #virtualization, #databases och #flash memory." | "Tis 12 feb 2013 06:58:22 +0000" |
"Andy Ryder" | "AndyRyder5" | "http://t.co/D3KOJIvF artikel om Madden 2013 med AI för att prodicera super bowl #databases # bus311" | "Tis 12 feb 2013 05:29:41 +0000" |
"Andy Ryder" | "AndyRyder5" | "http://t.co/rBhBXjma en artikel om integritetsinställningar och facebook #databases # bus311" | "Tis 12 feb 2013 05:24:17 +0000" |
"Brett Englebert" | "Brett_Englebert" | "# BUS311 University of Minnesota NCFPD skapar #databaser för att förhindra" matbedrägerier ". Http://t.co/0LsAbKqJ" | "Tis 12 feb 2013 01:49:19 +0000" |
Brett Englebert | "Brett_Englebert" | "# BUS311 företag kan skydda sin produktion #databaser, men hur är deras backupfiler? Http://t.co/okJjV3Bm" | "Tis 12 feb 2013 01:31:52 +0000" |
"Nimbus Data Systems" | "NimbusData" | "@NimbusData VD @tisakovich @BarclaysOnline Big Data-konferensen i San Francisco idag, pratar #virtualization, # databaser, och #flashminne" | "Mån, 11 feb 2013 23:15:05 +0000" |
"SSWUG.ORG" | "SSWUGorg" | "Glöm inte att anmäla dig till vår GRATIS expo denna fredag: #Databases, #BI och #Sharepoint: Vad du behöver veta! Http://t.co/Ijrqrz29" | "Mån, 11 feb 2013 22:15:37 +0000" |
Det här ser bättre ut. Nu i användare bord (Tabell 3) finns det bara en kolumn med Twitter-handtag. I följande bord (Tabell 2), är det bara ett Twitter-handtag per fält i kolumnen "to_user".
Edgar F. Codd, datavetenskapare som lagde ner den teoretiska grunden för relationella databaser, kallade detta steg att ta bort repeterande data över kolumnerna den första normala formen (1NF).
Nu när vi har fixa repetitioner över kolumner måste vi fixa repetitioner över rader. Eftersom användarna @ AndyRyder5 och @Brett_Englebert var tweeted två gånger, dupliceras deras information i användare bord (Tabell 3). Detta indikerar att vi måste dra ut tweetsna och placera dem i sitt eget bord.
Fig. 3
Som tidigare lagras "tweet" själva tweeten. Eftersom kolumnen "created_at" lagrar tidsstämpeln för tweeten, är det meningsfullt att dra det in i den här tabellen också. Jag inkluderar också en hänvisning till kolumnen "användarnamn" så vi vet vem som publicerade tweeten. Här är resultatet av att placera tweets i sitt eget bord:
Tabell 4: Den tweets tabell
text | skapad vid | Användarnamn |
---|---|---|
"Vad tycker du om #emailing #campaigns #traffic i #USA? Är det en bra marknad idag? Har du #databaser?" | "Tis 12 feb 2013 08:43:09 +0000" | "_DreamLead" |
"Bill Gates Talks databaser, fri programvara på Reddit http://t.co/ShX4hZlA #billgates #databases" | "Tis, 12 feb 2013 07:31:06 +0000" | "GunnarSvalander" |
"RT @ KirkDBorne: Läsningar i #Databaser: utmärkt läslista, många kategorier: http://t.co/S6RBUNxq via @rxin Fascinating." | "Tis 12 feb 2013 07:30:24 +0000" | "GEsoftware" |
"RT @tisakovich: @NimbusData vid @Barclays Big Data-konferensen i San Francisco idag, pratar #virtualization, #databases och #flash memory." | "Tis 12 feb 2013 06:58:22 +0000" | "Adrianburch" |
"http://t.co/D3KOJIvF artikel om Madden 2013 med AI för att prodicera super bowl #databases # bus311" | "Tis 12 feb 2013 05:29:41 +0000" | "AndyRyder5" |
"http://t.co/rBhBXjma en artikel om integritetsinställningar och facebook #databases # bus311" | "Tis 12 feb 2013 05:24:17 +0000" | "AndyRyder5" |
"# BUS311 University of Minnesota NCFPD skapar #databaser för att förhindra" matbedrägerier ". Http://t.co/0LsAbKqJ" | "Tis 12 feb 2013 01:49:19 +0000" | "Brett_Englebert" |
"# BUS311 företag kan skydda sin produktion #databaser, men hur är deras backupfiler? Http://t.co/okJjV3Bm" | "Tis 12 feb 2013 01:31:52 +0000" | "Brett_Englebert" |
"@NimbusData VD @tisakovich @BarclaysOnline Big Data-konferensen i San Francisco idag, pratar #virtualization, # databaser, och #flashminne" | "Mån, 11 feb 2013 23:15:05 +0000" | "NimbusData" |
"Glöm inte att anmäla dig till vår GRATIS expo denna fredag: #Databases, #BI och #Sharepoint: Vad du behöver veta! Http://t.co/Ijrqrz29" | "Mån, 11 feb 2013 22:15:37 +0000" | "SSWUGorg" |
Tabell 5: Den användare tabell
fullständiga namn | Användarnamn |
---|---|
"Boris Hadjur" | "_DreamLead" |
"Gunnar Svalander" | "GunnarSvalander" |
"GE-programvara" | "GEsoftware" |
"Adrian Burch" | "Adrianburch" |
"Andy Ryder" | "AndyRyder5" |
"Brett Englebert" | "Brett_Englebert" |
"Nimbus Data Systems" | "NimbusData" |
"SSWUG.ORG" | "SSWUGorg" |
Efter splittringen användare bord (Tabell 5) har unika rader för användare och deras Twitter-handtag.
Edgar F. Codd kallade detta steg för att ta bort repeterande data över raderna den andra normala formen (1NF).
Data kan infogas, hämtas, uppdateras och raderas från en tabell.
Än så länge, bord 1 har delats i tre nya tabeller: följande (Tabell 2), tweets (Tabell 4), och användare (Tabell 5). Men hur är det här användbart? Upprepad data har tagits bort, men nu sprids data över tre oberoende tabeller. För att kunna hämta data måste vi rita meningsfulla länkar mellan tabellerna. På så sätt kan vi uttrycka frågor som "vad en användare har tweeted och vem en användare följer".
Sättet att rita länkar mellan tabeller är att först ge varje rad i ett bord en unik identifierare, betecknad en primär nyckel och hänvisa sedan den primära nyckeln till den andra tabellen som du vill länka.
Vi har faktiskt redan gjort det här användare (Tabell 5) och tweets (Tabell 4). I användare, Den primära nyckeln är kolumnen "användarnamn" eftersom inga två användare kommer att ha samma Twitter-handtag. I tweets, Vi hänvisar till den här nyckeln i kolumnen "användarnamn" så vi vet vem tweeted vad. Eftersom det är en referens, kolumnen "användarnamn" i tweets kallas en främmande nyckel. På så sätt länkar "användarnamnet" nyckeln till användare och tweets bord tillsammans.
Är kolumnen "användarnamn" den bästa idén för en primär nyckel för användare tabell?
Å ena sidan är det en naturlig nyckel - det är vettigt att söka med ett Twitter-handtag istället för att ge varje användare ett numeriskt ID och söka på det. Å andra sidan, om en användare vill byta sitt Twitter-handtag? Det kan orsaka fel om den primära nyckeln och alla hänvisningar till främmande nycklar inte uppdateras exakt, fel som kan undvikas om ett konstant numeriskt ID användes. Slutligen beror valet på ditt system. Om du vill ge användarna möjlighet att ändra sitt användarnamn är det bättre att lägga till en numerisk automatisk inkrementerande "id" -kolumn till användare och använd det som den primära nyckeln. Annars borde "användarnamn" vara bra. Jag fortsätter att använda "användarnamn" som den primära nyckeln för användare
Låt oss gå vidare till tweets (Tabell 4). En primär nyckel borde identifiera varje rad unikt, så vad ska den primära nyckeln vara här? Fältet "created_at" fungerar inte eftersom om två användare tweet på exakt samma tid skulle deras tweets ha samma tidsstämpel. Texten har samma problem med att om två användare båda tweet "Hej världen" kunde vi inte skilja mellan raderna. Kolumnen "användarnamn" är den främmande nyckeln som definierar länken med användare så låt oss inte röra med det. Eftersom de andra kolumnerna inte är bra kandidater är det meningsfullt här att lägga till en numerisk automatisk inkrementerande "id" -kolumn och använda den som primärnyckel.
Tabell 6: Den tweets bord med en "id" kolumn
id | text | skapad vid | Användarnamn |
---|---|---|---|
1 | "Vad tycker du om #emailing #campaigns #traffic i #USA? Är det en bra marknad idag? Har du #databaser?" | "Tis 12 feb 2013 08:43:09 +0000" | "_DreamLead" |
2 | "Bill Gates Talks databaser, fri programvara på Reddit http://t.co/ShX4hZlA #billgates #databases" | "Tis, 12 feb 2013 07:31:06 +0000" | "GunnarSvalander" |
3 | "RT @ KirkDBorne: Läsningar i #Databaser: utmärkt läslista, många kategorier: http://t.co/S6RBUNxq via @rxin Fascinating." | "Tis 12 feb 2013 07:30:24 +0000" | "GEsoftware" |
4 | "RT @tisakovich: @NimbusData vid @Barclays Big Data-konferensen i San Francisco idag, pratar #virtualization, #databases och #flash memory." | "Tis 12 feb 2013 06:58:22 +0000" | "Adrianburch" |
5 | "http://t.co/D3KOJIvF artikel om Madden 2013 med AI för att prodicera super bowl #databases # bus311" | "Tis 12 feb 2013 05:29:41 +0000" | "AndyRyder5" |
6 | "http://t.co/rBhBXjma en artikel om integritetsinställningar och facebook #databases # bus311" | "Tis 12 feb 2013 05:24:17 +0000" | "AndyRyder5" |
7 | "# BUS311 University of Minnesota NCFPD skapar #databaser för att förhindra" matbedrägerier ". Http://t.co/0LsAbKqJ" | "Tis 12 feb 2013 01:49:19 +0000" | "Brett_Englebert" |
8 | "# BUS311 företag kan skydda sin produktion #databaser, men hur är deras backupfiler? Http://t.co/okJjV3Bm" | "Tis 12 feb 2013 01:31:52 +0000" | "Brett_Englebert" |
9 | "@NimbusData VD @tisakovich @BarclaysOnline Big Data-konferensen i San Francisco idag, pratar #virtualization, # databaser, och #flashminne" | "Mån, 11 feb 2013 23:15:05 +0000" | "NimbusData" |
10 | "Glöm inte att anmäla dig till vår GRATIS expo denna fredag: #Databases, #BI och #Sharepoint: Vad du behöver veta! Http://t.co/Ijrqrz29" | "Mån, 11 feb 2013 22:15:37 +0000" | "SSWUGorg" |
Till sist, låt oss lägga till en primär nyckel till följande tabell. I denna tabell identifierar varken kolumnen "from_user" eller kolumnen "to_user" unikt varje rad i sig. Men "from_user" och "to_user" gör tillsammans, eftersom de representerar ett enda förhållande. En primär nyckel kan definieras i mer än en kolumn, så vi ska använda båda dessa kolumner som den primära nyckeln för följande tabell.
När det gäller den främmande nyckeln är "from_user" och "to_user" varje utländsk nyckel eftersom de kan användas för att definiera en länk med användare tabell. Om vi frågar efter ett Twitter-handtag på kolumnen "from_user" får vi alla användare som följer. På motsvarande sätt, om vi frågar efter ett Twitter-handtag på kolumnen "to_user" får vi alla användare efter honom.
Vi har gjort mycket så långt. Vi tog bort repetitioner över kolumner och rader genom att separera data i tre olika tabeller, och sedan valde vi meningsfulla primära nycklar för att länka borden tillsammans. Hela processen kallas normalisering och dess utdata är data som är rent organiserad enligt relationsmodellen. Konsekvensen av denna organisation är att rader kommer att dyka upp i databasen endast en gång framåt, vilket i sin tur gör CRUD-operationerna enklare.
Fig. 4 diagrammer den färdiga databasschemat. De tre tabellerna är länkade ihop och de primära nycklarna är markerade.
Fig. 4
Det finns små variationer i SQL mellan varje RDBMS-leverantör, kallad SQL-dialekter.
Nu när vi vet hur man utformar en relationsdatabas, implementerar vi faktiskt en? Relationella databashanteringssystem (RDBMS) är programvara som låter dig skapa och använda relationsdatabaser. Det finns flera kommersiella och open source-leverantörer att välja mellan. På den kommersiella sidan är Oracle Database, IBM DB2 och Microsoft SQL Server tre välkända lösningar. På den fria och öppna källsidan är MySQL, SQLite och PostgreSQL tre allmänt använda lösningar.
MySQL används på nästan alla Internetföretag du har hört talas om. I samband med denna artikel använder Twitter MySQL för att lagra sina användares tweet.
SQLite är vanligt i inbyggda system. iOS och Android låter utvecklare använda SQLite för att hantera sin apps privata databas. Google Chrome använder SQLite för att lagra din surfhistorik, cookies och miniatyrbilder på sidan "Mest besökta".
PostgreSQL är också en mycket använd RDBMS. PostGIS-tillägget kompletterar PostgreSQL med geospatialfunktioner som gör det användbart för kartläggning av applikationer. En anmärkningsvärd användare av PostgreSQL är OpenStreetMap.
När du har laddat ner och installerat en RDBMS på ditt system, är nästa steg att skapa en databas och tabeller inuti den för att infoga och hantera din relationella data. Så här gör du det med Structured Query Language (SQL), vilket är standardspråket för att arbeta med RDBMS.
Här är en kort översikt över vanliga SQL-satser som är relevanta för exemplet Twitter-data ovan. Jag rekommenderar att du kolla in SQL Cookbook för en mer komplett applikationsdriven lista över SQL-frågor.
Skapa DATABASE utveckling;
Skapa TABLE-användare (fullständigt namn VARCHAR (100), användarnamn VARCHAR (100));
RDBMS kräver att varje kolumn i en tabell ges en datatyp. Här har jag tilldelat kolumnerna "full_name" och "användarnamn" datatypen VARCHAR
vilket är en sträng som kan variera i bredd. Jag har godtyckligt ställt en max längd på 100. En fullständig lista över datatyper finns här.
INSERT INTO användare (full_name, användarnamn) VALUES ("Boris Hadjur", "_DreamLead");
SELECT text, created_at FRÅN tweets WHERE användarnamn = "_ DreamLead";
UPDATE-användare SET full_name = "Boris H" WHERE användarnamn = "_ DreamLead";
DELETE FROM users WHERE användarnamn = "_ DreamLead";
SQL liknar ganska vanliga engelska meningar. Det finns små variationer i SQL mellan varje RDBMS-leverantör, kallad SQL-dialekter, men skillnaderna är inte dramatiska nog att du inte enkelt kan överföra din SQL-kunskap från den ena till den andra.
I den här artikeln lärde vi oss att designa en relationsdatabas. Vi tog en samling data och organiserade den i relaterade tabeller. Vi tittade också kort på RDBMS-lösningar och SQL. Så börja med att ladda ner en RDBMS och normalisera några av dina data till en relationsdatabas idag.
Förhandsvisa bildkälla: FindIcons.com/Barry Mieny