Laden...

Partitionierung von Tabellen

Erstellt von jaipur vor 9 Jahren Letzter Beitrag vor 9 Jahren 5.063 Views
J
jaipur Themenstarter:in
127 Beiträge seit 2007
vor 9 Jahren
Partitionierung von Tabellen

verwendetes Datenbanksystem: MS SQL Server 2012 Express

Hallo!

Es handelt sich um 5000 Dateien mit je 1000 Zeilen. Da ich hier sicherlich nicht 5.000.000 Zeilen durchlaufen möchte, bin ich auf die Idee gekommen diese zu partitionieren, klappt so weit auch ganz gut! Allerdings mache ich dieses dynamisch, für jede Datei eine eigene Tabelle.

Was mich jetzt hier gestört hat, neben meinen Tabellen (Produkte, Artikel,...) habe ich jetzt sehr viele dynamisch erzeugte Tabellen, für jedes Produkt und für jeden Artikel.

Daher bin ich beim programmieren auf die Idee gekommen, diese in verschiedene Datenbanken zu packen:
DbListe, hier alle Tabellen wie z.B. Kunden, Produkte, Artikel
DbListeData, hier alle dynamischen Tabellen, wie z.B. A000001 für Artikel mit der ID 1

Macht so eine Trennung überhaupt Sinn? Was mir hier nicht gefallen hat ist, das ich bei einer Trennung keine Fremdschlüssel über Datenbanken hinweg vergeben kann. Das finde ich persönlich sehr schade, denn hier hatte mir LINQ natürlich alles an Arbeit abgenommen.

Meine Frage, macht eine Trennung der Tabellen überhaupt Sinn oder bin ich von LINQ mittlerweile zu sehr verwöhnt worden?

T
2.224 Beiträge seit 2008
vor 9 Jahren

@jaipur
Ich verstehe nicht genau warum du deine Daten trennen willst.
Klar sind 5 Mio Datensätze schon eine Menge aber wo genau liegt da das Problem?

Wenn du ein Performance Problem bei 5 Mio Einträgen hast, dann würde ich die Struktur deiner Daten in Frage stellen.
Ggf. fehlen dir dann entscheidene Stellschrauben wie Indizies etc.

Oder liegt es an der Verarbeitung der Daten an sich?
Wo genau klemt den dort der Schuh?
Ggf. mal mit Threads arbeiten oder gibt es dort noch ein anderen Engpass?

Bevor man die Daten dynamisch aufteilt, sollte man schon gute Gründe dafür haben.
Ich halte dies nur in speziellen Fällen wirklich sinnvoll.
Bei einem unserer uralten Shops wurde dies auch mal gemacht.
Das Endergebnis war dann ein fasst unbrauchbare DB.
Diese dann per Mangement Studio zu öffnen hat locker mal 15 Min. gedauert, da einige Tausend Tabellen aufgelistet wurden.

Wenn du also keinen guten Grund hast dies nicht alles in eine Tabelle zu packen, dann stellt sich aber die Frage ob die DB dann überhaupt der richtige Ort für deine Daten ist.

Bei einer unserer Lösungen, die GPS Daten speichern, haben wir z.B. alle Daten die älter als eine Woche sind ausgelagert.
Diese wieder im Dateisystem gespeichert in einer sauberen Ordner Struktur die dann als Index dient.
Somit erreichen wir auch eine hohe Performace ohne eine Datenbank.

Um die Lage aber gut einschätzen zu können, wären einige Details von nöten.
Hoiffe du kannst damit aushelfen.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

J
jaipur Themenstarter:in
127 Beiträge seit 2007
vor 9 Jahren

Mit der Antwort hätte ich jetzt nicht gerechnet 😉

Es handelt sich um eine Kundendatenbank mit allen Produkten, Produkte bestehen aus mehreren Artikeln. Ich möchte bei einem Mausklick zu einem Artikel sagen in welchem Produkt diese Verbaut ist.

So ein Produkt besteht aus 500 bis 2000 Artikeln und das bei 5000 Kunden. Und ein Produkt besteht aus mehreren Produkten.

Beispiel Auto (Mercedes Benz C200): Sitz, Lenkrad, ...in der Summe ca. 100 "Einheiten"
Artikel: 5 Meter Stoff, 500 Gramm ABER unterschiedliche Artikelnummern.

Meine Tabellen:
Kunden: ID, Nummer, Name, Adresse
Einheiten: ID, Nummer, Name
Artikel: ID Nummer, Name

Nicht erschrecken, ich habe für jeden Artikel zwei dynamische Tabellen erstellt, in dieser habe ich alle Produkte und in der anderen alle Einheiten. Äh, für die "Einheiten" auch... Da sind ca 5000 Einheiten und 20000 Artikel, also 50000 Tabellen in der Datenbank!

Öffnen kann ich diese noch ohne Probleme, beim programmieren werden die Listen auch sehr schnell abgefragt.

Reichen dir diese Details aus?

3.825 Beiträge seit 2006
vor 9 Jahren

Hallo,

Daher bin ich beim programmieren auf die Idee gekommen, diese in verschiedene Datenbanken zu packen

Warum das ?

Macht so eine Trennung überhaupt Sinn?

Nein.

5000 Kunden und 2000 Artikel ist für eine Datenbank keine Menge.

Falls Du irgendwo Performance-Probleme hast dann verbessere die Datenbankstruktur.

Wenn Deine Datenbank 1 TB erreicht dann kannst Du vielleicht auf mehrere Partitionen aufteilen.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

