WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   Databasnormalisering av datum? (https://www.wn.se/forum/showthread.php?t=24521)

Frej 2007-10-22 13:53

Normaliserar ni era datum?

Med en smalint (2 byte) kan man ju då få ~275 år.
Istället för en smaldatetime (4 byte) med 179 år.

Eller vad rekomenderar ni, håller på att sätta upp en databas
med normalisering i alla led, och började fundera lite över datum.

hnn 2007-10-22 14:29

DATE typen :)
eller TIMESTAMP

martine 2007-10-22 15:01

Citat:

Originally posted by Frej@Oct 22 2007, 13:53
Eller vad rekomenderar ni, håller på att sätta upp en databas
med normalisering i alla led, och började fundera lite över datum.

Det effektivaste är säkerligen att använda de inbyggda typerna (DATE etc) särskilt om man behöver göra sökningar på datum.

Skulle själv aldrig använda något annat än DATE eftersom det krånglar till hämtningar (SELECT) från databasen när man inte kan jämföra och hämta datum utan vidare (t.ex. med BETWEEN).

Frej 2007-10-22 15:14

Martine: Självklart kan man hämta och använda sig av Between även om man normaliserar data, man använder vyer för att skapa "tabeller" för att hämta datat man vill hantera. Förövrigt är det inte "best practice" att använda SELECT, INSERT, UPDATE eller DELETE direkt mot tabeller. SELECT skall köras mot Vyer och UPDATE, INSERT och DELETE skall köras mot lagrade procedurer.

Det jag undrar över är om man skall ha en tabell med en smalint (Identity) kolumn och en smaldatetime kolumn.
Sedan i övriga tabeller så refererar man till smalint värdet för att få tag i rätt datum. på detta vis så sparar man 2 byte för varje datum där det finns 3 eller fler av samma datum. Dock förlorar man 2 byte om datumet vara används en gång och blir ingen skillnad vid dubletter.

Hmm...
Jag har ju nästan svarat på detta själv. Alltså beror det på hur mycket samma datum kommer användas i min databas.

Jag undrar ändå, om någon annan normaliserar datum?

oller 2007-10-22 18:16

Nej. Skulle tippa att det är rätt så sällsynt.

Mvh

SimonP 2007-10-22 22:31

Du kan tjäna några bytes men samtidigt ökar ju CPU belastningen lite eftersom det krävs extra anrop enbart för att lagra och hämta datum.

Frej 2007-10-23 09:56

SimonP: Lagringen kan jag hålla med om att det krävs ett extra anrop att få fram om Datumet redan existerar och returnera IDt eller om man skall skapa en ny rad för valt datum.

Men att det skulle ta mer CPU kraft att endast hämta datum vet jag inte. Då man kan fylla varje data page med fler rader så krävs färre läsningar av HDD huvudet vilket i sin tur medför bättre I/O prestanda. Och det är till 99.9% (ej fakta) HDD som begränsar I/O prestandand och inte CPUn.

SimonP 2007-10-23 11:08

Citat:

Originally posted by Frej@Oct 23 2007, 09:56
Men att det skulle ta mer CPU kraft att endast hämta datum vet jag inte. Då man kan fylla varje data page med fler rader så krävs färre läsningar av HDD huvudet vilket i sin tur medför bättre I/O prestanda. Och det är till 99.9% (ej fakta) HDD som begränsar I/O prestandand och inte CPUn.
Självklart tar det lite CPU, alla förfrågningar tar CPU, och ligger resultatet efter en SELECT fråga inte i cacheminnet ökar även I/O från hdd, precis som du skriver. Men cacheminnet gör att I/O-prestandan från HDD inte behöver vara avgörande jämt, ju mer RAM-minne ju mindre HDD I/O.

Robert 2007-10-23 20:20

Personligen skulle jag inte försöka mig på normalisering på den här nivån. Det finns anledningar till att man tex inte bryter ut egennamn i separata tabeller, och datum.... tja, för att spara några bytes? Disk är billigt, en JOIN är dyr! ;)

Det är lika dåligt att övernormalisera en databas som att inte alls normalisera. Mera aggregeringar till folket! :)

[edit: stavfel]

martine 2007-10-23 22:55

Citat:

Originally posted by Frej@Oct 22 2007, 15:14
Martine: Självklart kan man hämta och använda sig av Between även om man normaliserar data, man använder vyer för att skapa "tabeller" för att hämta datat man vill hantera. Förövrigt är det inte "best practice" att använda SELECT, INSERT, UPDATE eller DELETE direkt mot tabeller. SELECT skall köras mot Vyer och UPDATE, INSERT och DELETE skall köras mot lagrade procedurer.
Nu är det möjligt att du är mycket bättre insatt i databaser men ger det verkligen alltid en prestandavinst att använda vyer och procedurer? Det är ju trots allt en omväg till informationen…

Den stora vinsten ligger väl antagligen i att använda rader av fast bredd och inte om det kostar 2 eller 3 bytes. För framtidssäkring känns det trots all säkrare att satsa på "enkla" lösningar och låta databasen sköta optimeringen. Det kan mycket väl hända att lyfta 4 bytes data från en tabell går snabbare än 2 bytes om du har en processor som kör med 64 bitar, med 2 bytes måste den då maska ut 32 bitar och skicka dem separat, medans 4 bytes kan skickas löpande.

"Supernormalisering" betyder ju inte alltid prestandavinst och för min del tycker jag frågan också är om man inte gör saker krånligare än vad är nödvändigt i optimeringssyfte.

Weaver 2007-10-23 23:03

Nej, normalisera inte datum. Använd datatyperna timestamp, date, time eller datetime beroende på dina behov.

