12. marts 2005 - 11:09Der er
8 kommentarer og 1 løsning
Clustered index vs flere tabeller.
Jeg er igang med et projekt på mit arbejder hvor jeg skal lave et treeview på en hjemmeside som skal indeholder omkring 1000 punkter. Der vil forekomme jævnlige opdateringer af menuen. Jeg har snakket om det med en kollega og vi er ikke enige om hvordan vi skal ligge data til treeviewet ind i databasen. Treeviewet bliver i 3 niveauer med overpunkter, mellempunkter og underpunkter. Data hentes fra databasen og skrives til en xml fil. Det er først på det tredje niveau at der skal bruges en url til at skifte side. Han mener at det bør laves i en tabel med et clustered index på denne måde: MenuID MenuIndex MenuTitel MenuUrl. MenuID er et autogeneret ID. MenuIndex er et clustered index hvor data er fordelt på denne måde 01.00.00 på denne måde hvor de 2 første tal viser hvilket overmenupunkt den enkelte række tilhører. De 2 næste tal viser hvilket mellempunkt rækken tilhører. f.eks. 01.02 er andet mellempunkt under overpunkt 1. De sidste 2 tal viser hvilket underpunkt rækken tilhører. f.eks 02.02.03 er 3 underpunkt under anden mellempunkt som ligger under andet overpunkt. MenuTitel er titelen på det enkelte menupunkt. MenuUrl er den side som skal kaldes via et underpunkt. Da der ikke skal kaldes nogen værdier fra MEnuUrl til over og mellempunkter skal kolonnen enten tillade null værdier eller have skrevet et 0 som default value. Her vil alt data blive hentet ud med en SELECT * Menu. Der efter skal data undersøges og fordeles på de enkelte niveauer.
Min tilgang til det vil være en struktur med 3 tabeller. en til overpunkter, en til mellempunkter og en til underpunkter. Til overpunkter vil tabellen se sådan her ud: OverpunktID Titel.
Til mellempunkter vil tabellen se sådan her ud: MellemPunktID Titel OverpunktID(relation til overpunkt tabellen)
Til underpunkter vil tabellen se sådan her ud: UnderPunktID Titel Url MellemPunktID(relation til mellempunkt tabellen). I min til gang hentes data ud undervejs. De skrives til xml filen via 3 foreach sætninger inden i hinanden. Først Hentes alle overpunkter ud. Derefter hentes alle mellempunkter som tilhører det enkelte overpunktid. Til sidst hentes alle underpunkter som tilhører det enkelte mellempunkt.
Jeg håber at denne beskrivelse er fyldstgørende nok. Ellers så bare spørg.
Spørgsmålet er hvilken en metode er bedst, hurtigst og bedst for databasen ? Du må meget gerne give nogle gode begrundelser hvorfor det ene er bedre end det andet.
Siden som det skal vises på er en asp.net side programmet i c#.
Med kunstig intelligens skaber HP’s nye OmniBook X 14 en unik og skræddersyet brugeroplevelse målrettet dem, der ønsker høj ydeevne og intelligente funktioner
Jeg er helt sikkert tilhænger af din model med 3 tabeller. Og når det så er sagt er der en endnu bedre løsning på opgaven. Begrænsningen for jer begge ligger i at et er rimeligt kompliceret at udvide løsningen på et senere tdispnkt evt. med et ekstra underpunkt. Din vens løsning er ikke så god, fordi når data skal findes frem skal der bruges en masse strengmanipulation.. ala.. find første punktum tag de næste 2 chars osv osv.. Det giver en stor flaskehals! Så istedet for at bruge 3 tabeller skal du kun bruge en inde i den skal du blot lave en ekstra kollonne der indeholder på hvilket niveau menupunktet ligger, altså en slags level_id. I det her tilfælde vil der være 3 levels, men den kan jo således snildt udvides :O)
Du kan så hente data udfra din tabel evt. igennem din kode eller vha. et par rekursive joins - Det er lidt op til dig selv hvad du finder bedst, men nu når du allerede er igang (rent tankemæssigt) med at lave det i koden så fortsæt med det. Men husk at du altså kan lave en noget mere fleksibel kode med en rekursiv funktion, men det vigtigste er jo at I kommer igang med noget brugbart - herefter kan den laves mere fleksibel :O)
Rent indexmæssigt vil det være umuligt at lave et brugbart index på xx.yy.zz, for når der skal kigges efter et specielt tal skal der igen bruges strengmanipulation på venstre side af lighedstegnet - hvilket gør at indexet aldrig kommer i brug.
Der ligger så vidt jeg kan se et potentielt problem i dit foreslag da et felt url ikke bruges på de 2 første niveauer men kun på det tredje niveau. Det vil betyde at der i en del tilfælde intet vil stå i det felt(null) eller bare et 0.
Et rekursivt join er jo et der kalder sig selv igen og igen, det er også kendt som et selfjoin. Artiklen skriver at det ofte kan være svært at få til at fungere... hmm ja både og vil jeg sige, noglegange er den slags rigtig gode og andre gange skal man finde en anden løsning - Det kan afsløres ved lidt prototyping osv., den artikel du har fundet ser rigtig god ud og har og vil sikkert give dig en masse gode idéer
Ja du har ret der fremkommer NULLs i de ubenyttede urls eller... Dette her vil ikke løse problemet, men kan evt. være med til at normalisere dine data. -> Istedet for at skrive url'en direkte i (jeg kalder den tbl_levels) kan du referere vha. en id til en urltabel. Når url'en får en id kan du også bedre holde øje med hvor mange gange der bliver klikket på menupunktet, men det er jo en helt anden snak. Anyway du kunne lave en url_id kollonne og når url'en blot var tom kunne den evt. pege på id 0 i urltabellen som jo måske kunne være et NULL. Der er mange muligheder i det setup, men det vigtigste er blot ikke at designe noget som på sigt kan begrænse sig selv og det vil mit forslag ikke gøre. Pas på ikke at lade dig begrænse af eks.vis xx.yy.zz eller 3 tabeller. (begge løsninger er jo rimeligt begrænsede *S*)
så skal jeg vel også lave en del tidskrævende operationer for at sikre mig at f.eks. nodelev1 lukker når der ikke er flere elementer i nodelev2 som tilhører det bestemte nodelev1.
Eller har du en fiks ide det til hvordan jeg gør det ?
Ja det skal du jo sikre dig, men den slags kan snildt klares hvis du eks.vis bruger en rekursiv funktion (der for du det hele forærende). Jeg tror for dit vedkommende at det nemmeste vil være hvis du trækker det hele ud enten i et datatable eller som en datareader og så bare går i gang med at loope det hele igennem. Når du forlader dit rekursive kald for hver indgang skal du blot huske at afslutte noden igen, men ligeså snart du har forstået idéen med et rekursivt kald vil du meget nemmere forstå det her :O)
Jeg har lavet en tabel som ser ud på denne måde: MenuID | Menucategoryid | ParentID | PostLevel | Titel | SortOrder MenuID er et autogeneret id. Menucategoryid er det menuid som den enkelte række hører ind under ParentID er id'et p det menupunkt som ligger et niveau højere. Postlevel er niveauet i træet hvor det enkelte punkt ligger Titel er titelen på det enkelte punkt SortOrder er en int som skal bruges til at sortere de enkelte punkter på hver niveau. Det vil sige at sortorder bruges til at sortere de enkelte niveauer og det er i forbindelse med det at problemet opstår. Der skal nemlig ikke være en alfabetisk sorteringsorder på data men derimod en bruger defineret hvor det menupunkt med sort 1 står først osv.
Spørgsmålet er kan jeg bruge denne metode med en enkelt tabel eller skal jeg bruge flere tabeller ??
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.