sql >> Databasteknik >  >> RDS >> Database

Vad är ett en-till-många-förhållande i en databas? En förklaring med exempel

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:

  1. 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.

  1. 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:

  1. 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).
  2. 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:

  1. 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.
  2. 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.
  3. 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 .
  4. 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-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.


  1. Problem med createb i postgres

  2. SQL uppdatera fält i en tabell från fält i en annan

  3. 4 sätt att konvertera ett tal till en procentandel i SQL Server (T-SQL)

  4. Versaler av dag- och månadsnamn vid formatering av datum i Oracle