Wenn ich dich richtig verstehe, gibt es eine Tabelle Lagerbewegung, in der die Bewegungen aus (von,nach,menge) bestehen. Vermutlich gibt es noch eine Tabelle Lagerstamm, die die einzelnen Lager definiert. Dann müsste es in etwa so gehen:
select ls.lager, sum(lb.menge)
from ( select von as lager, -menge as menge from lagerbewegung
union all
select nach, menge from lagerbewegung
) lb right join lagerstamm ls on lb.lager = ls.lager
group by ls.lager
Wie würdet ihr am ehesten folgenden Fall abbilden: Normalerweise werden Stammdaten in der Landessprache erfasst, manche Kunden benötigen aber die Stammdaten in mehreren Sprachen (und dies ggf. parallel in einer Ausgabe - z.B. deutsch und englisch, aber das nur am Rande).
Ich kann mir dafür mehrere Lösungsansätze in der Datenbank vorstellen, so ganz glücklich bin ich bei keinem davon. Meine bisherigen 3 Ansätze:
1. (Imho schlechtester Ansatz) Man lässt nur eine begrenzte Zahl von Sprachen zu, und doppelt die betroffenen Felder innerhalb einer Tabelle (z.B. BezeichnungDe, BezeichnungEn).
2. Man legt keinerlei Sprachabhängige Anteile in die eigentliche Stammdatentabelle, und hat neben dieser eine Tabelle mit den sprachabhängigen Teil die auf die Id der Stammdatentabelle verweist, und dazu die Sprache/Kultur als Primärschlüssel hält.
Beispiel:
TabelleA
- Id [Primärschlüssel]
- <weitere Sprachunabhängige Felder>
TabelleALang
- Id [Primärschlüssel]
- Sprache/Kultur [Primärschlüssel] (z.B. de-DE - ggf. in zwei Felder für "Fallback" gesplittet)
- <Sprachabhängige Felder>
3. Wie 2. nur das man die Felder einer Sprache (nennen wir sie mal die "Hauptsprache" oder "Standardsprache) in der TabelleA hält, und die zweite Tabelle nur bemüht, wenn man davon abweichende Eingaben machen will. Problematisch sehe ich das nur dann an, wenn ein System beispielsweise von mehreren verschiedenen Sachbearbeitern in unterschiedlichen Länder gepflegt wird.
@lilbeat
zum "spielen", also zum üben mit c++ und DB's ist dein Konzept tragbar, für ernste Projecte wird kaum einer SQL uebers Inet schicken, weil zu unperformant / zu viel Overhaed.
Weswegen Datenbankserver über Inet eher selten verwendet werden. Also meist ist soweiso ne Zwischenschicht (die ne Eigene Logik hat, und damit den Verkehr komprimiert und cacht) da dran. Weswegen man auch seltener SQL Angebote fuers Web findet.
Besser: nen eigenes Protokoll entwerfen, und die DB's als reine Backends laufen lassen. nen Mysqlserver(RDBMS) mit nur einem Prozess als zugriff macht dann auch wenigers sinn, da waer ne reine File Lösung besser (wenns unbedingt sql sein muss: sqlite, wenn eigenes Protokoll geht, dann ne memory DB ala memcached oder berkley db oder sowas ... )
Und noch nen Tipp zu nem Fallstrick:
gibst du wegns eines tunnels "localhost" an, reagiert der client (er scannt auf die zeichenfolge) etwas ungewoehnlich. Er meint dass der server aufn Localhost auch im pipe modus lauft, und verucht sich dann ueber ne pipe zu verbinden, was ja bei nem tunnel nicht hasst -> geht nicht.
immer 127.0.0.1 als server angeben um das zu umgehen ...
Ciao ...
Moin Hustbaer,
Dann miss es mal.
Ich hatte das nur sehr locker gemssen. Suchzeit bei meinem Systen (jeweils 3 Fundstellen) 0.14 sec,
bei der gleichen Datenmenge mit SQLIte hatte der Apache nach einigen Minuten etwas von einem 500 gemunkelt ...
(Feld-Wald+Wiesen-PC, Win XP prof, 4 GB RAM, Dualcore, RAID1, Apache 2).
Interessante Ideen. Eigentlich logisch - ich muß das jetzt nur noch irgendwie mit der Praxis zusammenbringen.
Nach Deinen Ausführungen dürfte SQLite aber nicht dermaßen dramatisch einknicken.
Eigentlich sollten die Sektoren mit den SQLite-Pages auch hintereinanderliegen, die Datenbank wurde ja neu
aufgebaut. Inwieweit da Ergebnisse des Caching eingehen weiß ich nicht. Nur, je weniger Daten umso mehr
dürfte auch in den Cache passen. Die Chance, daß eine Datei mit 1 MB komplett im Cache liegt ist naturgemäß
höher wie bei einer großen Datenbank.
In der Firma läuft das auf schnellen PCs mit 10 Platten RAIDs, wir haben da auch ein 10 MBit Anbindung.
Bei unseren 130 Mio. Records wären das aufgerundet 6 IOs.
6 oder 27 I/Os dürften sich nicht so zwicken ...
Bei dem diskutierten System (es funktioniert da leicht anders), kenne ich die Datenmengen der einzelnen
vorkommenden Suchbegriffe - die habe ich mal in einzelne Dateien abgelegt (die größte wird 24 MB pro Jahr).
Die kann ich komplett in den Speicher laden, durchsuchen und habe dann sofort die Trefferliste. Von da
hole ich dann die Bestandsdaten.
Wobei es auch relativ einfach sein sollte einen B-Baum-artigen Index mit deinem sortierten Datenfile zu verbinden.
Beim Herumprobieren mit SQLite habe ich alle Daten (nicht nur die Suchbegriffe) in einer DB. NUR die
Suchbegriffe dort speichern müßte ich nochmal probieren ...
("Bestandsdaten" bedeutet hier: Den Rest der Angaben aus den Rechnungszeilen, nicht die PDF/XML).
Die Datenfiles sind "in order of einlesing", also unsortiert.
--
Suchbegriffe sind hier Kundennummer, Belegnummer, Artikelnummer (alle mit festen Längen).
Eingrenzungen durch Datum und Niederlassung sind möglich.
Bestandsdaten: Angaben wie Preise, Menge etc.
Ja, das ist wahrscheinlich gar nicht schlecht, wenn man mit extra Tabellen arbeitet.
Das meine ich, da muss es doch irgendwo etwas zu lesen geben.
Ich weiß nur nicht, wie ich suchen muss.
Oder gibt es da einfach nicht so viel zu beachten?
jenz
Die Frage hat erstmal nix mit SQL zu tun, denn als erstes wirst du wissen müssen wie du das "ähnliche Artikel suchen" implementieren willst.
Schlagworte abspeichern ist vermutlich eine gute Möglichkeit.
Wenn du dich dazu entschieden hast, musst du dir noch überlegen wie du nun anhand der Schlagworte die ähnlichen Artikel finden willst.
Erst wenn du das weisst, kannst du dir Gedanken darüber machen wie man das performant mit einer Datenbank umsetzen könnte.
Oder du baust das System mal mit Schlagworten, und bastelst die "Ähnliche Artikel finden" Funktion später dazu.
Dazu wirst du dann evtl. neue Spalten, Hilfstabellen und/oder Indexe brauchen, aber das sollte ja kein Problem darstellen.
Hi,
entweder bei order by nicht die Feldnamen, sondern die Spaltennummer angeben, also z.B. ... order by 3,5,2;
oder Du machst über die Abfrage noch eine Abfrage
z.B. select * from (select * from ... ) order by Feld...;
Gruß Mümmel
Gern geschehen.
Ich hatte das mit clock() ausgemessen. Ich hatte Suchzeiten von 70 sec bis
Start der Auslieferung über den Webserver, die sind auf 0.5 zusammengeschnurrt
(je nach SQL-Statement, ca 10 Mio Records).
In der Cachedatei habe ich das komplette HTML bis auf die Spaltenköpfe,
dh die Cachedatei lese ich mit read() und haue die mit fwrite() auf stdout.
Die Transferzeiten über den Webserver ändert es leider nicht.
Vorallem kommt es auf dein Tabellendesign an.
EIne Tabelle in der alle Daten stehen, welche 2 Mill rows hat, ist nicht so einfach zu durchsuchen wenn die Tabelle (Datei) sehr groß ist.
Durchsuche mal eine Datei mit mehreren 100 GB.
Weiters kommt es darauf an wieviele das gleichzeitig machen.
Was ist denn lange bei dir?
Manche sind foh wenn die Abfrage in 5 Sekunden fertig ist.
Für manche ist das sehr lange.
MySQL wurde nie für sowas gebaut.
Deshalb kann man auch bei den großen RDBMS (ORACLE, MSSQL) das ganze in mehrere Dateien zerlegen.
Hier gibt es noch viel mehr Hebel um anzusetzen und es zu beschleunigen. Das hat MySQL nicht.
Würde auf Tempo für kleine Tabellen im Web erfunden.
Hi,
gibt es unter MySql bereits (standardmäßig) defines für bestimmer Werte-Typen?
Ich meine zum Beispiel sowas wie:
TINYINT_MIN_VALUE = -128;
TINYINT_MAX_VALUE = 127;
Viele Dank!
Megusta schrieb:
Für gewöhnlich lege ich dann eine weitere Tabelle an die stets nur einen (oder keinen) Datensatz enthält, nämlich einen Fremdschlüssel auf den "selektierten" Datensatz der eigentlichen Tabelle.
Naja, einen pro Arbeitsstatuio/User/... hoffentlich.
Oder ist die Datenbank etwa lokal?
Das scheint mir keine saubere Lösung zu sein. Aber wie sollte man es besser realisieren?
Man könnte eine Tabelle für alle diese Einstellungen zusammen machen, mit Name + Value.
Man könnte die eigentliche Tabelle um eine Spalte "Selected" erweitern. In dieser Spalte sind stets alle Einträge bis auf einen genullt. Das ist wohl noch unsauberer.
Ja, das wäre grässlich.
Oder man speichert die ID des selektierten Datensatzes eben nicht in der Datenbank sondern in den Programmsettings (irgendeiner Datei). Auch nicht so das Wahre.
Finde ich nicht schlimm. Wo wäre das Problem?
Erst mal vielen Dank
Ich hab das so gemacht wie du das beschrieben hast.
DataSource1->DataSet = SQLQuery1;(im Quelltext)
Der Debugger macht folgende Fehlermeldung
DataSource1: Zirkuläre Datenverbindungen sind nicht erlaubt
und das DBGrid1->DataSource setzt du dann auf diese DataSource (am besten direkt im Object-Inspector).hab ich gemacht.
Vielleicht habt ihr ja ein Bespielprojekt wo es einen Button für die SQL Abfrage gibt. Wär schön wenn ihr mir es mailen könnt.
Ich guck auch mal im Internet, ob ich da was finde
Viele Grüße
Dirk
d_baule@yahoo.de
Ich grübel schon eine ganze Weile am Design einiger Datenbankabfrage und der Struktur der Resultsets herum.
Ausgangproblem ist in etwa Folgendes:
| ItemID |
|--------|
| 0 |
| Names |
|-------|
| foo |
| bar |
| Counts |
|--------|
| 0 |
| 1 |
| Cities |
|----------|
| Berlin |
| New York |
Names, Counts und Cities beziehen sich hier auf das Item mit der ID 0 und können beispielsweise Ergebnisse von Subqueries sein.
Das ganze soll in einem Resultset zurückgegeben werden. Der "klassische" Weg dürfte da ja ein Join über alle Tabellen sein, wobei in etwa das rauskommen sollte:
| ItemID | Names | Counts | Cities |
|--------+-------+--------+----------|
| 0 | foo | 0 | Berlin |
| 0 | foo | 0 | New York |
| 0 | bar | 0 | Berlin |
| 0 | bar | 0 | New York |
| 0 | foo | 1 | Berlin |
| 0 | foo | 1 | New York |
| 0 | bar | 1 | Berlin |
| 0 | bar | 1 | New York |
Problem hierbei: hohe Redundanz, dass sich die Kardinalitäten der einzelnen Tabellen aufmultiplizieren. Potentiell können die einzelnen Tabellen durchaus jeweils Dutzende wenn nicht gar Hunderte Werte enthalten. Die Anzahl der Spalten kann ebenfalls noch stark wachsen.
Ausserdem gibts noch das kleine Problem, dass die Tabellen Names, Counts, und Cities prinzipiell lehr sein können - ich also auch wieder mit Outer Joins arbeiten müssten und NULL Values auftreten können.
Eine alternative Lösung wäre ein Key-Value Ansatz, dessen Resultset in etwa wie folgt aussieht:
| ItemID | Key | StringValue | IntValue |
|--------+-------+-------------+----------|
| 0 | name | foo | NULL |
| 0 | name | bar | NULL |
| 0 | count | NULL | 0 |
| 0 | count | NULL | 1 |
| 0 | city | Berlin | NULL |
| 0 | city | New York | NULL |
Hier besteht nur noch Redundanz durch die mit NULL belegten Werte, allerdings ist die Anzahl der primitiven Datentypen letztendlich konstant.
Aber das ganze wirkt natürlich schon sehr unelegant und so ein Ansatz macht das Weiterverarbeiten des Resultsets auch ungleich schwieriger.
Mach IMHO nur Sinn, wenn es normal ist, dass man nur einen Teil der Daten benötigt, dann müllt der Blob nicht den Cache zu, falls die Datenbank minderbemittelt genug ist, das nicht selbst handeln zu können.
Wenn man den Blob eh immer mit lädt, wenn man den Rest der Daten selektiert, kann man den Blob auch gleich in derselben Tabelle wie den Rest der Daten lassen.