En-till-många-relationer är en av de vanligaste databasrelationerna. Om du vill lära dig när och hur du använder en-till-många-relationer är den här artikeln en bra utgångspunkt.
Du kommer säkerligen att använda en-till-många-relationer för att lagra information i vilken relationsdatabas som helst, oavsett om du designar programvara på företagsnivå eller bara skapar en enkel databas för att hålla reda på din farbrors frimärkssamling.
En kort introduktion till den relationella modellen
Relationsdatabaser är en kärnkomponent i alla moderna transaktionsapplikationer. Relationsmodellen är sammansatt av tabeller (data organiserade i rader och kolumner) som har minst en unik nyckel som identifierar varje rad. Varje tabell representerar en enhet. Detta visas i följande exempel, en mycket enkel version av en tabell som representerar kundorder:
Ovanstående diagram, som jag skapade online med Vertabelo, har en enda tabell. Varje rad i tabellen representerar en ordning och varje kolumn (även känd som ett attribut ) representerar varje enskild information som finns i en beställning.
För dem som ännu inte är bekanta med designverktyget Vertabelo, artikeln Vilka symboler används i ER-diagram? förklarar de symboler och konventioner som används. Du kanske också vill lära dig mer om relationsmodeller och databaser med hjälp av vår databasmodelleringskurs.
Vad är relationer och varför behöver vi dem?
Om vi tar en djupare titt på tabellen som användes i det föregående exemplet, kommer vi att se att den inte riktigt representerar en fullständig ordning. Den har inte all information du kan förvänta dig. Du kommer att märka att den inte innehåller någon information relaterad till kunden som gjorde beställningen och inte heller har den något om de produkter eller tjänster som beställts.
Vad ska vi göra för att slutföra denna design för att lagra orderdata? Ska vi lägga till kund- och produktinformation i ordern tabell? Det skulle kräva att man lägger till nya kolumner (attribut) för kundnamn, skattekoder, adresser etc. som visas nedan:
"Beställnings-ID" | "Beställningsdatum" | "OrderAmount" | Kund | "Kundadress" | "Kundtelefon" | "TaxIdentifier" |
---|---|---|---|---|---|---|
1 | jun-23 | 10 248,15 USD | International Services Ltd | 1247 St River Blvd, Charlotte, NC | (555) 478-8741 | IS789456 |
2 | jun-27 | 14 785,45 USD | World Master Importing Inc. | 354 Mountain Hill Rd, Los Angeles, CA | (555) 774-8888 | WM321456 |
3 | jul-01 | 7 975,00 USD | First State Provisioning Llc | 444 North Highway, Houston, TX | (555) 698-7411 | FS947561 |
4 | jul-03 | 6 784,25 USD | International Services Ltd | 1247 St River Blvd, Charlotte, NC | (555) 478-8741 | IS789456 |
5 | jul-07 | 21 476,10 USD | World Master Importing Inc. | 354 Mountain Hill Rd, Los Angeles, CA | (555) 774-8888 | WM321456 |
6 | 12 juli | 9 734,00 USD | First State Provisioning Llc | 444 North Highway, Houston, TX | (555) 698-7411 | FS947561 |
7 | 17 juli | 14 747,45 USD | World Master Importing Inc. | 354 Mountain Hill Rd, Los Angeles, CA | (555) 774-8888 | WM321456 |
8 | 21 juli | 19 674,85 USD | International Services Ltd | 1247 St River Blvd, Charlotte, NC | (555) 478-8741 | IS789456 |
Om vi gör det kommer vi snart att stöta på problem. De flesta kunder lägger mer än en beställning, så detta system kommer att lagra kundinformation många gånger, en gång för varje beställning av varje kund. Det verkar inte vara ett smart drag.
Dessutom, vad händer när en kund ändrar sitt telefonnummer? Om någon behöver ringa kunden kan de hitta det gamla numret på tidigare beställningar – om inte någon uppdaterar hundratals (eller till och med tusentals) befintliga beställningar med den nya informationen. Och detsamma skulle gälla för alla andra förändringar.
En relationsmodell kräver att vi definierar varje entitet som en separat tabell och upprättar relationer mellan dem. Att lagra all information i en enda tabell fungerar helt enkelt inte.
Det finns flera typer av relationer mellan tabeller, men den vanligaste är förmodligen en-till-många-relationen, som ofta skrivs som 1:N. Den här typen av relation innebär att en rad i en tabell (vanligtvis kallad den överordnade tabellen) kan ha en relation med många rader i en annan tabell (vanligtvis kallad underordnad tabell). Några vanliga exempel på en-till-många-relationer är:
- En biltillverkare tillverkar många olika modeller, men en viss bilmodell byggs bara av en enda biltillverkare.
- En kund kan göra flera köp, men varje köp görs av en enda kund.
- Ett företag kan ha många telefonnummer, men ett telefonnummer tillhör ett företag.
Det finns även andra typer av relationer mellan tabeller; om du vill lära dig mer om dem, se den här artikeln om många-till-många-relationer.
Om vi går tillbaka till vårt första beställningsexempel, Customer
tabellen skulle vara den överordnade tabellen och Order
bord barnet; en kund kan ha många beställningar, medan en beställning kan tillhöra en enskild kund.
Observera att en-till-många-definitionen tillåter att en rad i den överordnade tabellen associeras med många rader i varje underordnad tabell, men det krävs inte. Egentligen tillåter designen en kund att ha noll beställningar (dvs. en ny kund som ännu inte har gjort sitt första köp), en beställning (en relativt ny kund som har gjort ett enda köp) eller många beställningar (en frekvent kund).
Visa en-till-många-relationer i ett akutdiagram
Låt oss ta en titt på ett mer komplett exempel på ett enkelt kundbeställningssystem som använder ett ER-diagram (eller entitetsrelation). (Om du vill lära dig mer om dessa diagram är Vertabelo Features:Logical Diagrams en bra utgångspunkt.) Här är modellen:
Detta är en mer realistisk design. Du kommer att märka att det finns nya entiteter (tabeller) i diagrammet, som nu innehåller tabellerna Customer
, Order
, Order Detail
och Product
. Men det viktigaste du lägger märke till är att det nu finns relationer mellan borden .
I en databasmodell representeras relationer av linjer som förbinder två enheter. Egenskaperna för dessa relationer representeras av olika kopplingar:
- När det finns en enda vertikal linje, har den entitet som är närmast den anslutaren endast en rad som påverkas av relationen. Det är "en" i en-till-många.
- När det finns en multi-line connector som ser ut som en kråkfot, har entiteten närmast den connectorn flera rader som påverkas av relationen; det är de "många".
När man tittar på bilden och känner till notationen är det enkelt att förstå att diagrammet definierar att varje Order
kan ha många Order Details
och att varje Order Detail
tillhör en enda Order
.
Implementera en en-till-många-relation mellan tabeller
För att definiera en en-till-många-relation mellan två tabeller måste den underordnade tabellen referera till en rad i den överordnade tabellen. De steg som krävs för att definiera det är:
- Lägg till en kolumn i den underordnade tabellen som lagrar värdet på den primära identifieraren. (De flesta databasmotorer tillåter faktiskt att det är vilken unik nyckel som helst från den överordnade tabellen, inte bara den primära nyckeln.) Kolumnen kan definieras som obligatorisk beroende på dina affärsbehov; trots det skapas vanligtvis kolumner för främmande nyckel
Obs! Det är en god praxis att hålla samma namn på referenskolumnerna som i den refererade (förälder) tabellen. Detta gör det ännu enklare att förstå förhållandet.
- Lägg till en främmande nyckel begränsning på barnbordet. Detta indikerar att varje värde som lagras i den här nya kolumnen refererar till en rad i den överordnade tabellen.
Restriktioner för främmande nyckel är en funktion som är tillgänglig i relationsdatabaser som upprätthåller att:
- När du lägger till en rad i den underordnade tabellen måste värdet på referenskolumnen matcha ett (och endast ett) värde i den överordnade tabellen. (Det är därför en kolumn eller uppsättning kolumner som utgör en primärnyckel eller unik nyckel måste refereras).
- Om någon försöker ta bort en rad från den överordnade tabellen eller försöker ändra värdena för den unika/primära nyckeln som används som referens och det finns en underordnad tabell som refererar till den raden, operationen kommer att misslyckas.
Dessa två funktioner säkerställer att databasen behåller sin integritet. Det finns ingen chans att skapa beställningar som hänvisar till en icke-existerande kund, och inte heller att ta bort en kund som redan har beställningar.
Skapa en främmande nyckel
Syntax för främmande nyckel beror vanligtvis på måldatabasmotorn. När du har definierat din logiska modell kan du använda funktionen "Generera fysisk modell..." på Vertabelos logiska diagram för att omvandla din (databasagnostiska) modell till en fysisk modell som matchar din databasleverantör. Vertabelo kommer också att generera det nödvändiga SQL-skriptet som gör att du kan skapa tabellerna och relationerna i din måldatabas.
Några praktiska exempel på 1:N-relationer
Låt oss nu granska några exempel på verkliga en-till-många-relationer.
En-till-många-relation med primärnycklar
Detta är förmodligen det vanligaste scenariot när man definierar en en-till-många-relation. Den underordnade tabellen använder det primära nyckelvärdet för den överordnade tabellen för att upprätta relationen.
Det här exemplet beskriver en grundläggande onlineströmningstjänst. Låt oss granska vad som lagras i var och en av tabellerna och hur de förhåller sig till de andra tabellerna i vår modell:
- Varje
ServiceType
definierar hur ett konto "beter sig" (t.ex. hur många användare som kan ansluta till systemet samtidigt, om kontot har Full HD aktiverat, etc.). Den har en relation med andra enheter:- En en-till-många-relation med
Account
, vilket betyder att varje tjänsttyp kan ha många konton av den typen.
- En en-till-många-relation med
- Varje
Account
lagrar information om en kund. Den har två direkta relationer till andra enheter:- Varje konto tillhör en enda
ServiceType
, som förklarats ovan. - Den här tabellen har en en-till-många-relation med
Profile
tabell, vilket innebär att mer än en användare kan ansluta till vårt system med samma konto.
- Varje konto tillhör en enda
- Varje
Profile
representerar en användare i vårt system. Den har två relationer till andra enheter:- Varje profil tillhör ett enda
Account
. Detta gör att alla familjemedlemmar (eller kanske en grupp vänner) kan dela samma konto medan var och en har sina egna personliga attribut (t.ex. ett profilnamn). - Varje profil har en unik
Avatar
.
- Varje profil tillhör ett enda
- Varje
Avatar
är en bild som gör att vi snabbt kan identifiera varje kontoanvändare. Den har en relation med en annan enhet:- En en-till-många-relation med
Profile
, vilket innebär att en enda avatar kan tilldelas profiler på olika konton.
- En en-till-många-relation med
En-till-många-relationer med naturliga nycklar eller unika surrogatnycklar
Användningen av surrogat-primärnycklar är ett allmänt accepterat sätt att modellera tabeller. (Surrogatprimärnycklar genereras av databasen och har inget verkligt affärsvärde.) Denna metod ger nycklar som är enklare att använda och ger viss flexibilitet när ändringar krävs.
Det finns dock situationer – t.ex. när vi behöver interagera med externa system – där det är ett dåligt tillvägagångssätt att använda en nyckel som genereras i vår databas. För dessa scenarier är det vanligtvis bättre att använda naturliga nycklar, som är unika värden som är en del av den enhet som lagras och som inte genereras automatiskt av vår databas.
Följande exempel representerar en grundläggande datamodell för en organisation som håller reda på fordon (dvs. bilens märke, modell, färg och år), deras ägare och eventuella överträdelser av kollektivtrafiken. När vi definierade det använde vi surrogat primärnycklar för att fastställa relationerna mellan fordonen och märken, modeller och ägare, eftersom all denna information hanteras internt av vårt system.
I det här systemet, hur kan en polisman i en annan stad rapportera en bil som har parkerats olagligt med vår primärnyckel för fordonet (VehicleID
)? Sådan information finns inte naturligt på det parkerade fordonet, men registreringsskylten finns där. Det betyder att det enklaste sättet att ta emot och associera information från en extern källa (i det här exemplet, vilken polisavdelning som helst i landet) är att använda en naturlig unik nyckel istället för en surrogat-primärnyckel.
Den fysiska implementeringen av detta logiska diagram för SQL Server är tillgängligt här:
En-till-många-relationer på samma bord
De tidigare exemplen fokuserade på relationer mellan två eller flera tabeller, men det finns också scenarier där relationen uppstår mellan rader i samma tabell. Denna typ av en-till-många-relation kallas också för en hierarkisk relation; det används i många system för att representera trädliknande strukturer, det vill säga ett organisationsschema, ett huvudbokkonto eller en produkt och dess beståndsdelar.
Första gången du behöver skapa den här typen av struktur kommer du att bli frestad att definiera en tabell för var och en av nivåerna i din hierarki, som visas i följande diagram:
Det finns många problem med detta tillvägagångssätt:
- Alla tabeller är nästan identiska och lagrar identisk information.
- Om din organisation lägger till en ny nivå måste du ändra datamodellen och lägga till en ny tabell, nya främmande nycklar, etc.
- Om en anställd får en befordran måste du ta bort dem från en tabell och infoga dem i en annan.
Därför är det bästa sättet att modellera den här typen av struktur att använda en enda tabell som refererar till sig själv, som visas i detta diagram:
Här ser vi en enda Employee
tabell och en kolumn med namnet EmployeeID_Manager
. Den kolumnen hänvisar till en annan anställd i samma organisation som är arbetsledare/chef för den nuvarande anställde.
Jag lade till _Manager
suffix för att skilja mellan ID för den aktuella raden och ID för chefen. (Vi skulle kunna använda ManagerID
istället, men jag föredrar att behålla det ursprungliga namnet på den refererade kolumnen och, i de fall där båda finns i samma tabell, lägga till ett suffix som förklarar den roll den faktiskt har).
Att förstå hierarkiska relationer är mer komplext än andra en-till-många-relationer. Men om du glömmer tabellen där all information är lagrad och föreställer dig att det faktiskt finns olika tabeller, var och en av dem representerar en nivå i hierarkin, är det lite lättare att visualisera. Föreställ dig att du skapar relationen mellan två enheter och sedan kombinerar dem till en enhet.
Vad är härnäst?
Exemplen som tillhandahålls hjälper dig att identifiera olika scenarier som kräver en en-till-många-relation. Du kan börja designa din egen databasstruktur med hjälp av Vertabelo Database Modeler, ett webbaserat verktyg som låter dig inte bara generera en logisk modell utan också skapa en fysisk version av den för den databasleverantör du behöver.
Nu är det din tur – använd kommentarsektionen för att berätta om dina tankar om den här artikeln, ställa ytterligare frågor eller dela dina erfarenheter av databasmodellering.