sql >> Databasteknik >  >> RDS >> Mysql

enkel fast tabell med flera kolumner kontra flexibla abstrakta tabeller

Vissa problem måste klargöras och lösas innan vi kan gå in i en rimlig diskussion.

Förutsättningskrav upplösning

  1. Etiketter
    I ett yrke som kräver precision är det viktigt att vi använder exakta etiketter, för att undvika förvirring och för att vi ska kunna kommunicera utan att behöva använda långrandiga beskrivningar och kvalificeringar.

    Det du har lagt upp som FixedTables är Onormaliserat . Helt rätt kan det vara ett försök till Third Normal form, men i själva verket är det en platt fil, Unnormalised (inte "denormalized). Det du har postat som AbstractTables är för att vara exakt, Entity-Attribute-Value , som är nästan, men inte riktigt, sjätte normalformen, och är därför mer normaliserad än 3NF. Förutsatt att det görs korrekt, förstås.

    • Den onormaliserade platta filen är inte "avnormaliserad". Den är proppfull av dubblering (ingenting har gjorts för att ta bort upprepade grupper och dubbletter av kolumner eller för att lösa beroenden) och Nulls, det är en prestationssvin på många sätt och förhindrar samtidighet.

    • För att bli denormaliserad måste den först normaliseras, och sedan backas normaliseringen lite av någon god anledning. Eftersom det inte är normaliserat i första hand kan det inte avnormaliseras. Det är helt enkelt onormaliserat.

    • Det kan inte sägas vara avnormaliserat "för prestation", eftersom det är en prestationssvin är det själva motsatsen till prestation. Tja, de behöver en motivering för bristen på formaliserad design], och "för prestanda" är det. Även den minsta formella granskning avslöjade den felaktiga framställningen (men väldigt få människor kan tillhandahålla, så den förblir dold, tills de får en utomstående att ta itu med, du gissade rätt, det enorma prestandaproblemet).

    • Normaliserade strukturer fungerar mycket bättre än onormaliserade strukturer. Mer normaliserade strukturer (EAV/6NF) presterar bättre än mindre normaliserade strukturer (3NF/5NF).

    • Jag håller med om tanken på OMG-ponnyer, men inte deras etiketter och definitioner

    • snarare än att säga 'inte "avnormalisera" om du inte måste' , jag säger, 'Normalisera troget, punkt' och 'om det finns ett prestandaproblem har du inte normaliserat korrekt' .

  2. Wikipedia
    Posterna för Normalformer och Normalisering erbjuder definitioner som är felaktiga; de förväxlar de normala formerna; de saknas när det gäller normaliseringsprocessen; och de ger lika vikt åt absurda eller tvivelaktiga NF:er som har avfärdats för länge sedan. Resultatet är att Wikipedia lägger till ett redan förvirrat och sällan förstått ämne. Så slösa inte bort din tid.

    Men för att komma vidare, utan att den referensen utgör ett hinder, låt mig säga detta.

    • Definitionen av 3NF är stabil och har inte ändrats.
    • Det finns mycket förvirring av NF mellan 3NF och 5NF. Sanningen är att detta är ett område som utvecklats under de senaste 15 åren; och många organisationer, akademiker såväl som leverantörer med sina produkter med begränsningar, hoppade på att skapa en ny "Normal Form" för att validera sina erbjudanden. Alla tjänar kommersiella intressen och akademiskt osunda. 3NF i sitt ursprungliga omanipulerade tillstånd avsett och garanterat vissa attribut.
    • Summan är, 5NF är idag, vad 3NF var tänkt att vara för 15 år sedan, och du kan hoppa över de kommersiella skämten och de tolv eller så "speciella" (kommersiella och pseudoakademiska) NF:erna däremellan, några av vilka identifieras i Wikipedia, och även det i förvirrande termer.
  3. Femte normalformen
    Eftersom du har kunnat förstå och implementera EAV i ditt inlägg kommer du inte ha några problem att förstå följande. Naturligtvis är en sann relationsmodell en förutsättning, starka nycklar, etc. Femte normalformen är, eftersom vi hoppar över den fjärde:

    • Tredje normalformen
      • vilket i enkla definitiva termer är att varje icke-nyckelkolumn i varje tabell har en 1::1 relation till tabellens primärnyckel,
      • och inga andra icke-nyckelkolumner
    • Noll dataduplicering (resultatet, om normaliseringen fortskrider flitigt, inte uppnås av intelligens eller erfarenhet enbart, eller genom att arbeta mot det som ett mål utan den formella processen)
    • inga uppdateringsavvikelser (när du uppdaterar en kolumn någonstans behöver du inte uppdatera samma kolumn som finns någon annanstans, kolumnen finns på ett och bara ett ställe).
    • Om du förstår ovanstående kan 4NF, BCNF och alla fåniga "NFs" avfärdas, de krävs för fysiska registerarkiveringssystem, som främjas av akademiker, ganska främmande för den relationella modellen (Codd).
  4. Sjätte normalformen

    • Syftet är eliminering av saknad data (attributkolumner), aka eliminering av nollvärden
    • Detta är den enda sanna lösningen på nollproblemet (även kallat Hantering av saknade värden), och resultatet är en databas utan nollvärden. (Det kan göras på 5NF med standarder och Null-ersättningar men det är inte optimalt.) Hur du tolkar och visar de saknade värdena är en annan historia.
    • Tekniskt sett är den inte en riktig normalform, eftersom den inte har 5NF som en förutsättning, men den har ett värde
  5. EAV vs sjätte normalform
    Alla databaser jag har skrivit, utom en, är rena 5NF. Jag har arbetat med (administrerat, fixat, förbättrat) ett par EAV-databaser, och jag har implementerat många riktiga 6NF-databaser. EAV är en lös implementering av 6NF, ofta gjord av personer som inte har bra koll på Normalisering och NF:erna, men som kan se värdet i, och behöver flexibiliteten i, EAV. Du är ett perfekt exempel.

    Skillnaden är denna:eftersom det är löst, och eftersom implementerare inte har en referens (6NF) att vara trogen, implementerar de bara det de behöver, och de skriver allt i kod; det blir en inkonsekvent modell.

    Medan en ren 6NF-implementering har en ren akademisk referenspunkt, och därför är den vanligtvis stramare och konsekvent. Vanligtvis visas detta i två synliga element:

    • 6NF har en katalog som innehåller metadata, och allt är definierat i metadata, inte kod. EAV har ingen, allt är i kod (implementerare håller reda på objekt och attribut). Uppenbarligen underlättar en katalog tillägget av kolumner, navigering och gör det möjligt att skapa verktyg.
    • 6NF när det förstås, tillhandahåller den sanna lösningen på Null-problemet. EAV-implementerare, eftersom de saknar 6NF-kontexten, hanterar saknade data i koden, inkonsekvent, eller ännu värre, tillåter null i databasen. 6NF-implementerare tillåter inte nollvärden och hanterar saknade data konsekvent och elegant, utan att kräva kodkonstruktioner (för nollhantering, du måste naturligtvis fortfarande koda för saknad data).