Ett undantag dock. Om detta datumet skulle ändras väldigt ofta så kan du få bättre performance genom att normalisera. Ett exempel (som dock inte är datumbaserat) hade kunnat vara en räknare för hur många gånger en sida har visats. I databastabellen lagrar du content för sidan samt hur många gånger den visats. I detta fallet hade du tjänat performance genom att bryta ut räknar INTen till en egen tabell för att inte förstöra query cachen varje gång en ny sidvisning sker.

Weaver 2007-10-23 23:12

Citat:

Nu är det möjligt att du är mycket bättre insatt i databaser men ger det verkligen alltid en prestandavinst att använda vyer och procedurer? Det är ju trots allt en omväg till informationen…
Vyer ger ingen prestandavinst men å andra sidan har de bara ett väldigt litet overhead. Dock är det väldigt lätt att skapa sig prestandaförluster med dem om man inte har tungan rätt i mun [1].

Procedurer kan generellt ge ganska stor prestandavinst men det existerar inte några bra verktyg för att debugga dem så de är en mardröm att arbeta med när man kommer upp i komplexitet.

[1] http://www.mysqlperformanceblog.com/...-troublemaker/

Robert 2007-10-28 10:42

Citat:

Ursprungligen postat av martine
Citat:

Ursprungligen postat av Frej
Martine: Självklart kan man hämta och använda sig av Between även om man normaliserar data, man använder vyer för att skapa "tabeller" för att hämta datat man vill hantera. Förövrigt är det inte "best practice" att använda SELECT, INSERT, UPDATE eller DELETE direkt mot tabeller. SELECT skall köras mot Vyer och UPDATE, INSERT och DELETE skall köras mot lagrade procedurer.

Nu är det möjligt att du är mycket bättre insatt i databaser men ger det verkligen alltid en prestandavinst att använda vyer och procedurer? Det är ju trots allt en omväg till informationen…

[..klipp..]

"Supernormalisering" betyder ju inte alltid prestandavinst och för min del tycker jag frågan också är om man inte gör saker krånligare än vad är nödvändigt i optimeringssyfte.

Jag ser inte vilken databas det är frågan om, men iaf i MS SQLServer så lär sig query execution enginen vad en SP gör och optimerar därefter sin sökning. Därför är det dåligt att köra inline sql mot en databas -eller- dynamisk sql i en SP. Sedan så tycker jag det är bättre ur en arkitekturell synvinkel att använda sig av SP's.

Jag skulle säga att normalisering(läs Övernormalisering) inte ligger i samma vågskål som Prestanda. Ökar du det ena så minskar du det andra. Man kan fundera på att tom aggregera information om det visar sig att (vilket ofta är sant) det skrivs kanske 1 gång per 1000 läsningar (eller mer), vilket betyder att man gör de tidskrävande sakerna vid skrivning och optimerar via aggregering för de andra 1000 tillfällena. Exempel på detta kan tex vara räknare för foruminlägg som updateras vid skrivning och inte räknas ut vid läsning etc.

fors 2007-10-28 10:51

Citat:

Originally posted by Weaver@Oct 23 2007, 22:03
Nej, normalisera inte datum. Använd datatyperna timestamp, date, time eller datetime beroende på dina behov.

Ett undantag dock. Om detta datumet skulle ändras väldigt ofta så kan du få bättre performance genom att normalisera. Ett exempel (som dock inte är datumbaserat) hade kunnat vara en räknare för hur många gånger en sida har visats. I databastabellen lagrar du content för sidan samt hur många gånger den visats. I detta fallet hade du tjänat performance genom att bryta ut räknar INTen till en egen tabell för att inte förstöra query cachen varje gång en ny sidvisning sker.

Det senare kan man ju dock lösa genom att cachelagra det i minnet istället. Så slipper förändra databasdesignen.

Weaver 2007-10-28 17:02

Citat:

Ursprungligen postat av fors
Citat:

Ursprungligen postat av Weaver
Nej, normalisera inte datum. Använd datatyperna timestamp, date, time eller datetime beroende på dina behov.
Ett undantag dock. Om detta datumet skulle ändras väldigt ofta så kan du få bättre performance genom att normalisera. Ett exempel (som dock inte är datumbaserat) hade kunnat vara en räknare för hur många gånger en sida har visats. I databastabellen lagrar du content för sidan samt hur många gånger den visats. I detta fallet hade du tjänat performance genom att bryta ut räknar INTen till en egen tabell för att inte förstöra query cachen varje gång en ny sidvisning sker.

Det senare kan man ju dock lösa genom att cachelagra det i minnet istället. Så slipper förändra databasdesignen.

Det kan du väl inte alls, detta värdet måste ju skrivas till databasen vid varje pageview. En cache kan ju bara hjälpa dig om du har mycket läsningar.

fors 2007-10-28 18:24

Citat:

Ursprungligen postat av Weaver
Citat:

Ursprungligen postat av fors
Det senare kan man ju dock lösa genom att cachelagra det i minnet istället. Så slipper förändra databasdesignen.


Det kan du väl inte alls, detta värdet måste ju skrivas till databasen vid varje pageview. En cache kan ju bara hjälpa dig om du har mycket läsningar.

Alltså om man cachelagrar sidinnehållet i minnet och uppdaterar tabellen som vanligt. Dvs, man använder inte query-cachen. Det får ju ungefär samma resultat som din lösning.

Weaver 2007-10-28 18:46

Citat:

Originally posted by fors@Oct 28 2007, 19:24
Alltså om man cachelagrar sidinnehållet i minnet och uppdaterar tabellen som vanligt. Dvs, man använder inte query-cachen. Det får ju ungefär samma resultat som din lösning.
Nu har detta blivit lite off-topic. Detta kommer inte att fungera om du visar antalet visningar av sidan på själva sidan.


Alla tider är GMT +2. Klockan är nu 22:43.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson