Zur Startseite Eine Frage die immer mal wieder auftaucht:
Ich habe eine Tabelle mit Artikeln. Jeder Artikel gehört zu einer Warengruppe. Es kann allerdings vorkommen, dass ein Artikel zu mehr als einer Warengruppe gehört. Wie sollte mein Tabellen-Design aussehen, um beispielsweise später eine Abfrage nach eine besonderen Sortierung innerhalb der Warengruppe durchzuführen?
Anmerkung Die hier vorgestellten Tabellen-Definitionen und INSERT-Anweisungen sollen lediglich das Prinzip eine m:n Beziehung verdeutlichen. Einige der Tabellendefinitionen und auch die INSERT-Anweisungen würde man in einer endgültigen Anwendung anders verwenden. Sie dienen hier nur dazu, schnell einige Beispiel-Tabellen und Daten zu erzeugen, damit das Verfahren anschaulich erläutert werden kann. In meinen Online-Kursen wird selbstverständlich genauer auf Einzelheiten bei CREATE und INSERT eingegangen.
Die Artikel-Tabelle:
CREATE TABLE test_artikel ( id int(11) NOT NULL auto_increment, artnr char(10) NOT NULL, name varchar(80) NOT NULL, preis decimal(8,2) NOT NULL, PRIMARY KEY (id) ) TYPE=MyISAM;
In die Tabelle werden einige Test-Artikel eingefügt:
INSERT INTO test_artikel VALUES(1, 'A001', 'Kugelschreiber', 2.40); INSERT INTO test_artikel VALUES(2, 'A002', 'Kopierpapier', 3.99); INSERT INTO test_artikel VALUES(3, 'D001', 'Computerdrucker', 399.00); INSERT INTO test_artikel VALUES(4, 'K001', 'Kleinkopierer', 499.00); INSERT INTO test_artikel VALUES(5, 'C001', 'Kleincomputer', 799.00);
Das sollte bis hierhin unproblematisch sein. Für den einzelnen Artikel können natürlich noch weitere Felder mit Einzeldaten zum Artikel (z.B. Gewicht) hinzugefügt werden.
Advertisement/WerbungCREATE TABLE test_warengruppen ( warengruppe_id int(11) unsigned NOT NULL auto_increment, bezeichnung varchar(80) NOT NULL, sortierung int(11) unsigned NOT NULL, PRIMARY KEY (warengruppe_id) ) TYPE=MyISAM;
Auch hier sollten einige Warengruppen als Beispiel eingefügt werden. Für die Sortierung kann ein Nummernkreis im Hunderter- oder Tausender-Bereich gewählt werden, um später bequem weitere Warengruppen in die Sortierung einfügen zu können.
INSERT INTO test_warengruppen VALUES(1, 'Schreibwaren', 100); INSERT INTO test_warengruppen VALUES(2, 'Papier', 110); INSERT INTO test_warengruppen VALUES(3, 'Kugelschreiber', 120); INSERT INTO test_warengruppen VALUES(4, 'Elektroartikel', 200); INSERT INTO test_warengruppen VALUES(5, 'Drucker', 210); INSERT INTO test_warengruppen VALUES(6, 'Kopierer', 220); INSERT INTO test_warengruppen VALUES(7, 'Computer', 230);
Damit sind die beiden wesentlichen Tabellen vorhanden. Nun fehlt eigentlich nur noch die Zuordnung zwischen beiden Tabellen. Weil ein Artikel auch zu mehr als einer Warengruppe gehören kann, wird die Warengruppe nicht direkt beim Artikel gespeichert. Um die Abfrage später flexibler zu halten, wird hierfür eine Extra-Tabelle verwendet:
CREATE TABLE test_artikel_warengruppen ( artikel_id int(11) unsigned NOT NULL, warengruppe_id int(11) unsigned NOT NULL, index (artikel_id) ) TYPE=MyISAM;
Auch hier sollen nun die Artikel den Warengruppen zugeordnet werden. Dabei wird ein Artikel mindestens zwei Warengruppen zugeordnet (z.B. Der Kugelschreiber zu "Schreibwaren" und "Kugelschreiber").
INSERT INTO test_artikel_warengruppen VALUES(1, 1); INSERT INTO test_artikel_warengruppen VALUES(1, 3); INSERT INTO test_artikel_warengruppen VALUES(1, 6); INSERT INTO test_artikel_warengruppen VALUES(2, 2); INSERT INTO test_artikel_warengruppen VALUES(2, 1); INSERT INTO test_artikel_warengruppen VALUES(3, 4); INSERT INTO test_artikel_warengruppen VALUES(3, 5); INSERT INTO test_artikel_warengruppen VALUES(4, 4); INSERT INTO test_artikel_warengruppen VALUES(4, 7); INSERT INTO test_artikel_warengruppen VALUES(5, 4); INSERT INTO test_artikel_warengruppen VALUES(5, 6);
Um nun eine sinnvolle Abfrage zu erzeugen, müssen diese drei Tabellen über ihre jeweiligen Schlüsselfelder miteinander verbunden werden:
select * from test_artikel art, test_artikel_warengruppen ref, test_warengruppen wg where ref.artikel_id=art.id and wg.warengruppe_id=ref.warengruppe_id order by sortierung
Dabei werden alle Artikel zusammen mit der zugeordneten Warengruppe ausgegeben und nach dem Feld "sortierung" sortiert.
Die Sortierung kann bei dieser Abfrage nach jedem Feld in der Tabelle erfolgen. Es könnte der Artikel nach Artikelnummer, Artikelbezeichnung oder die Warengruppe nach Bezeichnung sortiert werden. Hier soll die Liste nach der Gewichtung der Warengruppen erfolgen, wobei die Warengruppe mit der kleinsten Zahl in "sortierung" zuerst erscheint.
Falls nicht alle Warengruppen zugeordnet wurden, kann die Abfrage auch mit einem LEFT JOIN erfolgen, um festzustellen, welche Artikel noch einer Warengruppe zugeteilt werden müssen.
select * from test_artikel art left join test_artikel_warengruppen ref on ref.artikel_id=art.id left join test_warengruppen wg on wg.warengruppe_id=ref.warengruppe_id order by sortierung
Hinweis: Diesen Text und die enthaltenen Beispielprogramme und Skripte dürfen Sie zum Erlernen der einzelnen Techniken und auch als Grundlage für Ihre eigenen Projekte auf eigene Gefahr kostenlos nutzen.
Bitte denken Sie daran, dass alle Texte und Quellcodes trotzdem urheberrechtlich geschützt sind. Eine direkte Weitergabe ist nur nach ausdrücklicher schriftlicher Genehmigung gestattet.