Använd gilla för att markera nyttiga inlägg!
Skapa databas
Rentals.VehicleID är inte unik utan är rimligtvis en FK som pekar på Vehicles.ID, du kan ju hyra ut samma fordon flera gånger eller hur ? Då kan inte Rentals.VehicleID vara unik.
Vehicles.FuelType och FuelPrices.FuelType borde ju varit en FK också till en FuelType tabell men det funkar som det är om du är noga med att ha samma värde där, fast inte idealt.
Jag förstår, jag vet inte riktigt hur jag ska tänka nu när jag ska sätta ihop tabellerna, vet jag redan nu att jag kommer kunna svara på mina frågor och få ut data?
Jag förstår, jag vet inte riktigt hur jag ska tänka nu när jag ska sätta ihop tabellerna, vet jag redan nu att jag kommer kunna svara på mina frågor och få ut data?
Ha lite tålamod ska jag försöka bringa lite ordning på alltihopa med en stegvis beskrivning av hur du kan gå tillväga med (hoppas jag) begripliga kommentarer och förklaringar.
Det kommer under förmiddagen (2/1).
Är lite förvånad över hur många som har enstaka kommentarer som inte riktigt hänger ihop med varandra.
Vad är det för IT-utbildning du gått där de inte går igenom sånt här?
Jag förstår, jag vet inte riktigt hur jag ska tänka nu när jag ska sätta ihop tabellerna, vet jag redan nu att jag kommer kunna svara på mina frågor och få ut data?
Tycker du fått massor av tips hur du ska tänka och en länk till databasbok på svenska till och med. Du borde ha koll på PK och FK vid det här laget och hur man ska tänka när man sätter ihop tabeller.
PK = primär nyckel, unik identifierare för "raden" av information, kan vara en naturlig nyckel (som regnummer) eller surrogat som ett genererat ID som du verkar ha.
FK = främmande nyckel, pekar ut en relation med data i en annan tabell, alltså pekar på den primära nyckeln i den tabell som har informationen som relateras till. (Därav namnet relationsdatabas f.ö.)
Hur man tänker här är ju som tipsats om, man modellerar verksamheten genom att analysera denna, till exempel med pappers metoden som zoomster sa. Och databasboken som länkades har en del info om entity modellering också.
Du vet ju genom uppgiften en massa information du måste ha i tabellerna och hur relationerna måste se ut. Visst det är en del träning att kunna se relationerna men inte så svårt.
Tänk på vad som är en till flera relationer, du har en bil men kan ha flera uthyrningar per bil till exempel, då är det en FK i tabellen för uthyrningar för där kan det finnas flera uthyrningar på samma bil.
När du gör frågorna sedan kommer det bli en select där du väljer ut genom att joina flera av dina tabeller på FK och/eller specifikt väljer ut data med hjälp av den primära nyckeln eller andra kolumner. Men där är vi inte ännu då du inte skapat databasen eller fyllt med data eller ?
Jag tycker den modellen du har nu borde fungera med frågorna om du petar in vehicleid som fk till vehicles.id och fyller med data.
Först av allt:
Hoppa över index. Alla större databashanterare ordnar automatiskt index i sådan utsträckning att det täcker grundläggande behov. Problemställningen ger inte upphov till någon krånglig lösning och inte heller till någon "stor" databas. Alla sökningar och andra operationer på databasen (insättning och uppdatering) kommer gå fort utan extra index.
De flesta av frågorna som ställts i de svar du fått besvaras mer eller mindre automatiskt om man benar ut problematiken lite grand medan man bygger modellen. Problemet biluthyrning är, vad gäller databasmodell inte svårt, utan tvärtom faktiskt ganska trivialt.
Verktyget jag kommer använda är lite enklare än de flesta verktyg som numera används men jag har hållit på länge och upplever att resultatet lätt kan diskuteras med folk som inte är hemma på området och att nybörjare lätt kan lära sig att använda det och sedan gå vidare till mer komplexa verktyg som duger bättre för riktigt stora jobb.
Man börjar med att ta fram en modell och det mest grundläggande är en ER-modell (Entity-Relationship-modell = objekt- och sambandsmodell) där jag kommer rita rektanglar för objektklasser (= mängder av objekt / tabeller med objektbeskrivningar) och linjer för sambandsklasser (= mängder av samband mellan objekt / antingen tabeller med sambandsbeskrivningar eller främmande nycklar i objektklasser). Med främmande nyckel menas en referens från en tabell till en annan och regeln säger att om det finns en främmande nyckel ska den antingen inte ha något värde (= null) eller måste den ha ett värde som motsvarar ett objekt i den tabell den refererar till.
Allt det här lossnar nog medan vi går igenom problembeskrivningen och samtidigt bygger modellen. Jag kommer bygga en traditionell och mycket enkel ER-modell och man ska vara medveten om att det finns en mängd olika notationer och tekniker.
Det är viktigt att förstå att vi modellerar möjligheter, d.v.s. vad vi vill kunna representera och att det är i databasen som vi sedan realiserar en representation. Med andra ord kan det t.ex. finnas en bil av en viss modell om vi tar med det i modellen men det är inte säkert att vi utnyttjar den möjligheten i databasen (= kanske finns det ingen rad i biltabellen som motsvarar Volvo C70).
OBS också att alla delar av modellen ska vara namngivna. Så som den här modellen kommer se ut kommer alla sambandklasser försvinna vid övergången till databasstruktur och därför namnger jag sambandsklasserna med bara sammansättningen av första bokstäverna i de objektklasser de sammanbinder. Att namnge sambandsklasser är svårt och jag är lite lat, normalt skulle man ge dem beskrivande namn.
Nu kör vi
1.
Centralt i modellen blir bilar och kunder så jag ritar in dessa som objektklasser (med namnet i singularis)
2.
Varje bil är av en viss modell medan det för varje modell kan finnas mer än en faktisk bil, vilket man ser genom gaffeln i ena änden av sambandsklassen jag kallat "BiMo" (ett beskrivande namn kunde varit "BilModell", men jag kommer vara lat och det kommer bli svårare med namngivningen):
3.
Katgorisera för att kunden ska kunna välja bil lättare: t.ex. antal passagerare, kombi, lyx, m.m. Samma resonemang gäller för gaffeln i änden mot Modell och ingen gaffel i änden mot Kategori
4.
Vi lägger till Bokning där vi vill låta kunden kunna boka en bil av en viss kategori med möjligheten för kunden att välja en viss bilmodell.
Vi lägger också till Uthyrning som ju gäller en viss bil av de som är möjliga enligt bokningen och eftersom uthyrning är en viktig del av verksamheten och dess bokföring så måste varje uthyrning kunna identifieras unikt. Dessutom kopplar vi uthyrningen till den bokning som låg till grund för uthyrningen.
5.
Vill vi kunna representera kostnader. Det enklaste sättet är att koppla kostnader i form av fakturor och utlägg till varje enskilt fordon. Samtidigt kan vi representera telefonnummer till kunder på liknande sätt:
6.
I de flesta fall skriver man in alla egenskaper (personnummer, namn, adress, m.m.) direkt i modellen men jag tycker att modellen då snabbt blir plottrig och svårläst så de senaste 30 åren har jag alltid istället gjort en tabell som beskriver delarnas egenskaper, en s.k. egenskapsmatris. Så gör jag nu också. Jag kommer inte sätta ut datatyper förrän det är dags att förvandla modellen och egenskapsmatrisen till en databasstruktur och sedan vidare till en uppsättning kommandon i SQL för att realisera databasen.
Jag skriver dessutom ut vilka egenskaper som kommer att vara primärnycklar.
Här kan man lägga till att det kan finnas fler än en möjlighet till primärnycklar. Alla dessa kallas kandidatnycklar och av de befintliga möjligheterna väljer man en till primärnyckel. De övriga kandidatnycklarna är viktiga men eftersom det i den här databasen inte kommer finnas mer än en kandidatnyckel per tabell så nöjer jag mig med att påpeka detta. I ett senare skede kommer jag att göra en del ändringar och då kommer jag att använda det som nu kallas primärnyckel till att säkra upp databasen vad gäller dubbletter och referenser till andra tabeller. OBS att jag endast ger exempel på egenskaper. Missar säkert en del men det kan man ju komplettera efter behov.
Egenskapsmatrisen:
Namn | Primärnyckel | Övriga egenskaper |
---|---|---|
Bil | regnr | färg, mätarställning |
Modell | modellbeteckning (ex. S70)) | märke (ex Volvo), dörrantal, bränsletyp, bränsleåtgång, bränslemått (l/mil, t.ex.) |
Kategori | kategoribeteckning | passagerantal, kombi, maxlast, dygnspris, km-pris, långtidsrabatt, ... |
Uthyrning | uthyrningsnummer | startdatum, slutdatum, startmätarställning, slutmätarställning, kostnad |
Kund | personnummer | förnamn, efternamn, adress, postnummer, postort |
Telefon | telnr | |
Bokning | bokningsnummer | startdatum, slutdatum (OBS att det kommer till saker senare) |
Kostnad | verifikationsnummer | datum, typ, summa, kommentar (typen kan vara bränsle, reparation, fordonsskatt, försäkring, ...) |
Numera brukar man välja bort att använda informationsbärande egenskaper för att kunna få referensintegritet genom att istället använda stora heltal som en slags serienummer. Jag kommer att använda "id" som namn (inom parentes om aktuell beteckning för primärnyckeln kan användas och om inte kommer jag att sätta den gamla primärnyckeln som "unik". "unik" kommer då användas för att se till att samma värde inte används mer än en gång. Då blir det istället:
Namn | Primärnyckel | Övriga egenskaper |
---|---|---|
Bil | id | unik(regnr), färg, mätarställning |
Modell | id | unik(modellbeteckning), märke, dörrantal, bränsletyp, bränsleåtgång, bränslemått |
Kategori | id | unik(kategoribeteckning), passagerantal, kombi, maxlast, dygnspris, km-pris, långtidsrabatt, ... |
Uthyrning | uthyrningsnummer(id) | startdatum, slutdatum, startmätarställning, slutmätarställning, kostnad |
Kund | id | unik(personnummer), förnamn, efternamn, adress, postnummer, postort |
Telefon | id | unik(telnr) |
Bokning | bokningsnummer (id) | startdatum, slutdatum (OBS att det kommer till saker senare) |
Kostnad | verifikationsnummer(id) | datum, typ, summa, kommentar (typen kan vara bränsle, reparation, fordonsskatt, försäkring, ...) |
Miss av mig så, för att kunna hantera internationella kunder ändrar jag Telefon så att landsnumret kommer med:
Namn | Primärnyckel | Övriga egenskaper |
---|---|---|
Telefon | id | unik(telnr, landskod) |
Sambandsklasserna kommer inte ha några egna egenskaper i en så enkel modell men alla kommer få en primärnyckel som består av sammanslagningen av primärnycklarna i de objektklasser som de binder samman, här använder jag "tabellnamn_id" för id som hör till tabellen "tabellnamn".
Namn | Primärnyckel | Övriga egenskaper |
---|---|---|
KoBi | verifikationsnummer, bil_id | |
BiMo | bil_id, modellbeteckning | |
MoKa | modell_id, kategori_id | |
BiUt | bil_id, uthyrningsnummer | |
MoBo | modell_id, bokningsnummer | |
KaBo | kategori_id, bokningsnummer | |
UtBo | uthyrningsnummer, bokningsnummer | |
UtKu | uthyrningsnummer, kund_id | |
KuBo | kund_id, bokningsnummer | |
KuTe | kund_id, telefon_id |
Nu överför vi modellen och egenskapsmatrisen till en databasstruktur. Som tur är finns det en del ganska enkla regler. Här använder jag bara de som behövs.
Jag använder mig av beteckningen:
tabellnamn: (P(primärnyckel), övriga egenskaper) Om unik(x) används U(x)
Regel 1: Alla Objektklasser som innehåller mer än bara primärnyckel ska bilda en tabell.
Bil: (P(id),U(regnr), färg, mätarställning)
Modell: (P(id), U(modellbeteckning), märke, dörrantal, bränsletyp, bränsleåtgång, bränslemått)
Kategori: (P(id), U(kategoribeteckning), passagerantal, kombi, maxlast, dygnspris, km-pris, långtidsrabatt)
Uthyrning: (P(uthyrningsnummer), startdatum, slutdatum, startmätarställning, slutmätarställning, kostnad)
Kund: (P(id), U(personnummer), förnamn, efternamn, adress, postnummer, postort)
Telefon: (P(id), U(telnr, landskod))
Bokning: (P(bokningsnummer), startdatum, slutdatum)
Kostnad: (P(verifikationsnummer), datum, typ, summa, kommentar)
Regel 2: Sambandsklasser av typen 1:N (de med gaffel i en ände) försvinner men den delen av primärnyckeln som är mot 1-änden (utan gaffel) blir en egenskap i objektklassen på N-sidan (gaffel-änden) och faktiskt en främmande nyckel där.
KoBi försvinner och Bil_id blir främmande nyckel i Kostnad:
Kostnad: (P(verifikationsnummer), datum, typ, summa, kommentar, FK(bil_id))
o.s.v.:
Bil: (P(id),U(regnr), färg, mätarställning, FK(modell_id))
Modell: (P(id), U(modellbeteckning), märke, dörrantal, bränsletyp, bränsleåtgång, bränslemått, FK(kategori_id))
Kategori: (P(id), U(kategoribeteckning), passagerantal, kombi, maxlast, dygnspris, km-pris, långtidsrabatt)
Uthyrning: (P(uthyrningsnummer), startdatum, slutdatum, startmätarställning, slutmätarställning, kostnad, FK(bil_id), FK(kund_id))
Kund: (P(id), U(personnummer), förnamn, efternamn, adress, postnummer, postort)
Telefon: (P(id), U(telnr, landskod), FK(kund_id))
Bokning: (P(bokningsnummer), startdatum, slutdatum, FK(modell_id), FK(kategori_id), FK(kund_id))
Kostnad: (P(verifikationsnummer), datum, typ, summa, kommentar, FK(bil_id))
En sak kvar: UtBo som inte har någon gaffel och därför klassas som 1:1-sambandsklass, d.v.s. en bokning motsvaras av en och endast en uthyrning. Här får man resonera sig fram lite grand.
Eftersom bokningar kommer till utan att det finns en uthyrning men uthyrningar (nästan) alltid motsvaras av en föregående bokning (utom när en kund kommer in på uthyrningskontoret och frågar efter en bil som inte ska ut till kund och det råkar finnas en tillgänglig) så föredrar jag att skapa referensen till bokningen i Uthyrning. Så jag lägger till en extra främmande nyckel i Uthyrning:
Bil: (P(id),U(regnr), färg, mätarställning, FK(modell_id))
Modell: (P(id), U(modellbeteckning), märke, dörrantal, bränsletyp, bränsleåtgång, bränslemått, FK(kategori_id))
Kategori: (P(id), U(kategoribeteckning), passagerantal, kombi, maxlast, dygnspris, km-pris, långtidsrabatt)
Uthyrning: (P(uthyrningsnummer), startdatum, slutdatum, startmätarställning, slutmätarställning, kostnad, FK(bil_id), FK(kund_id), FK(bokning_id))
Kund: (P(id), U(personnummer), förnamn, efternamn, adress, postnummer, postort)
Telefon: (P(id), U(telnr, landskod), FK(kund_id))
Bokning: (P(bokningsnummer), startdatum, slutdatum, FK(modell_id), FK(kategori_id), FK(kund_id))
Kostnad: (P(verifikationsnummer), datum, typ, summa, kommentar, FK(bil_id))
Nu är vi klara att skapa SQL-satserna för att bygga databasen. Här definierar jag databasen efter hur det skulle bli i PostgreSQL. Det skiljer sig lite från MySQL och andra. Man får läsa på lite om man använder en annan databashanterare. Vi kan be om kommentarer angående hur det skiljer sig från MySQL... Eftersom många databashanterare inte är förtjusta i svenska tecken blir det engelska i definitionerna men t.ex. PostgreSQL hanterar diakritiska tecken utan problem, d.v.s. tecken som har, sett från engelska, underliga accenter som t.ex. trema ovanför a och o (= ä och ö). Jag sätter kommentarer direkt i koden, allt som står efter '--' på en rad i SQL blir en kommentar. Jag tar tabellerna i en ordning som gör att jag inte gör våld på främmande nycklar.
create table category ( -- kategori
id bigserial not null primary key,
category character varying(50) not null unique, -- kategoribeteckning
passenger_no integer not null, -- passagerantal
combi boolean, -- kombi (sant = 't', falskt = 'f') men man kan använda 'true' och 'false'
load_capacity integer, -- maxlast
day_price decimal(6,2), -- dygnspris, max 9999.99
km_price decimal(5,2), -- km-pris, max 999,99
discount decimal(4,2) -- långtidsrabatt, max 99.99
);
create table model ( -- modell
id bigserial not null primary key,
model character varying(50) not null unique, -- modellbeteckning
make character varying(50) not null, -- märke
door_no integer not null, -- dörrantal
fuel_type character varying(50) not null, -- bränsletyp
fuel_consumption integer not null, -- bränsleåtgång
fuel_measure character varying(10) not null, -- bränslemått
category_id bigint not null references category(id) -- främmande nyckel till kategoritabellen
);
create table car ( -- bil
id bigserial not null primary key,
regnr character varying(8) not null unique, -- regnr
color character varying(20), -- färg
meter integer not null default 0, -- mätarställning
model_id bigint not null references model(id) -- främmande nyckel till modelltabellen
);
create table expense ( -- kostnad
voucher_id bigserial not null primary key, -- verifikationsnummer
type character varying(50), -- typ av utgift
sum decimal(10,2) not null, -- summa med högst tio siffror varav två är decimaler (= max 99999999.99)
comment text, -- kommentar
car_id bigint references car(id) -- främmande nyckel till biltabellen
);
create table client ( -- kund
id bigserial not null primary key,
pnr character varying(13) not null unique, -- personnummer
first_name character varying(50) not null, -- förnamn
family_name character varying(50) not null, -- efternamn
address character varying(50) not null, -- adress
postcode integer not null, -- postnummer
district character varying(50) not null -- postort, vanligt i england men vanligt med 'city' i USA
);
create table phone ( -- telefon
id bigserial not null primary key,
phone_no bigint not null, -- telnr
country_code character varying(10) not null default '+46', --landskod default till Sverige
client_id bigint not null references client(id), -- främmande nyckel till kundtabellen
unique(phone_no, country_code) -- om flera egenskaper tillsammans ska vara unik kombination gör man så
);
create table booking ( -- bokning
booking_no bigserial not null primary key, -- bokningsnummer
startdate timestamp without time zone not null, -- startdatum (och tid)
enddate timestamp without time zone not null, -- slutdatum (och tid)
model_id bigint references model(id), -- främmande nyckel till modelltabellen
category_id bigint not null references category(id), -- främmande nyckel till kategoritabellen
client_id bigint not null references client(id) -- främmande nyckel till kundtabellen
);
-- märk att modellreferensen inte är tvingande medan kategori- och kundreferenserna är det
create table rental ( -- uthyrning
rental_no serial not null primary key, -- uthyrningsnummer
startdate timestamp without time zone not null, -- startdatum (och tid)
enddate timestamp without time zone not null, -- slutdatum (och tid)
meter_at_start integer not null, -- startmätarställning
meter_at_end integer, -- slutmätarställning
cost decimal(7,2), -- kostnad, beräknas vid återlämn. av bil
car_id bigint not null references car(id), -- främmande nyckel till biltabellen
client_id bigint not null references client(id), -- främmande nyckel till kundtabellen
booking_id bigint references booking(booking_no) -- främmande nyckel till bokningdtabellen
);
Slutligen: Kan man få svar på alla frågor??
Ja, det kan man. Utmaning till alla: formulera utgående ifrån de här givna tabelldefinitionerna alla de frågeställningar som finns i ursprungsinlägget.
Förutsättningar: kort sträcka är mindre än 10 mil.
Jag återkommer med SQL queries själv (måste jobba lite också )
Ställ gärna frågor på innehållet, Jag svarar så gott jag kan.
Namn | Primärnyckel | Övriga egenskaper |
---|---|---|
Bil | regnr | färg, mätarställning |
Modell | modellbeteckning (ex. S70)) | märke (ex Volvo), dörrantal, bränsletyp, bränsleåtgång, bränslemått (l/mil, t.ex.) |
Kategori | kategoribeteckning | passagerantal, kombi, maxlast, dygnspris, km-pris, långtidsrabatt, ... |
Uthyrning | uthyrningsnummer | startdatum, slutdatum, startmätarställning, slutmätarställning, kostnad |
Kund | personnummer | förnamn, efternamn, adress, postnummer, postort |
Telefon | telnr | |
Bokning | bokningsnummer | startdatum, slutdatum (OBS att det kommer till saker senare) |
Kostnad | verifikationsnummer | datum, typ, summa, kommentar (typen kan vara bränsle, reparation, fordonsskatt, försäkring, ...) |
Fantastiskt inlägg, iaf för någon som är nybörjare!
Kommer säkert ha massa frågor. Till att börja med, borde det inte vara en kolumn för kostnad i modell också?
Fantastiskt inlägg, iaf för någon som är nybörjare!
Kommer säkert ha massa frågor. Till att börja med, borde det inte vara en kolumn för kostnad i modell också?
Jag tror inte att du ska se det som att du får ett färdigt svar. Du behöver så klart bygga ut med era specifika grejer.
Fantastiskt inlägg, iaf för någon som är nybörjare!
Kommer säkert ha massa frågor. Till att börja med, borde det inte vara en kolumn för kostnad i modell också?
Det kan man ha men det är enklare att samla alla kostnader som en bunt räkningar som jag gjort i tabellen "expense" (kostnad). Det stämmer dessutom bra för bokföring om man lägger till en kolumn för vilket konto som skall belastas och datum då man betalade m.m.
Jag tror inte att du ska se det som att du får ett färdigt svar. Du behöver så klart bygga ut med era specifika grejer.
Ja självklart!
Det kan man ha men det är enklare att samla alla kostnader som en bunt räkningar som jag gjort i tabellen "expense" (kostnad). Det stämmer dessutom bra för bokföring om man lägger till en kolumn för vilket konto som skall belastas och datum då man betalade m.m.
Förstår, såg bara inte var man får den informationen ifrån, kändes som den skulle höra samman med "model".
Ja självklart!
Förstår, såg bara inte var man får den informationen ifrån, kändes som den skulle höra samman med "model".
Man får fundera lite. Jag har inte tagit med inköpskostnaden, som ju ska spridas över tiden som bilen är i bruk. Kan inte riktigt avskrivningsregler för biluthyrningsföretag men troligtvis ska kostnaden för inköp spridas över ett antal år på samma sätt som allt annat man använder för professionen. Men jag tror att alla kostnader ska höra ihop med den fysiska bilen och inte med modellen.
Man får fundera lite. Jag har inte tagit med inköpskostnaden, som ju ska spridas över tiden som bilen är i bruk. Kan inte riktigt avskrivningsregler för biluthyrningsföretag men troligtvis ska kostnaden för inköp spridas över ett antal år på samma sätt som allt annat man använder för professionen. Men jag tror att alla kostnader ska höra ihop med den fysiska bilen och inte med modellen.
Borde det inte finnas med en kostnad på själva bilen för kund?
Slutgiltiga priset beror på vilken bil (eller kategori enligt serafims modell), antal dagar och km som körts.
För en specifik car eller Vehicle..
Alltså beräknat av
day_price decimal(6,2), -- dygnspris, max 9999.99
km_price decimal(5,2), -- km-pris, max 999,99
discount decimal(4,2) -- långtidsrabatt, max 99.99
och
startdate timestamp without time zone not null, -- startdatum (och tid)
enddate timestamp without time zone not null, -- slutdatum (och tid)
meter_at_start integer not null, -- startmätarställning
meter_at_end integer, -- slutmätarställning
edit2: Missade att 'expense' är företagets kostnader
alternativt (nja)
kolla i expense tabellen (och om något skapade upp en expense vid varje slutförd uthyrning) och vi har en referens till en uthyrning.
eller enligt mitt alt. 2
DateOfDeparture
DistanceUponDeparture
DateOfReturn
DistanceUponReturn
alternativt
om detta kalkyleras vid återlämning av bilen.
DaysRented (calculated?)
TravelDistanceInMeter (calculated?)
och
RentalFeePerDay
RentalFeePerKm
*edit: stavning
*edit2: duuhhh
Borde det inte finnas med en kostnad på själva bilen för kund?
Beräknas utifrån priset i bilens kategori och tid + km. Kanske kategorin borde haft ett timpris också...
För att förenkla för OP, kanske vi ska hålla oss till förutsättningarna och frågorna som fanns i första inlägget?
Känns som det finns risk för att vi försöker hjälpa till med fel saker annars.
F.ö. kanonbra förklaring och väldigt intressant metod att modellera databasen serafim!
Slutgiltiga priset beror på vilken bil (eller kategori enligt serafims modell), antal dagar och km som körts.
För en specifik car eller Vehicle..
Alltså beräknat av
day_price decimal(6,2), -- dygnspris, max 9999.99
km_price decimal(5,2), -- km-pris, max 999,99
discount decimal(4,2) -- långtidsrabatt, max 99.99
och
startdate timestamp without time zone not null, -- startdatum (och tid)
enddate timestamp without time zone not null, -- slutdatum (och tid)
meter_at_start integer not null, -- startmätarställning
meter_at_end integer, -- slutmätarställning
edit2: Missade att 'expense' är företagets kostnader
alternativt (nja)
kolla i expense tabellen (och om något skapade upp en expense vid varje slutförd uthyrning) och vi har en referens till en uthyrning.
eller enligt mitt alt. 2
DateOfDeparture
DistanceUponDeparture
DateOfReturn
DistanceUponReturn
alternativt
om detta kalkyleras vid återlämning av bilen.
DaysRented (calculated?)
TravelDistanceInMeter (calculated?)
och
RentalFeePerDay
RentalFeePerKm
*edit: stavning
*edit2: duuhhh
Beräknas utifrån priset i bilens kategori och tid + km. Kanske kategorin borde haft ett timpris också...
Men data för att räkna ut vad företaget betalar för bilen?
I detta fall så ser jag att det är manuellt uträknat och inmatat..
Enligt
Varje bil kostar firman X kronor per månad och Y kronor per mil.
T.ex. Avbetalningen till Volvo Finance för lånet till bilen Volvo XC90 med reg.nummer 'abc 123', är 3200kr per månad samt kostnaden för slitage 3 kr/km. Eftersom förutsättningarna inte ger oss någon beräkning av exakta beloppet, så antar vi att man manuellt har satt ett schablon belopp antingen hela summan per månad eller enligt min alt2, både per månad och per km.
I alt.2
VehicleCosts
VehicleID
PerMonth
PerKm
det saknas uppgifter om det i serafims modell (bygga ut?). Men om vi antar att expense tabellen har fyllts med en post om en bil som kommer/har kostat och lägger till datum+expense_type i tabellen, så kan man uppnå samma sak.
@zoomster2: Metoden utvecklades av Lennart Lindström som äger IRM-konsult (reklam??). Han har utvecklat den vidare, notationen är lite annorlunda och det jag använde nu är en liten, liten del av metoden som numera är heltäckande och klarar av stora databasmodelleringsproblem. Jag har använt den och UML om vartannat i 32 år, varvat med andra metoder då behovet funnits.
Tack för berömmet men själv hittar jag både luckor i förklaringarna och brister i modellen. Den kom till under två tidiga morgontimmar i morse mest för att jag tyckte att alla som ville hjälpa till fragmenterade både frågan och hjälpen så att det inte riktigt hängde ihop. Tyckte det blev mer begripligt om man tog ett helhetsgrepp på problemställningen.
Jag tänkte att om alla fokuserade på min eller någon annan bättre modell och vi försöker besvara frågorna i ursprungsinlägget som @Tryckvagen skrev så kan vi hitta bristerna, rätta till modellen och komplettera med skillnaderna mot andra databashanterare.
Databasen som den definierats i mitt inlägg existerar i min postgreSQL-server som jag har gående på min egen dator. Jag har inte lagt in några data utan bara kollat att mina idéer verkar funka.
Vill gärna att folk påpekar fel och brister, inte med "vad är det här för skit" utan med "det här borde ändras så här", "det här måste till", "den här egenskapen bör flyttas till den tabellen", o.s.v.
Även naturligtvis, kommentarer om man tycker det är skit men då "det här är skit därför att ..."
Just nu håller jag på med annat (ren programmering för att gräva i XML och HTML för att hitta information som krävs i ett större projekt (och som landar som data i databaser efter kraftiga transformationer med hjälp av XSLT) så att hoppa på den här frågan innebär ett rejält kontextbyte. Det är däför jag hoppas att andra ska hjälpa med frågorna. De är inte svåra men tar en del tid.
Efter varje uthyrning registreras mätarställningen på bilen (Viktigt med ganska många mätarställningar, >500st totalt för alla bilar.)
Men besvaras inte det med:
meter_at_start integer not null, -- startmätarställning
meter_at_end integer, -- slutmätarställning ?
Offtopic: Lite spontan feedback. Som verktyg av analys av affärsmodell in -> sql datastruktur ut, så ser jag detta som kanon! Väldigt pedagogiskt sätt att via steg identifiera och hitta möjligheter av användandet av affärsdata.
Fortfarande offtopic: Men, som IT Arkitekt på ett stort företag, är jag samtidigt tveksam att implementera detta för ett utvecklingsteam, då vi jobbat hårt med att flytta fokus från 'data first' (modellering av databas (sql/nosql/etc) först) till 'business function first'. T.ex. tidigare så hade vi kanske lagt till 'expense' tabell, eftersom det var naturligt från data sidan. Men troligtvis så borde den information finnas/ägas av en ekonomi(SAP?) eller liknande lösning istället.
Andra andningen av offtopic: Tankesättet som du tar fram tycker jag om, men man får vara försiktig, och komma ihåg att inte överarbeta och istället ta fram databas modeller efter behovet av mjukvaran som frågar efter den.
Efter varje uthyrning registreras mätarställningen på bilen (Viktigt med ganska många mätarställningar, >500st totalt för alla bilar.)
Men besvaras inte det med:
meter_at_start integer not null, -- startmätarställning
meter_at_end integer, -- slutmätarställning ?
Jovisst, man lägger in info både i 'car' och 'rental' då kunden kommer in med bilen. Om du ska hitta mätarställningen för en viss bil:
select meter from car where regnr = 'ABC123'
men om du bara lägger in mätarställningen i 'rental' och ska ställa samma fråga:
select max (meter_at_end) from rental where car_id =
(select id from car where regnr = 'ABC123')
Offtopic: Lite spontan feedback. Som verktyg av analys av affärsmodell in -> sql datastruktur ut, så ser jag detta som kanon! Väldigt pedagogiskt sätt att via steg identifiera och hitta möjligheter av användandet av affärsdata.
Fortfarande offtopic: Men, som IT Arkitekt på ett stort företag, är jag samtidigt tveksam att implementera detta för ett utvecklingsteam, då vi jobbat hårt med att flytta fokus från 'data first' (modellering av databas (sql/nosql/etc) först) till 'business function first'. T.ex. tidigare så hade vi kanske lagt till 'expense' tabell, eftersom det var naturligt från data sidan. Men troligtvis så borde den information finnas/ägas av en ekonomi(SAP?) eller liknande lösning istället.
Andra andningen av offtopic: Tankesättet som du tar fram tycker jag om, men man får vara försiktig, och komma ihåg att inte överarbeta och istället ta fram databas modeller efter behovet av mjukvaran som frågar efter den.
I de flesta projekt jag har varit med i så består utvecklingsteamet av flera grupper som arbetar var och en för sig med olika saker och deras sammansatta ansträngningar integreras med jämna mellanrum. Databaserna skapas nästan alltid som ett resultat av mjukvaruutvecklingen och väldigt sällan efter så specifika frågeställningar som i den här tråden.
I vissa projekt, en bråkdel av de jag har varit med i, så centreras projektet kring databasen. Oftast då man har speciella krav från lagstiftning eller myndighetsutövning. Idag täcks ganska ofta, men inte alltid, de behoven av färdiga system som t.ex. SAP. Då använder man programvara som hämtar intressant information från det systemet, ofta SAP, där man lagrar all data som krävs för företagets redovisning till myndigheter och ofta även de data som leder fram till redovisningsdata. Man skulle kunna lägga hela uthyrningsverksamhetens informationsbehov i SAP men frågeställningen här är inte kopplad till ett storföretags verksamhet och ett litet biluthyrningsföretag skulle inte ha nytta av SAP och framför allt inte råd med SAP. Jag gillade deras databas-back-end som ju är Sybase (eller var innan SAP köpte Sybase). Sedan uppköpet har jag inte haft något med Sybase att göra annat än indirekt då jag haft uppdrag som involverade SAP.
Flera av de projekt jag jobbat med har haft frågeställningar som gjort det nödvändigt att börja med databasmodellering, mest på grund av frågeställningens komplexitet. Det senaste har 45 tabeller i databasen och det skulle inte varit möjligt att gå en annan väg än att börja med informationsstrukturering (och därmed databasen). Däremot gick det inte med metoden jag använt här utan via UML och framförallt genom att analysera dataflöden.
Men allt detta är som sagt off topic ...
Först av allt:
Hoppa över index. Alla större databashanterare ordnar automatiskt index i sådan utsträckning att det täcker grundläggande behov. Problemställningen ger inte upphov till någon krånglig lösning och inte heller till någon "stor" databas. Alla sökningar och andra operationer på databasen (insättning och uppdatering) kommer gå fort utan extra index.
De flesta av frågorna som ställts i de svar du fått besvaras mer eller mindre automatiskt om man benar ut problematiken lite grand medan man bygger modellen. Problemet biluthyrning är, vad gäller databasmodell inte svårt, utan tvärtom faktiskt ganska trivialt.
Verktyget jag kommer använda är lite enklare än de flesta verktyg som numera används men jag har hållit på länge och upplever att resultatet lätt kan diskuteras med folk som inte är hemma på området och att nybörjare lätt kan lära sig att använda det och sedan gå vidare till mer komplexa verktyg som duger bättre för riktigt stora jobb.
Man börjar med att ta fram en modell och det mest grundläggande är en ER-modell (Entity-Relationship-modell = objekt- och sambandsmodell) där jag kommer rita rektanglar för objektklasser (= mängder av objekt / tabeller med objektbeskrivningar) och linjer för sambandsklasser (= mängder av samband mellan objekt / antingen tabeller med sambandsbeskrivningar eller främmande nycklar i objektklasser). Med främmande nyckel menas en referens från en tabell till en annan och regeln säger att om det finns en främmande nyckel ska den antingen inte ha något värde (= null) eller måste den ha ett värde som motsvarar ett objekt i den tabell den refererar till.
Allt det här lossnar nog medan vi går igenom problembeskrivningen och samtidigt bygger modellen. Jag kommer bygga en traditionell och mycket enkel ER-modell och man ska vara medveten om att det finns en mängd olika notationer och tekniker.
Det är viktigt att förstå att vi modellerar möjligheter, d.v.s. vad vi vill kunna representera och att det är i databasen som vi sedan realiserar en representation. Med andra ord kan det t.ex. finnas en bil av en viss modell om vi tar med det i modellen men det är inte säkert att vi utnyttjar den möjligheten i databasen (= kanske finns det ingen rad i biltabellen som motsvarar Volvo C70).
OBS också att alla delar av modellen ska vara namngivna. Så som den här modellen kommer se ut kommer alla sambandklasser försvinna vid övergången till databasstruktur och därför namnger jag sambandsklasserna med bara sammansättningen av första bokstäverna i de objektklasser de sammanbinder. Att namnge sambandsklasser är svårt och jag är lite lat, normalt skulle man ge dem beskrivande namn.
Nu kör vi
1.
Centralt i modellen blir bilar och kunder så jag ritar in dessa som objektklasser (med namnet i singularis)
http://semidako.se/biluthyrning/modell1.png
2.
Varje bil är av en viss modell medan det för varje modell kan finnas mer än en faktisk bil, vilket man ser genom gaffeln i ena änden av sambandsklassen jag kallat "BiMo" (ett beskrivande namn kunde varit "BilModell", men jag kommer vara lat och det kommer bli svårare med namngivningen):
http://semidako.se/biluthyrning/modell2.png
3.
Katgorisera för att kunden ska kunna välja bil lättare: t.ex. antal passagerare, kombi, lyx, m.m. Samma resonemang gäller för gaffeln i änden mot Modell och ingen gaffel i änden mot Kategori
http://semidako.se/biluthyrning/modell3.png
4.
Vi lägger till Bokning där vi vill låta kunden kunna boka en bil av en viss kategori med möjligheten för kunden att välja en viss bilmodell.
Vi lägger också till Uthyrning som ju gäller en viss bil av de som är möjliga enligt bokningen och eftersom uthyrning är en viktig del av verksamheten och dess bokföring så måste varje uthyrning kunna identifieras unikt. Dessutom kopplar vi uthyrningen till den bokning som låg till grund för uthyrningen.
http://semidako.se/biluthyrning/modell4x.png
5.
Vill vi kunna representera kostnader. Det enklaste sättet är att koppla kostnader i form av fakturor och utlägg till varje enskilt fordon. Samtidigt kan vi representera telefonnummer till kunder på liknande sätt:
http://semidako.se/biluthyrning/modell5.png
6.
I de flesta fall skriver man in alla egenskaper (personnummer, namn, adress, m.m.) direkt i modellen men jag tycker att modellen då snabbt blir plottrig och svårläst så de senaste 30 åren har jag alltid istället gjort en tabell som beskriver delarnas egenskaper, en s.k. egenskapsmatris. Så gör jag nu också. Jag kommer inte sätta ut datatyper förrän det är dags att förvandla modellen och egenskapsmatrisen till en databasstruktur och sedan vidare till en uppsättning kommandon i SQL för att realisera databasen.
Jag skriver dessutom ut vilka egenskaper som kommer att vara primärnycklar.
Här kan man lägga till att det kan finnas fler än en möjlighet till primärnycklar. Alla dessa kallas kandidatnycklar och av de befintliga möjligheterna väljer man en till primärnyckel. De övriga kandidatnycklarna är viktiga men eftersom det i den här databasen inte kommer finnas mer än en kandidatnyckel per tabell så nöjer jag mig med att påpeka detta. I ett senare skede kommer jag att göra en del ändringar och då kommer jag att använda det som nu kallas primärnyckel till att säkra upp databasen vad gäller dubbletter och referenser till andra tabeller. OBS att jag endast ger exempel på egenskaper. Missar säkert en del men det kan man ju komplettera efter behov.
Egenskapsmatrisen:
Namn | Primärnyckel | Övriga egenskaper |
---|---|---|
Bil | regnr | färg, mätarställning |
Modell | modellbeteckning (ex. S70)) | märke (ex Volvo), dörrantal, bränsletyp, bränsleåtgång, bränslemått (l/mil, t.ex.) |
Kategori | kategoribeteckning | passagerantal, kombi, maxlast, dygnspris, km-pris, långtidsrabatt, ... |
Uthyrning | uthyrningsnummer | startdatum, slutdatum, startmätarställning, slutmätarställning, kostnad |
Kund | personnummer | förnamn, efternamn, adress, postnummer, postort |
Telefon | telnr | |
Bokning | bokningsnummer | startdatum, slutdatum (OBS att det kommer till saker senare) |
Kostnad | verifikationsnummer | datum, typ, summa, kommentar (typen kan vara bränsle, reparation, fordonsskatt, försäkring, ...) |
Numera brukar man välja bort att använda informationsbärande egenskaper för att kunna få referensintegritet genom att istället använda stora heltal som en slags serienummer. Jag kommer att använda "id" som namn (inom parentes om aktuell beteckning för primärnyckeln kan användas och om inte kommer jag att sätta den gamla primärnyckeln som "unik". "unik" kommer då användas för att se till att samma värde inte används mer än en gång. Då blir det istället:
Namn | Primärnyckel | Övriga egenskaper |
---|---|---|
Bil | id | unik(regnr), färg, mätarställning |
Modell | id | unik(modellbeteckning), märke, dörrantal, bränsletyp, bränsleåtgång, bränslemått |
Kategori | id | unik(kategoribeteckning), passagerantal, kombi, maxlast, dygnspris, km-pris, långtidsrabatt, ... |
Uthyrning | uthyrningsnummer(id) | startdatum, slutdatum, startmätarställning, slutmätarställning, kostnad |
Kund | id | unik(personnummer), förnamn, efternamn, adress, postnummer, postort |
Telefon | id | unik(telnr) |
Bokning | bokningsnummer (id) | startdatum, slutdatum (OBS att det kommer till saker senare) |
Kostnad | verifikationsnummer(id) | datum, typ, summa, kommentar (typen kan vara bränsle, reparation, fordonsskatt, försäkring, ...) |
Miss av mig så, för att kunna hantera internationella kunder ändrar jag Telefon så att landsnumret kommer med:
Namn | Primärnyckel | Övriga egenskaper |
---|---|---|
Telefon | id | unik(telnr, landskod) |
Sambandsklasserna kommer inte ha några egna egenskaper i en så enkel modell men alla kommer få en primärnyckel som består av sammanslagningen av primärnycklarna i de objektklasser som de binder samman, här använder jag "tabellnamn_id" för id som hör till tabellen "tabellnamn".
Namn | Primärnyckel | Övriga egenskaper |
---|---|---|
KoBi | verifikationsnummer, bil_id | |
BiMo | bil_id, modellbeteckning | |
MoKa | modell_id, kategori_id | |
BiUt | bil_id, uthyrningsnummer | |
MoBo | modell_id, bokningsnummer | |
KaBo | kategori_id, bokningsnummer | |
UtBo | uthyrningsnummer, bokningsnummer | |
UtKu | uthyrningsnummer, kund_id | |
KuBo | kund_id, bokningsnummer | |
KuTe | kund_id, telefon_id |
Nu överför vi modellen och egenskapsmatrisen till en databasstruktur. Som tur är finns det en del ganska enkla regler. Här använder jag bara de som behövs.
Jag använder mig av beteckningen:
tabellnamn: (P(primärnyckel), övriga egenskaper) Om unik(x) används U(x)
Regel 1: Alla Objektklasser som innehåller mer än bara primärnyckel ska bilda en tabell.
Bil: (P(id),U(regnr), färg, mätarställning)
Modell: (P(id), U(modellbeteckning), märke, dörrantal, bränsletyp, bränsleåtgång, bränslemått)
Kategori: (P(id), U(kategoribeteckning), passagerantal, kombi, maxlast, dygnspris, km-pris, långtidsrabatt)
Uthyrning: (P(uthyrningsnummer), startdatum, slutdatum, startmätarställning, slutmätarställning, kostnad)
Kund: (P(id), U(personnummer), förnamn, efternamn, adress, postnummer, postort)
Telefon: (P(id), U(telnr, landskod))
Bokning: (P(bokningsnummer), startdatum, slutdatum)
Kostnad: (P(verifikationsnummer), datum, typ, summa, kommentar)
Regel 2: Sambandsklasser av typen 1:N (de med gaffel i en ände) försvinner men den delen av primärnyckeln som är mot 1-änden (utan gaffel) blir en egenskap i objektklassen på N-sidan (gaffel-änden) och faktiskt en främmande nyckel där.
KoBi försvinner och Bil_id blir främmande nyckel i Kostnad:
Kostnad: (P(verifikationsnummer), datum, typ, summa, kommentar, FK(bil_id))
o.s.v.:
Bil: (P(id),U(regnr), färg, mätarställning, FK(modell_id))
Modell: (P(id), U(modellbeteckning), märke, dörrantal, bränsletyp, bränsleåtgång, bränslemått, FK(kategori_id))
Kategori: (P(id), U(kategoribeteckning), passagerantal, kombi, maxlast, dygnspris, km-pris, långtidsrabatt)
Uthyrning: (P(uthyrningsnummer), startdatum, slutdatum, startmätarställning, slutmätarställning, kostnad, FK(bil_id), FK(kund_id))
Kund: (P(id), U(personnummer), förnamn, efternamn, adress, postnummer, postort)
Telefon: (P(id), U(telnr, landskod), FK(kund_id))
Bokning: (P(bokningsnummer), startdatum, slutdatum, FK(modell_id), FK(kategori_id), FK(kund_id))
Kostnad: (P(verifikationsnummer), datum, typ, summa, kommentar, FK(bil_id))
En sak kvar: UtBo som inte har någon gaffel och därför klassas som 1:1-sambandsklass, d.v.s. en bokning motsvaras av en och endast en uthyrning. Här får man resonera sig fram lite grand.
Eftersom bokningar kommer till utan att det finns en uthyrning men uthyrningar (nästan) alltid motsvaras av en föregående bokning (utom när en kund kommer in på uthyrningskontoret och frågar efter en bil som inte ska ut till kund och det råkar finnas en tillgänglig) så föredrar jag att skapa referensen till bokningen i Uthyrning. Så jag lägger till en extra främmande nyckel i Uthyrning:
Bil: (P(id),U(regnr), färg, mätarställning, FK(modell_id))
Modell: (P(id), U(modellbeteckning), märke, dörrantal, bränsletyp, bränsleåtgång, bränslemått, FK(kategori_id))
Kategori: (P(id), U(kategoribeteckning), passagerantal, kombi, maxlast, dygnspris, km-pris, långtidsrabatt)
Uthyrning: (P(uthyrningsnummer), startdatum, slutdatum, startmätarställning, slutmätarställning, kostnad, FK(bil_id), FK(kund_id), FK(bokning_id))
Kund: (P(id), U(personnummer), förnamn, efternamn, adress, postnummer, postort)
Telefon: (P(id), U(telnr, landskod), FK(kund_id))
Bokning: (P(bokningsnummer), startdatum, slutdatum, FK(modell_id), FK(kategori_id), FK(kund_id))
Kostnad: (P(verifikationsnummer), datum, typ, summa, kommentar, FK(bil_id))
Nu är vi klara att skapa SQL-satserna för att bygga databasen. Här definierar jag databasen efter hur det skulle bli i PostgreSQL. Det skiljer sig lite från MySQL och andra. Man får läsa på lite om man använder en annan databashanterare. Vi kan be om kommentarer angående hur det skiljer sig från MySQL... Eftersom många databashanterare inte är förtjusta i svenska tecken blir det engelska i definitionerna men t.ex. PostgreSQL hanterar diakritiska tecken utan problem, d.v.s. tecken som har, sett från engelska, underliga accenter som t.ex. trema ovanför a och o (= ä och ö). Jag sätter kommentarer direkt i koden, allt som står efter '--' på en rad i SQL blir en kommentar. Jag tar tabellerna i en ordning som gör att jag inte gör våld på främmande nycklar.
create table category ( -- kategori
id bigserial not null primary key,
category character varying(50) not null unique, -- kategoribeteckning
passenger_no integer not null, -- passagerantal
combi boolean, -- kombi (sant = 't', falskt = 'f') men man kan använda 'true' och 'false'
load_capacity integer, -- maxlast
day_price decimal(6,2), -- dygnspris, max 9999.99
km_price decimal(5,2), -- km-pris, max 999,99
discount decimal(4,2) -- långtidsrabatt, max 99.99
);
create table model ( -- modell
id bigserial not null primary key,
model character varying(50) not null unique, -- modellbeteckning
make character varying(50) not null, -- märke
door_no integer not null, -- dörrantal
fuel_type character varying(50) not null, -- bränsletyp
fuel_consumption integer not null, -- bränsleåtgång
fuel_measure character varying(10) not null, -- bränslemått
category_id bigint not null references category(id) -- främmande nyckel till kategoritabellen
);
create table car ( -- bil
id bigserial not null primary key,
regnr character varying(8) not null unique, -- regnr
color character varying(20), -- färg
meter integer not null default 0, -- mätarställning
model_id bigint not null references model(id) -- främmande nyckel till modelltabellen
);
create table expense ( -- kostnad
voucher_id bigserial not null primary key, -- verifikationsnummer
type character varying(50), -- typ av utgift
sum decimal(10,2) not null, -- summa med högst tio siffror varav två är decimaler (= max 99999999.99)
comment text, -- kommentar
car_id bigint references car(id) -- främmande nyckel till biltabellen
);
create table client ( -- kund
id bigserial not null primary key,
pnr character varying(13) not null unique, -- personnummer
first_name character varying(50) not null, -- förnamn
family_name character varying(50) not null, -- efternamn
address character varying(50) not null, -- adress
postcode integer not null, -- postnummer
district character varying(50) not null -- postort, vanligt i england men vanligt med 'city' i USA
);
create table phone ( -- telefon
id bigserial not null primary key,
phone_no bigint not null, -- telnr
country_code character varying(10) not null default '+46', --landskod default till Sverige
client_id bigint not null references client(id), -- främmande nyckel till kundtabellen
unique(phone_no, country_code) -- om flera egenskaper tillsammans ska vara unik kombination gör man så
);
create table booking ( -- bokning
booking_no bigserial not null primary key, -- bokningsnummer
startdate timestamp without time zone not null, -- startdatum (och tid)
enddate timestamp without time zone not null, -- slutdatum (och tid)
model_id bigint references model(id), -- främmande nyckel till modelltabellen
category_id bigint not null references category(id), -- främmande nyckel till kategoritabellen
client_id bigint not null references client(id) -- främmande nyckel till kundtabellen
);
-- märk att modellreferensen inte är tvingande medan kategori- och kundreferenserna är det
create table rental ( -- uthyrning
rental_no serial not null primary key, -- uthyrningsnummer
startdate timestamp without time zone not null, -- startdatum (och tid)
enddate timestamp without time zone not null, -- slutdatum (och tid)
meter_at_start integer not null, -- startmätarställning
meter_at_end integer, -- slutmätarställning
cost decimal(7,2), -- kostnad, beräknas vid återlämn. av bil
car_id bigint not null references car(id), -- främmande nyckel till biltabellen
client_id bigint not null references client(id), -- främmande nyckel till kundtabellen
booking_id bigint references booking(booking_no) -- främmande nyckel till bokningdtabellen
);
Slutligen: Kan man få svar på alla frågor??
Ja, det kan man. Utmaning till alla: formulera utgående ifrån de här givna tabelldefinitionerna alla de frågeställningar som finns i ursprungsinlägget.
Förutsättningar: kort sträcka är mindre än 10 mil.
Jag återkommer med SQL queries själv (måste jobba lite också )
Ställ gärna frågor på innehållet, Jag svarar så gott jag kan.
Börjat fylla databasen med data nu, är väl nu frågorna kommer med queries för att få svar på frågorna.
Spelar det någon roll vilken databashanterare jag väljer egentligen? Alla följer TYP samma språk?
Alla följer inte samma språk/logik.
För några år sedan kom det databaser som HBase(ej ej relationsDB) som är schemalösa och fungerar enligt key-value principen(tänk HashMap).
Där används normal inga joins alls vilket gör att queries blir mycket enklare att ställa.
Hur ska man tänka nu när man ska fylla data, kolumner som 'kund' 'bil' 'modell' är bara att fylla rakt upp och ner, med de andra som tar data från andra tables?
Jag tänker såhär (ni får ursäkta för den dåliga formuleringen):
Skulle fylla uthyrning med några rader men när jag ska fylla startmätarställning.
'uthyrning'
meter_at_start integer not null, -- startmätarställning
meter_at_end integer, -- slutmätarställning [b]borde inte dessa värden tas från bokning?[/b
Ser ju vilka kolumner som är kopplade med varandra men vet inte vilka som jag ska fylla med data och vilka som tas från andra tables.
Hur exporterar man databasen sen? pg_dump dbname > outfile ?
Du får fylla med samma värden när du lägger in datan. Det är ju inte så viktigt just nu vad som skulle räknas ut eller plockas in automatiskt.
Vill man ha sådana kolumner som räknar automatiskt eller uppdateras automatiskt är det antingen en computed column eller en trigger man använder sig av men det är att komplicera det hela och det har nog komplicerats tillräckligt i denna tråd.
Ett tips är ju att köra allt på https://sqlfiddle.com eller var det ett krav att du skulle exportera ut det i något format ? Hur ska det hela presenteras ?
Vilket schema kör du nu förresten ? zoomsters eller serafins ? Eller en egen ?
Ok, nepp inget krav att exporter i något specifikt format. Exporterar man table för table då?
Frågorna skall presenteras i databasen bara.
Har byggt upp de med @serafim modell.
Hur ska man tänka nu när man ska fylla data, kolumner som 'kund' 'bil' 'modell' är bara att fylla rakt upp och ner, med de andra som tar data från andra tables?
Jag tänker såhär (ni får ursäkta för den dåliga formuleringen):
Skulle fylla uthyrning med några rader men när jag ska fylla startmätarställning.
'uthyrning'
meter_at_start integer not null, -- startmätarställning
meter_at_end integer, -- slutmätarställning [b]borde inte dessa värden tas från bokning?[/b
Ser ju vilka kolumner som är kopplade med varandra men vet inte vilka som jag ska fylla med data och vilka som tas från andra tables.
Samma ordning som jag definierade tabellerna så kommer du inte få krångel med främmande nycklar.
Grundtanke: Bilar måste finnas innan man kan hyra ut något och kunder innan någon kan boka dem eller hyra dem.
Grundregel: börja alltid med tabeller utan främmande nycklar = Category och Client
@zoomster2: Metoden utvecklades av Lennart Lindström som äger IRM-konsult (reklam??). Han har utvecklat den vidare, notationen är lite annorlunda och det jag använde nu är en liten, liten del av metoden som numera är heltäckande och klarar av stora databasmodelleringsproblem. Jag har använt den och UML om vartannat i 32 år, varvat med andra metoder då behovet funnits.
Tack för berömmet men själv hittar jag både luckor i förklaringarna och brister i modellen. Den kom till under två tidiga morgontimmar i morse mest för att jag tyckte att alla som ville hjälpa till fragmenterade både frågan och hjälpen så att det inte riktigt hängde ihop. Tyckte det blev mer begripligt om man tog ett helhetsgrepp på problemställningen.
Jag tänkte att om alla fokuserade på min eller någon annan bättre modell och vi försöker besvara frågorna i ursprungsinlägget som @Tryckvagen skrev så kan vi hitta bristerna, rätta till modellen och komplettera med skillnaderna mot andra databashanterare.
Databasen som den definierats i mitt inlägg existerar i min postgreSQL-server som jag har gående på min egen dator. Jag har inte lagt in några data utan bara kollat att mina idéer verkar funka.
Vill gärna att folk påpekar fel och brister, inte med "vad är det här för skit" utan med "det här borde ändras så här", "det här måste till", "den här egenskapen bör flyttas till den tabellen", o.s.v.
Även naturligtvis, kommentarer om man tycker det är skit men då "det här är skit därför att ..."
Just nu håller jag på med annat (ren programmering för att gräva i XML och HTML för att hitta information som krävs i ett större projekt (och som landar som data i databaser efter kraftiga transformationer med hjälp av XSLT) så att hoppa på den här frågan innebär ett rejält kontextbyte. Det är däför jag hoppas att andra ska hjälpa med frågorna. De är inte svåra men tar en del tid.
Vad exakt utvecklades av Lennart Lindström ? Ser ut att vara ganska standard entity modelling
"Entity–relationship modeling was developed for database design by Peter Chen and published in a 1976 paper"
https://en.wikipedia.org/wiki/Entity%E2%80%93relationship_mod...
Samma ordning som jag definierade tabellerna så kommer du inte få krångel med främmande nycklar.
Grundtanke: Bilar måste finnas innan man kan hyra ut något och kunder innan någon kan boka dem eller hyra dem.
Grundregel: börja alltid med tabeller utan främmande nycklar = Category och Client
Har skapat några rader nu, skulle jag kunna svara på någon av de enklare frågorna? Eftersom det frågas efter lite över 500 mätarställningar så antar jag att jag måste ha >500 uthyrningar också, kan jag göra alla dessa i ett svep?
Alla följer inte samma språk/logik.
För några år sedan kom det databaser som HBase(ej ej relationsDB) som är schemalösa och fungerar enligt key-value principen(tänk HashMap).
Där används normal inga joins alls vilket gör att queries blir mycket enklare att ställa.
Men här gäller SQL och då blir det relationsdatabas. Tydligen har @Tryckvagen valt PostgreSQL och då är det definitivt SQL som gäller.
Dessutom är det inte alla applikationsområden som lämpar sig för onormaliserade eller denormaliserade data. Datakonsistens ( i betydelsen att det inte ska finnas motsägelser i datamängden) är svår att upprätthålla i de systemen och i många fall i projekt jag varit med i, där man valt NoSQL-databas har man också valt att implementera kontrollmekanismer (som använder SQL och vanliga tabeller) för att ha en konsistenskontroll. Som ett resultat av de behoven har det kommit ännu nyare system, s.k. NewSQL-system som använder snabbheten hos NoSQL och kontrollsystem som oftast körs som egna processer och som går igenom och korrigerar data.
- Råkade öppna porr på jobb14
- Hjälp med felsökning efter div krasher/freezes.7
- YouTube höjer priset24
- Samsung S24 Ultra slår Iphone 16 Pro Max i batteritest34
- Quiz: Kan du lista ut vad som ska bort? Del 2116
- Actina speldatorerna (från fyndtråden)5
- Pausreklam för alla på Youtube93
- Ålder på er som spelar44
- Vilken film såg du senast?13734
- C++ och dess framtid att programmera minnessäkert - Hur går utvecklingen?55
- Köpes mITX AM4-moderkort
- Köpes Köpes: Datorhörlurar, mek tangentbord, arm till skärmar, ev mus
- Köpes mATX med 1151 socket
- Säljes Mighty Setups Akuma TKL
- Säljes Ryzen 5 3600 boxed
- Säljes Picopsu, Noctua-kylare, div vatenkylning
- Köpes Söker grafikkort runt 2500-3100 kr
- Säljes Dell Alienware AW3418DW Curved 34” 3440x1440 IPS 120Hz G-Sync
- Köpes Söker XTZ Edge A2.300 slutsteg.
- Säljes Bra nybörjar dator
- Microsoft släpper ”Windows‑appen”5
- Nvidia kan sluta tillverka RTX 4090 i oktober16
- Samsung S24 Ultra slår Iphone 16 Pro Max i batteritest34
- Guide: Cybenetics vs 80 Plus – lär känna PSU-certifieringarna32
- Nu får Discord ordentlig kryptering15
- Vinnarna i TCL-tävlingen korade – olja, rymd och fjäll på prispallen!8
- Rykte: Playstation 6 kan släppas i två versioner42
- Pausreklam för alla på Youtube93
- Svag säljstart för Ryzen 9000‑serien79
- Återställ låst Iphone 16 med annan Iphone17
Externa nyheter
Spelnyheter från FZ
- Silent Hill 2-remaken blir konsolexklusiv till PS5 i minst ett år igår
- Maxat MS Flight Sim 2024 kräver 64 GB minne av din dator igår
- PSN-krav ger God of War: Ragnarök låga användarbetyg igår
- Det var en gång en spelhelg – och den börjar nu! igår
- Beyond Shadowgate är här: "Officiella NES-uppföljaren" igår