J
jaipur Themenstarter:in
127 Beiträge seit 2007
vor 9 Jahren

Die 5000 Produkte mit 2000 Artieln sind nicht das Problem, wenn ich aber zu einem Artikel jedes Produkt aufgelistet bekommen möchte, dann sind diese 5000 x 2000 da schon eher ein zeitliches Problem.

Oder wie würdet ihr das lösen? Ich hatte zuerst eine Tabelle mit dem Namen ArtikelInProdukt:
Id, ProduktId, ArtikelId
Diese Tabelle hatte dann sehr viele Einträge, also diese 5000 x 2000, irgendwo zwischen 5 Und 10 Millionen. Daher mein Gedankw mit der Partitionierung...

Oder wie würdet ihr die Beziehung zwischen Produkt und Artikel herstellen?

3.825 Beiträge seit 2006
vor 9 Jahren
irgendwo zwischen 5 Und 10 Millionen

Für einen SQL Server ist das wenig. Wenn eine Abfrage länger als wenige Sekunden dauert hast Du was falsch gemacht.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

T
2.224 Beiträge seit 2008
vor 9 Jahren

@jaipur
Vielleicht hilft dir ein kleiner Kniff.

Wir hatten letztens auch ein Performance Problem bei einem unserer Projekte.
Dabei hatten wir in der DB 4 Tabellen die jeweils Daten von der obersten zur untersten Ebene hatten.

Aufbau (vereinfacht)
-Tour (Kann 1 bis N mal vorkommen)
-Auftrag (Kann 1 bis N mal innerhalb der Tour vorkommen)
-Lieferung (Kann 0 bis N mal innerhalb des Auftrags vorkommen)
-Lieferpositionen (Kann 0 bis N mal innerhalb einer Lieferung vorkommen)

Nun hatten wir aber das Problem, dass wir die Daten für ein TreeView, dass alle Ebenen benötigte, effizient einladen mussten.
Hier haben wir dann einfach einen Kniff gemacht.
Und zwar habe ich in der DB die Abfrage per LEFT JOIN gemacht und entsprechend alle Ebenen in einer Abfrage bekommen.
Zum trennen habe ich dann manuell einfach Prefix Spalten im Select angehangen.
In der Programmierung muss man dann nur die Daten handisch parsen, was aber mit sauberer Programmierung schnell geht.
Natürlich hat unsere Verarbeitung eher 10-20 Touren, jede Tour ca. 10 bis 30 Aufträge und jeweils eine Lieferung aber aktuell keine Lieferpositionen.

Könnte aber auch bei deinem Problem das dauerhafte Nachladen der Daten sparen, da du eben nur eine Abfrage für die Daten brauchst und dann eben per Programmierung parsen musst.
Sollte auch bei vielen Daten schnell gehen.

Hier musst du aber schauen, dass du das sauber umsetzt.
Je nachdem wie groß deine Datenstrukturen sind, kann das umsetzen des Parsers schwierig werden.

Nachtrag:
Das Select sah dann ungefähr so aus:
Select [_Tour], t., [_Auftrag], a., [Lieferung], l., [_Liferposition], p....
Die "
" Spalten marikeren dann das Prefix, was mit Null gefüllt war.
Dann kann ich sehen welche Daten ich gerade auslese und kann entsprechend die Struktur befüllen.

Nachtrag 2:
Die Verknüpfungen waren dann wie folgt.
-Tour(Guid PK)
-Auftrag(Guid PK, TourGuid FK)
-Lieferung(Guid PK, AuftragGuid FK)
-Lieferposition(Guid PK, LieferungGuid FK)

So sollte es bei dir in etwa aufgebaut sein.
Dann sollte es auch so klappen.
Musst dann eben nur deine Key Tabelle dort mit rein schieben.
Ob das aber so performant ist, kann ich nicht sagen.
Würde sogar das Gegenteil erwarten, da wir das auch vorher mit einer extra Tabelle hatten aber das eben unperformant war bei anderen Operationen.
Ggf. sollten sich dann deine Strukturen auch ändern.
Aber das musst du testen.

Nachtrag 3:
Nutze lieber ein Dictionary anstelle einer Liste.
Da jede Tabelle ja einen festen Namen hat, sollte dann auch die Suche nach den Tabellen innerhalb deiner Programmierung schneller gehen 😃
Natürlich nur, wenn dies deine Daten zu lassen.
Kenne ja die Liste nicht vom Inhalt her.
Würde aber aktuell von String ausgehen oder liege ich damit falsch?
Aber je nachdem ob mein Ansatz bei dir klappt, kannst du das aufteilen kann weglassen.

Nachtrag 4:
Mach es wie bei meinem Ansatz, wenn möglich.
Eine extra Tabelle mit den Schlüsseln macht hier Performance Probleme.
Spätestens bei der Abfrage muss dann die gesamte Tabelle abgesucht werden, was die Performance in den Keller zieht.
Entsprechend sollten die jeweiligen Zuweisungen zu den höheren Ebenen in einer extra Spalte innerhalb der unteren Ebene gespeichert sein.
Mag zwar etwas unschön sein, liefert aber die bessere Performancen.

Wenn du dann noch per Index die Daten aus der obersten Ebene eingrenzen kannst, dann sollte das einladen flott gehen.
Selbst wenn du einen riesigen Füllstand hast.
Dann musst du nur schauen, dass dein Code zum parsen der gequetschten Daten schnell genug ist.
Aber selbst das sollte kein großes Problem sein.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.