T.ex. För 6NF-databaser med en katalog har jag en uppsättning processer som [åter]genererar den SQL som krävs för att utföra alla SELECT, och jag tillhandahåller vyer i 5NF för alla användare, så att de inte behöver känna till eller förstå den underliggande 6NF-strukturen . De drivs bort från katalogen. Därför är ändringar enkla och automatiserade. EAV-typer gör det manuellt, på grund av frånvaron av katalogen.

Diskussion

Nu kan vi börja diskussionen.

"Självklart kan det vara mer abstrakt om värden är fördefinierade (Exempel:specialiteter kan ha sin egen lista)"

Säker. Men bli inte för "abstrakt". Upprätthåll konsekvens och implementera sådana listor på samma EAV (eller 6NF) sätt som andra listor.

"Om jag använder det abstrakta tillvägagångssättet kan det vara väldigt flexibelt, men frågorna kommer att bli mer komplexa med många kopplingar. Men jag vet inte om detta påverkar prestandan, exekvering av dessa 'merkomplexa' frågor."

  1. Joins är fotgängare i relationsdatabaser. Problemet är inte databasen, problemet är att SQL är besvärligt när man hanterar joins, speciellt sammansatta nycklar.

  2. EAV och 6NF databaser har fler Joins, som precis som fotgängare, varken mer eller mindre. Om du måste koda varje SELECT manuellt, så blir det besvärliga riktigt besvärligt.

  3. Hela problemet kan elimineras genom att (a) gå med 6NF över EAV och (b) implementera en katalog, från vilken du kan (c) generera all grundläggande SQL. Eliminerar också en hel klass av fel.

  4. Det är en vanlig myt att Joins på något sätt har en kostnad. Helt falskt.

    • Jongen implementeras vid kompilering, det finns inget väsentligt som "kostar" CPU-cykler.
    • Problemet är storleken på tabeller förenas, inte kostnaden för sammanfogningen mellan samma bord.
    • Sammanfoga två tabeller med miljontals rader vardera, på en korrekt PK⇢FK-relation, som var och en har lämpliga index
      (Unik på den överordnade [PK]-sidan; Unik på den underordnade sidan [PK=förälder FK + något]
      är omedelbar
    • Där underordnade index inte är unikt, men åtminstone de inledande kolumnerna är giltiga, går det långsammare; där det inte finns något användbart index är det naturligtvis väldigt långsamt.
    • Inget av det har att göra med kostnaden för medlemskap.
    • Där många rader returneras, kommer flaskhalsen att vara nätverket och disklayouten; inte kopplingsbearbetningen.
  5. Därför kan du bli så "komplex" som du vill, det kostar inget, SQL klarar det.

Jag skulle vara intresserad av att veta vad som är upp- och nackdelar med båda metoderna. Jag kan bara föreställa mig själv, men jag har inte erfarenheten att bekräfta detta.

  1. 5NF (eller 3NF för de som inte har tagit steget) är det enklaste och bästa, när det gäller implementering; användarvänlighet (utvecklare såväl som användare); och underhåll.

    • Nackdelen är att varje gång du lägger till en kolumn måste du ändra databasstrukturen (tabell DDL). Det är bra i vissa fall, men inte i de flesta fall, på grund av ändringskontroll på plats, ganska betungande.
    • För det andra måste du ändra befintlig kod (kod som hanterar den nya kolumnen räknas inte, eftersom det är ett krav):där goda standarder implementeras, minimeras det; där de saknas är omfattningen oförutsägbar.
  2. EAV (vilket är vad du har postat), gör att kolumner kan läggas till utan DDL-ändringar. Det är den enda anledningen till att människor väljer det. (kod som hanterar den nya kolumnen räknas inte, eftersom det är ett krav). Om det implementeras väl kommer det inte att påverka befintlig kod; om inte, kommer det att göra det.

  3. Men du behöver EAV-kapabla utvecklare.

    • När EAV implementeras dåligt är det avskyvärt, en värre röra än 5NF gjort dåligt, men inte värre än Unnormalised vilket är vad de flesta databaser där ute är (felaktigt framställt som "denormaliserad för prestanda").
    • Naturligtvis är det ännu viktigare (än i 5NF/3NF) att ha en stark transaktionskontext, eftersom kolumnerna är mycket mer distribuerade.
    • På samma sätt är det viktigt att behålla deklarativ referensintegritet:de smuts jag har sett berodde till stor del på att utvecklarna tog bort DRI eftersom det blev "för svårt att underhålla", resultatet blev, som du kan föreställa dig, en mamma av en datahög med dubbletter av 3NF/5NF-rader och kolumner överallt. Och inkonsekvent Null-hantering.
  4. Det finns ingen skillnad i prestanda, förutsatt att servern har konfigurerats rimligt för det avsedda syftet. (Ok, det finns specifika optimeringar som bara är möjliga i 6NF, som inte är möjliga i andra NF:er, men jag tror att det ligger utanför ramen för denna tråd.) Och återigen, EAV som gjorts dåligt kan orsaka onödiga flaskhalsar, inte mer än Onormaliserad.

  5. Naturligtvis, om du går med EAV, rekommenderar jag mer formalitet; köp hela pundet; gå med 6NF; implementera en katalog; verktyg för att producera SQL; Visningar; hantera saknade data konsekvent; eliminera null helt och hållet. Detta minskar din sårbarhet för kvaliteten på dina utvecklare; de kan glömma de esoteriska problemen med EAV/6NF, använda Views och koncentrera sig på applogiken.



  1. SQL Server-markörtyper - Dynamisk markör | SQL Server Tutorial / TSQL Tutorial

  2. Att nå 2100 parametergränsen (SQL Server) när du använder Contains()

  3. PostgreSQL kan inte påbörja/avsluta transaktioner i PL/pgSQL

  4. Optimera gruppvis maximal fråga