MySQL
Tom
- datenbank
0 MatzeA0 Sven Rautenberg0 fastix®
Hallo,
ich habe da eine Tabelle, in der werden Verkaufsartikel beschrieben. Allerdings hat nun jeder Verkaufsartikel andere Kenngrößen.
Milch:
Fettgehalt
Erzeugerangaben (Freitext)
Schraube:
DIN
Länge
Gewinde
Farbe
na und so weiter.
Die Kenngrößen für Schrauben werden daher in einer Tabelle für Schrauben udn die für Autos eben in einer für Autos geführt. Die Satzformate sind ja vollkommen unterscheidlich.
In der Tabelle Artikel steht nun die Warengruppe des Artikels drin. Die WG ist ein Schlüssel für die zugehörige Kenngrößen-Tabelle.
Wie kann ich jetzt ein SELECT aufbauen, das für jeden Datensatz die passenden Kenngrößen einschließt? Die zugehörige Tabelle erhalte ich ja erst aus dem Datensatz selbst.
Kann man solche Abfragen überhaupt in einer Anweisung aufbauen?
Wie könnte ich ggf. die Datenstruktur ändern, um das in einer Abfrage hinzubekommen?
Liebe Grüße
Tom
Servus,
so einfach geht dies meines wissens nicht.
Du kannst innerhalb eines SQL Statement nicht dyamisch Anhand des Egebnisses von einer Tabelle zu anderen springen.
Das musst Du wohl selber ermitteln (extern vom Select) und dann ein weiteres Select anstossen.
<sepkulativ und nicht garantiert>
Folgendes könnte helfen. Erzeuge einen View, der exakt über alle Tabellen geht. Der also alle Tabelle beinhaltet.
Dann kannst du Dein Select auf die 1. Tabelle und immer auf den View
reduzieren. Aber ich halte, selbst wenn es klappt, diese Lösung nicht für gut.
Performance der DB wird erheblich strapaziert.
</sepkulativ und nicht garantiert>
Ich persitiere meine Daten anderster und zwar über EJB <-- Java
Somit mache ich mir nicht mehr den grossen Kopf darüber, was in der DB passiert.
Gruss Matze
Moin!
Milch:
Fettgehalt
Erzeugerangaben (Freitext)Schraube:
DIN
Länge
Gewinde
FarbeDie Kenngrößen für Schrauben werden daher in einer Tabelle für Schrauben udn die für Autos eben in einer für Autos geführt. Die Satzformate sind ja vollkommen unterscheidlich.
Mit anderen Worten: Du hast derzeit eine Tabelle mit den Artikeln, und je Artikelgruppe (Schrauben, Milch, Kekse, Autos) dann eine Tabelle, in der einzelne Spalten enthalten sind, welche die angebbaren Eigenschaften des Artikels beschreiben.
Ungünstiges DB-Design, würde ich mal sagen. Jedenfalls vom Standpunkt der Normalisierung aus gesehen.
Zunächst mal die Frage: Warum brauchst du für die einzelnen Artikel derartig unterschiedliche Eigenschaften? Ließen sich die Eigenschaften nicht in ein gemeinsames Schema pressen, welches dann für alle Artikel paßt? Im Zweifelsfall kommen also Gewicht/Volumen, Farbe, Abmessungen und Hersteller in eine Tabelle, und Zusatzangaben in ein Textfeld.
Oder du legst insgesamt drei Tabellen an, die flexibel zusammengesetzt werden:
1. Der Artikel an sich (mit einer Artikel-ID).
2. Eine Tabelle mit Eigenschaften und Eigenschafts-ID: Menge, Farbe, Gewinde, Fettgehalt, ...
3. Eine Tabelle, die aus drei Spalten besteht: Artikel-ID, Eigenschafts-ID, und Wert.
Damit kannst du dann alle Eigenschaften aller Artikel in genau einer Tabelle verwalten. Die Suche nach Eigenschaften gestaltet sich dann auch recht einfach. Wenn du beispielsweise alle Artikel mit Gewindemaß suchst, findest du die Eigenschafts-ID durch Benutzerangabe heraus, suchst dann alle Artikel-IDs in der Wertetabelle und verknüpfst dann die Artikel-Tabelle damit - und ggf. dann nochmal die Wertetabelle, um alle Angaben zum Artikel zu erhalten.
Die Pflege solche einer Tabelle ist wahrscheinlich etwas aufwendiger, aber auch wesentlich dynamischer. Denn wenn du neue Eigenschaften für bislang unbekannte Artikel hinzufügen willst, kommen die einfach in die Eigenschaftstabelle hinein und können dann sofort einem Artikel zugeordnet werden.
Und du kannst, um die Eigenschaften je nach Warengruppe einzuschränken, bzw. zuzuordnen, dann noch eine vierte Tabelle eröffnen, die Einträge hat in der Form "Warengruppe-ID <-> Eigenschafts-ID", damit gewisse Eigenschaften bei einer Warengruppe auftauchen, und der ganze Rest nicht (beispielsweise ist das verwendete Getriebeöl bei Food-Produkten eher uninteressant).
Wie kann ich jetzt ein SELECT aufbauen, das für jeden Datensatz die passenden Kenngrößen einschließt? Die zugehörige Tabelle erhalte ich ja erst aus dem Datensatz selbst.
Kann man solche Abfragen überhaupt in einer Anweisung aufbauen?
Schwierig. Deine einzige Chance wäre, dass du immer _alle_ Tabellen joinst. Das würde aber ziemlich aufwendig werden, was die Datenbankarbeit angeht. Und es würde dir ein heftig langes Ergebnis liefern, denn die entstehende Tabelle würde alle möglichen vorhandenen Eigenschaften auflisten, die meisten davon NULL.
Wie könnte ich ggf. die Datenstruktur ändern, um das in einer Abfrage hinzubekommen?
Mit der Aufsplittung wie oben beschrieben hast du mit Sicherheit mehr Erfolg. Allerdings gebe ich darauf keine Garantie, ich bin kein gelernter Datenbankmensch. Vielleicht gibts noch eine zweite Meinung in diesem Forum.
- Sven Rautenberg
Hallo Sven,
Mit anderen Worten: Du hast derzeit eine Tabelle mit den Artikeln, und je Artikelgruppe (Schrauben, Milch, Kekse, Autos) dann eine Tabelle, in der einzelne Spalten enthalten sind, welche die angebbaren Eigenschaften des Artikels beschreiben.
Ungünstiges DB-Design, würde ich mal sagen. Jedenfalls vom Standpunkt der Normalisierung aus gesehen.
Ja, darum suche ich ja eine andere Lösung. Die obige existiert zum Glück erst auf dem Papier.
Zunächst mal die Frage: Warum brauchst du für die einzelnen Artikel derartig unterschiedliche Eigenschaften? Ließen sich die Eigenschaften nicht in ein gemeinsames Schema pressen, welches dann für alle Artikel paßt? Im Zweifelsfall kommen also Gewicht/Volumen, Farbe, Abmessungen und Hersteller in eine Tabelle, und Zusatzangaben in ein Textfeld.
Das ist ungünstig, da nach den Eigenschaften auch gesucht werden soll und auch Artikel innerhalb ihrer Gruppe unterschiedlich viele Eigenschaften des glechen Typs haben können. So habe ich es bisher gemacht und das Ganze exploiert bald im Pflegeaufwand.
Oder du legst insgesamt drei Tabellen an, die flexibel zusammengesetzt werden:
- Der Artikel an sich (mit einer Artikel-ID).
- Eine Tabelle mit Eigenschaften und Eigenschafts-ID: Menge, Farbe, Gewinde, Fettgehalt, ...
- Eine Tabelle, die aus drei Spalten besteht: Artikel-ID, Eigenschafts-ID, und Wert.
Damit kannst du dann alle Eigenschaften aller Artikel in genau einer Tabelle verwalten. Die Suche nach Eigenschaften gestaltet sich dann auch recht einfach. Wenn du beispielsweise alle Artikel mit Gewindemaß suchst, findest du die Eigenschafts-ID durch Benutzerangabe heraus, suchst dann alle Artikel-IDs in der Wertetabelle und verknüpfst dann die Artikel-Tabelle damit - und ggf. dann nochmal die Wertetabelle, um alle Angaben zum Artikel zu erhalten.
Ja, das hört sich sehr gut an. Ich habe schon darüber nachgedacht, pro _Datentyp_ eine Tabelle anzulegen und die in den Join mit einzubeziehen. Dann wären auch die Probleme mit Rechnen(Zahlen), Datum, Blobs, Links, etc. verschwunden
Wobei man dann wahrscheinlich genau nach dem Verarbeitungstyp und dem Anzeigetyp einer Eigenschaft unterscheiden muss. Ein Link ist ja nur ein Text, wird eben nur anders angezeigt, als eine normale Zeichenfolge und beinhaltet eine Event-Funktion.
Zahlen sollen rechtsbündig (bzw. dezimalbündig) gezeigt werden, man soll damit rechnen können (habe noch nie probiert, ob bei MySQL SUM auch über Textfelder funktioniert)
na usw.
Die Pflege solche einer Tabelle ist wahrscheinlich etwas aufwendiger, aber auch wesentlich dynamischer. Denn wenn du neue Eigenschaften für bislang unbekannte Artikel hinzufügen willst, kommen die einfach in die Eigenschaftstabelle hinein und können dann sofort einem Artikel zugeordnet werden.
Ja, und wenn das Datentypproblem nicht wäre, dann könnte man auch den Artikel mit _einer_ Abfrage über alle Eigenschaften aufbauen.
Und du kannst, um die Eigenschaften je nach Warengruppe einzuschränken, bzw. zuzuordnen, dann noch eine vierte Tabelle eröffnen, die Einträge hat in der Form "Warengruppe-ID <-> Eigenschafts-ID", damit gewisse Eigenschaften bei einer Warengruppe auftauchen, und der ganze Rest nicht (beispielsweise ist das verwendete Getriebeöl bei Food-Produkten eher uninteressant).
Ja, das wäre dann die Klassendefinitionstabelle für die Warengruppen, in der auch die Anzeigefunktionen, die Validierungsfunktionen usw. für die Eigensschaften stehen. Sowas ähnliches habe ich bisher schon. Funktioniert sogar _sehr_ gut.
Vielleicht gibts noch eine zweite Meinung in diesem Forum.
Das sollte mich freuen. Bisher habe ich aber tiefgründigere "Denkschriften" fast nur von Dir erhalten. Die haben dann aber so nach und nach immer zum Erfolg geführt.
Schaun wir also mal.
Grüße aus dem mittleren Norden
Tom
Hallo Sven,
»»»»habe noch nie probiert, ob bei MySQL SUM auch über Textfelder funktioniert)
Habe ich gerade mal nachgeholt. MySQL scheint dann die Asci-Werte der Zeichen zu addieren. Kommt jedenfalls ne ziemlich merkwürdig große Zahl dabei heraus.
Grüße
Tom
Servus,
also ich abstrahiere jetzt gaaaaaaaanz schlimm.
Mache eine Tabelle
PRODUKT_EIGENSCHAFT_ZUORDNUNG
Zwei Spalten PRODUKT_ID und EIGENSCHAFT_ID
jeweils mit einem FK auf Tabelle
PRODUKT
(PRODUKT_ID, PRODUKT_NAME)
und
EIGENSCHAFT
(EIGENSCHAFT_ID, EIGENSCHAFT_PROP_ID)
<-- Besonderheit der Eigenschaft_ID n * m Beziehung
EIGENSCHAFT_PROP
(EIGENSCHAFT_PROP_ID, Eigenschaft, Wert)
Ich hoffe das Design hast Du verstanden.
Ist zwar nicht die allerbeste Lösung dürfte Dir aber bis zum Sankt nimmerleins Tag eine individuelle Zuronung von Eigenschaften zu Produkten ermöglichen.
Herje mach aber noch eine _Tabelle, wo Du alle Eigenschaften Verwaltest.
PROPIERTIE_INFO
(Propertie_ID, Propertie_NAME, PROPERTIE_TYPE, PRODUKT_ID)
Somit kannst Du hierdurch die Gui steuern und unterschiedlichen Produkten bestimmte Properties zurodnen.
Ich hoffe du hast die Logik verstanden und kannst das nun für Dich ändern.
Gruss Matze
Moin!
"Beim Stuff für's Web gibts kein Material, was sonst das Zeugs ist, aus dem die Sachen sind."
(fastix®, 13. Oktober 2003, 02:26 Uhr -> </archiv/2003/10/60137/#m338340>)
Hehe... ich werde schon zitiert :) Aber das Wortspiel hat mich seinerzeit ziemlich gereizt. Ich bin mir aber immer noch nicht sicher, ob's denn verstanden wird. Interessant ist die Übersetzung von "stuff"... :)
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix®
Moin!
"Beim Stuff für's Web gibts kein Material, was sonst das Zeugs ist, aus dem die Sachen sind."
(fastix®, 13. Oktober 2003, 02:26 Uhr -> </archiv/2003/10/60137/#m338340>)Hehe... ich werde schon zitiert :) Aber das Wortspiel hat mich seinerzeit ziemlich gereizt. Ich bin mir aber immer noch nicht sicher, ob's denn verstanden wird. Interessant ist die Übersetzung von "stuff"... :)
Ja, du hättest den Satz auch einfacher formulieren können. Ich habe in der Tat etwas Zeit benötigt, um zu verstehen, was gemeint ist. Sehr "verklausuliert". :)
Hm, wenn man zitiert wird, hat man "es" dann "geschafft"? :)
- Sven Rautenberg
Moin!
Hm, wenn man zitiert wird, hat man "es" dann "geschafft"? :)
Ja, irgendwie schon. Fragt sich nur wohin.
Mein Lieblingszitat ist von Lutz Donnerhacke: "Rechner sind Highspeedidioten. Sehr schnell, aber auch sehr dumm."
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix®
Hi,
"Beim Stuff für's Web gibts kein Material, was sonst das Zeugs ist, aus dem die Sachen sind."
(fastix®, 13. Oktober 2003, 02:26 Uhr -> </archiv/2003/10/60137/#m338340>)Hehe... ich werde schon zitiert :) Aber das Wortspiel hat mich seinerzeit ziemlich gereizt. Ich bin mir aber immer noch nicht sicher, ob's denn verstanden wird. Interessant ist die Übersetzung von "stuff"... :)
Ja, du hättest den Satz auch einfacher formulieren können. Ich habe in der Tat etwas Zeit benötigt, um zu verstehen, was gemeint ist. Sehr "verklausuliert". :)
Wahrscheinlich stammt von fastix® auch der Text dieses ominösen Patentes, dass die Buchstabenkombination von KFZ-Kennzeichen als Teilstring einer URL schützen sollte *ggg*
.de wäre dann ja Dessau oder Delmenhorst oder sowas?
Tom
Moin!
Wahrscheinlich stammt von fastix® auch der Text dieses ominösen Patentes, dass die Buchstabenkombination von KFZ-Kennzeichen als Teilstring einer URL schützen sollte *ggg*
Nö. Der nicht. Aber der hier: </archiv/2003/10/60681/#m341895>
Das Fenster ist mein!
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix®
Moin!
Also... ich würde so aufbauen:
table artikel:
| art_id | art_name | type_id | value_1 | value_2 | value_3 | .... | Freitext |
table_types:
| type_id | type_name | value_1_name | value_1_einheit | value_2_name | value_2_einheit | ... |
Du musst beim Abfragen jetzt einen Join machen, der die Spaltennamen und Einheiten der reinen Maßzahlen aus table_types feststellt. Vorteil davon ist, daß Du jetzt alle Formulare und Ausgaben auch dynamisch erzeugen kannst: Bei Schrauben wird eben nur nach dem Gewinde,Länge und Festigkeit gefragt/angezeigt, bei Milch nach Packungsgröße, Fettgehalt etc.
Ebenso ist es recht einfach einen neuen Artikeltyp mit seinen Eigenschaften anzulegen.
Eine Kleinigkeit: Du musst die Spalten so anlegen, daß diese auch durchsuchbar sind und das man MySQL mit ihnen rechnen kann. Also dezimal mit der maximal benötigten Anzahl an Kommastellen.
Dafür ist dann aber auch möglich effektive Indizees zu erstellen. Das ist für die Durchsuchbarkeit unter Umständen wichtig. Wenn Du dann noch ein Regelwerk hast, welches sicherstellt, daß bei Muttern und Schrauben das Material und das Gewinde an der selben Stelle (value_X) stehen, dann kannst Du sogar effektiv danach suchen.
Variante 2:
Du kannst natürlich auch _ein_ Feld für Daten bestimmen, in dem dann sowas auftaucht:
DIN=125677;Laenge=25;Gewinde=6;Gewindetyp=metric;Farbe=schwarz
Das müsstest Du dann in einem Programm außerhalb von MySQL "fetchen"
Vorteil: scheinbar einfacher.
Nachteil: keine dynamischen Formulare möglich (bei Neueinträgen in die DB) verbraucht unnötig Speicher....
Ach ja... womöglich gibt's noch mehr Ideen, die auch alle richtig sein können. Das hängt immer von Zweck und Ziel ab.
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix®
Moin!
table artikel:
| art_id | art_name | type_id | value_1 | value_2 | value_3 | .... | Freitext |
table_types:
| type_id | type_name | value_1_name | value_1_einheit | value_2_name | value_2_einheit | ... |
Das Problem ist, dass du damit die Menge der Eigenschaften künstlich begrenzt. Du kannst natürlich beliebig viele Values einfügen, aber irgendwann bei 1000 dürfte schon aus Praktikabilitätsgründen Schluß sein. Insbesondere, wenn nur ein Produkt so viele Eigenschaften hat, die anderen aber alle so bei 5 bis 10 liegen.
Außerdem verstößt dein Design gegen die Normalform: Mehrere gleichartige Attribute gehören nicht nebeneinander in eine Tabelle, sondern in eine eigene Tabelle.
Eine Kleinigkeit: Du musst die Spalten so anlegen, daß diese auch durchsuchbar sind und das man MySQL mit ihnen rechnen kann. Also dezimal mit der maximal benötigten Anzahl an Kommastellen.
Das Problem ist: Wenn bei Artikeltyp 1 das Gewicht an Platz 1 steht, und bei Typ 2 an Platz 5, wirst du niemals die Summe der Gewichte mit SUM() und GROUP BY errechnen können.
Ok, du wirst einwenden, dass man dann die Spalte 1 fest fürs Gewicht nehmen kann. Was aber, wenn Produkte kein Gewicht haben oder brauchen. Spalte unbenutzt leerlassen? Oder wiederverwenden für andere Eigenschaften? Und wenn Typ 3 jetzt sowohl Gewicht als auch diese andere Eigenschaft hat, die dann beide in Spalte 1 stehen müßten - schon wieder ein nicht auflösbarer Konflikt.
Dafür ist dann aber auch möglich effektive Indizees zu erstellen. Das ist für die Durchsuchbarkeit unter Umständen wichtig. Wenn Du dann noch ein Regelwerk hast, welches sicherstellt, daß bei Muttern und Schrauben das Material und das Gewinde an der selben Stelle (value_X) stehen, dann kannst Du sogar effektiv danach suchen.
Die Aufstellung dieses Regelwerks wird den allergrößten Aufwand verschlingen, weil es hierbeit unter Umständen zu nicht auflösbaren Konflikten kommen kann, wenn jede Spalte flexibel nutzbar sein soll.
Wenn hingegen die Spaltennutzung festgelegt ist (Spalte 1: Gewicht,...), dann benötigt man zur Beschreibung von 1000 verschiedenen Eigenschaften, die nicht alle genutzt werden, 1000 Spalten.
- Sven Rautenberg
Moin!
Hm... ja. Ich hab ja auch vorsorglich geschrieben, daß es in Abhängigkeit vom Zweck andere richtige Lösungen geben wird.
Ein Nachtrag zu meiner Lösung [2].
Es gibt den Spaltentyp "SET". http://www.mysql.com/doc/en/SET.html
Der erscheint mir auch recht interessant, macht es aber auch nicht gerade einfach. Immerhin müssten dann noch in einer weiteren Tabelle die Bezeichnungen und Maßeinheiten für die Artikelgruppen gehalten werden.
Aber scheinbar kann mit diesem zumidest selektiert und gerechnet werden. Ich zweifle aber an der Effiziens. Das Suchen darin dürfte "ewig" dauern, weil's halt eine Volltextsuche wird. Es spart aber das Anlegen und Verwalten einer Tabelle für jede Artikelgruppe- was ohne Zweifel jedoch die effektivste Methode für die Verwaltung wäre.
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix®
Hallöle,
Es gibt den Spaltentyp "SET". http://www.mysql.com/doc/en/SET.html
Beim Datentyp SET (als Untertyp von String) lässt sich leider später nur schwer eine Designänderung an diesem Feld durchführen. Das Verändern des SETs führ tin der Regel zur Löschung aller Daten der Spalte.
SET ist auf 16 unterschiedliche Werte begrenzt
ENUM ist auf 65536 unterschiedliche Werte begrenzt
Außerdem hat SET einen eigenbauten Fehler:
Wenn bei der Suche der Index des Feldes nicht gefunden wird, wird der Wert zugrundegelegt (oder war es umgekehrt?) Jedenfalls ist das sehr gefährlich.
Grüße
Tom
Moin!
Es gibt den Spaltentyp "SET".
leider später nur schwer eine Designänderung an diesem Feld durchführen....
SET ist auf 16 unterschiedliche Werte begrenzt...
Außerdem hat SET einen eigenbauten Fehler:...
Ich sehe, dies ist für Deinen Zweck nicht ggeignet. Nimm also eine der anderen angesprochenen Möglichkeiten.
MFFG (Mit freundlich- friedfertigem Grinsen)
fastix®
Selber moin,
Ich sehe, dies ist für Deinen Zweck nicht ggeignet. Nimm also eine der anderen angesprochenen Möglichkeiten.
Jau, das werde ich wohl müssen. Das einzige Problem sind ja die verscheidenen Datentypen. Das bedeutet, dass ich für jeden Datentyp der Datenvorhaltung (also nicht die Art der Anzeige) eine eigene Tabelle halten muss.
Die Sache wird also nur mittels n:m auflösbar sein und in zwei (oder sogar drei) SQL-Statements.
Also erst die Kopfdatensätze lesen
Dann alle n:m Beziehungen einlesen (Das sind nämlich die Zeiger auf die Dateiltabellen)
und nun für jede Zeile aus der N:M-Abfrage eine neue Abfrage auf die Joins der Tabellen machen.
Was Anderes fällt mir einfach nicht ein.
Irgendwie bin ich wohl dem PISA-Virus zum Opfer gefallen :-((
Grüße
Tom