theunreal
Goto Top

Many2Many Relation füllen ohne Duplikate?

Hallo zusammen,

wer meine älteren Threads kennt, weiß sicher, das wir mit einer uralten Access Lösung mehr schlecht als Recht durchs Leben kommen.
Diese Zeiten sind nun vorbei und es kommt etwas gutes, neues.

Ich schreibe grad eine Schnittstelle zwischen das alte Access System und das neue auf PSQL. Da ich ja bereits etwas Erfahrung im Bereich Datenbanken habe, klappt das ganz gut - allerdings habe ich ein Problem, zu dem ich grad keine Lösung finde.

Ich habe eine Many2Many Relation, die ich füllen möchte - nennen wir diese hier einfach mal "Zubehör" und zerlegen Sie in 3 Bestandteile : tblZubehörOwner, tblM2MRelationZubehör,tblZubehörName.
Ziel ist es beim Aufruf id Zubehör Owner alle namen der zugehörigen Zubehör-id's anzuzeigen.

Ich übersetze nun in einer Abfrage die Spalten mit festen Ja/Nein Werte des alten Systems auf die ID´s der tblZubehörName nd hole mir die id des tblZubehörOwners gleich mit dazu.
Dann füge ich beide id's in die tblM2MZubehörRelation.... an. Soweit so gut aber: Mir fehlt jetzt der Anker um Duplikate auszuschließen. Denn in der M2M kann ja jede Seite beliebig oft vorkommen, aber eine explizite Kombination soll nicht beliebig of vorkommen (z.b. OwnerID = 1, ZubehörNameID = 1 darf nur 1x sein). Das schließt einen Index aus, auf IsNull zu prüfen geht auch nicht.

Wie kann ich das lösen, ausser alles zu löschen und einfach stumpf neu anzufügen? Wo setze ich meinen Anker?

Ich danke für alle hilfreichen Tipps!
Gruß Sascha

Content-ID: 2807984785

Url: https://administrator.de/contentid/2807984785

Ausgedruckt am: 22.11.2024 um 08:11 Uhr

Lochkartenstanzer
Lösung Lochkartenstanzer 17.05.2022 aktualisiert um 11:33:17 Uhr
Goto Top
Moin,

Mach einen hash über die relevanten Einträge und nimm den als Schlüssel.Nachdem da keine Kryptographische Sicherheit notwendig ist, kannst Du z.B. beide in 10-stellige Dezimal-Stringsmut führenden Nullen aufblasen und die konkatenieren.

lks
TheUnreal
TheUnreal 17.05.2022 um 11:44:55 Uhr
Goto Top
Hi,
das klingt super und wird ausprobiert.Im nachhinein auch logisch und konsequent, die Paarung zu indizieren^^.
Vielen Dank für den Schubs!
ukulele-7
ukulele-7 17.05.2022 um 12:07:07 Uhr
Goto Top
Das mit dem Index verstehe ich nicht, wieso sollte kein Index möglich sein?

Die einfachste Form, doppelte Beziehungen zu verhindern, ist ein zusammen gesetzter Primärschlüssel auf OwnerID,ZubehörNameID. Der arbeitet wie ein UNIQUE-Constraint. Das wird auch in der Datenbanklehre häufig so definiert. Einen eindeutigen Hash über die IDs ist ansich das selbe Prinzip, warum aber ein Hash ist mir nicht ganz klar. Jedenfalls gibt es viele Wege das zu erzwingen.

Um bestehende Dubletten zu finden genügt ein
SELECT ... GROUP BY OwnerID,ZubehörNameID HAVING count(*) > 1
Lochkartenstanzer
Lochkartenstanzer 17.05.2022 aktualisiert um 12:21:48 Uhr
Goto Top
Zitat von @ukulele-7:

Einen eindeutigen Hash über die IDs ist ansich das selbe Prinzip, warum aber ein Hash ist mir nicht ganz klar. Jedenfalls gibt es viele Wege das zu erzwingen.

Weil ich nicht aus der Datenbankecke, sondern aus der Kryptographie-Ecke komme und mir das daher als erstes eingefallen ist. face-smile

Aber Du hast Recht, ob man das nun Hash oder zusammengesetzten Schlüssel nennt, ist egal, weil es prinzipiell das gleiche ist.

lks
TheUnreal
TheUnreal 17.05.2022 um 13:05:01 Uhr
Goto Top
Zitat von @ukulele-7:

Das mit dem Index verstehe ich nicht, wieso sollte kein Index möglich sein?

Die einfachste Form, doppelte Beziehungen zu verhindern, ist ein zusammen gesetzter Primärschlüssel auf OwnerID,ZubehörNameID.

Der grundsätzliche Ansatz, die beiden IDs zu verknüpfen und damit eine vernünftige Unique ID zu bekommen kam mir nicht in den Sinn face-smile

Ja, das habe ich mir dann auch gedacht und ein neues Feld dafür angelegt.
akretschmer
akretschmer 17.05.2022 um 18:45:49 Uhr
Goto Top
Mit PSQL meinst Du PostgreSQL? Falls ja: Gratulation, beste Wahl.

Zu Deiner Frage: die 2 Spalten, die das als Foreign Key jeweils dienen, kannst Du direkt als PRIMARY KEY dieser Tabelle nutzen. Voll easy.
TheUnreal
TheUnreal 18.05.2022 um 08:45:48 Uhr
Goto Top
@akretschmer
Jupp, es handelt sich um Postgres. Da ich gerne dazu lerne, kannst du mir deine Aussage etwas näher erläutern, bitte?
akretschmer
akretschmer 18.05.2022 um 09:52:29 Uhr
Goto Top
postgres=# create table bla(id int primary key);
CREATE TABLE
postgres=# create table foo(id int primary key);
CREATE TABLE
postgres=# create table bla_foo(bla_id int references bla, foo_id int references foo, primary key(bla_id, foo_id));
CREATE TABLE
postgres=# 
TheUnreal
TheUnreal 18.05.2022 um 10:23:18 Uhr
Goto Top
Danke!