• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

mySQL Doppeleinträge verhindern in beziehungstabelle Unique key

Diskordier

Neu angemeldet

Registriert
14 Juli 2013
Beiträge
161
Hallo leute ich hab eine Tabelle mit zwei Feldern darin sind IDs gespeichert

mit Unique key über zwei Tabellen kann ich einstellen das keine doppelten Einträge erstellt werden .

1 3
3 4
1 5
2 3
1 3 <- wird nicht gemacht da doppelt
3 1 <- das wird gemacht , soll aber nicht weil der Bezug symmetrisch ist :buh:

Wie kann ich das verhindern?

Danke für HIlfe.
 

Timon3

Team ModMii

Registriert
17 Juli 2013
Beiträge
499
Auch wenn ich dir bei deinem direkten Problem nicht weiterhelfen kann, klingt das erstmal so, als wäre deine Datenbankstruktur nicht ideal aufgebaut. Kannst du deine Situation genauer beschreiben?
 

KingJamez

Aktiver NGBler

Registriert
18 Juli 2013
Beiträge
502
Dein Pivot-Table sollte strukturiert sein, es sollte also eigentlich nicht passieren das du mal einen eintrag in die erste und mal in die 2te spalte schreibst.
Sollte es doch passieren, ist der Aufbau deiner Datenbank nicht wirklich logisch. Abhilfe könntest du schaffen indem du vor dem schreiben der Daten auf den eintrag prüfst.

[src=mysql]
SELECT * FROM table WHERE xx = 3 LIMIT 1
[/src]
erhältst du ein Ergebnis, darf nichts eingetragen werden
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
Hm, würde es nicht schon helfen das man die beiden Zahlen "sortiert" ? - Also das immer der kleine Nenner links und der größere rechts steht in der Abfrage/Eintrag? :)

So wäre immer sichergestellt das immer die gleiche Aufteilung vorhanden ist, sogar ohne auf den Wert erneut zu prüfen. Nein? Und man kann ohne schlechtes Gewissen einen Insert machen der dann nichts mehr bewirkt, weil herausgefiltert/ignoriert.
 

virtus

Gehasst

Registriert
24 Apr. 2015
Beiträge
1.689
Ort
AUF DEM MOND
Wie kann ich das verhindern?

Ich bin mir nicht sicher, wie dein Datenbankdesign allgemein aussieht, vielleicht ließe sich das durch Design-Anpassungen vermeiden.
Falls nicht, würde ich hier eher auf die Anwendungsebene wechseln.

Statt die ID's so einzutragen, wie sie rein kommen, sollte deine Anwendung eine "Normalisierung" durchführen.
Simpler Algorithmus:

[src=python]# normalizes
def normalize(ids):
io_ids = ids.copy()
io_ids.sort()
return io_ids


# incoming id's in what ever order
ids_ooo = [3, 2]
ids_io = normalize(ids_ooo)

# work with the ids
print(ids_io)[/src]

Funktionsweise: Du steckst die IDs in beliebiger Reihenfolge rein und bekommst sie "normalisiert" heraus.
Dazu legen wir zunächst eine Kopie der ursprünglichen Liste an. Ob das nötig ist oder du auf der originalen Liste arbeiten kannst, hängt von deinem konkreten Einsatzzweck ab. Die IDs werden in aufsteigender Reihenfolge zurück gegeben.

Grundlegende Idee:
Wenn du zwei IDs normalisierst, (besser gesagt deren Reihenfolge) landet folglich immer die kleinere ID an Position 1 und die größere an Position 2.
Wenn du nun also ganz allgemein zwei Tupel von IDs hast, so dass: (x, y), (y, x)
dann ist die Repräsentation innerhalb der Datenbank für beide Tupel identisch und in der Datenbank würde durch deine Anforderung der Eindeutigkeit kein doppelter Eintrag entstehen..



Nachtrag:
Wenn nicht klar ist, ob deine Anwendung sich stets an die Konvention hält, dann kannst du natürlich auch deine Datenbank diese Anforderung erfüllen lassen:

INSERT:
[src=mysql]VALUES (LEAST(15, 10), GREATEST(10, 15))[/src]

SELECT:
[src=mysql]WHERE `first` = LEAST(2, 1) AND `second` = GREATEST(1, 2)[/src]

Wenn die Queries aus einer Anwendung kommen, kannst du das auch mit Views und Triggern(?!) entsprechend "verstecken".
 
Zuletzt bearbeitet:

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
@virtus: Eine If Abfrage in PHP ob die ID 1 oder 2 größer ist als 2 oder 1, reichen doch auch schon aus dann Und dann wird nur der Query richtig "eingestellt" bzw. der "korrekte" verwendet. ;)

Zur Not helfen zwei Ternary Vergleiche in einer Zeile, wenn "x < y ? x : y".... nicht unbedingt schön, aber auch richtig, wobei mir noch ein Logikhändling fehlen würde, ob die IDs gleich sind - warum auch immer ;)
 
Zuletzt bearbeitet:

virtus

Gehasst

Registriert
24 Apr. 2015
Beiträge
1.689
Ort
AUF DEM MOND
@theSplit:
Welche Programmiersprache er einsetzt, ist letztlich vollkommen egal. Selbstverständlich kann er auch PHP verwenden.

Warum ich im Beispiel hier keine "einfache" if-Abfrage genutzt habe:
(1) Wie die Normalisierung funktioniert (Position 1: kleinerer Wert, Position 2: größerer Wert) ist eine grundsätzliche Design-Entscheidung. Der Hintergedanke ist, dass du dieses Schema an einer Position im Code festlegst und an allen Stellen, an denen du Normalisierung brauchst, keinen Gedanken mehr daran verschwenden musst, wie genau normalisiert wird, sondern nur noch festlegen musst, dass Normalisierung angewendet wird.
Um es anschaulicher auszudrücken: Stell dir vor du hast mehrere Entwickler. Würdest du an jeder Stelle "in place" die Normalisierung definieren, müssten sich alle Entwickler untereinander abstimmen und an wirklich jeder Stelle genau das Normalisierungsschema umsetzen. Das erfordert zum Einen einen höheren Koordinationsaufwand und ist natürlich auch deutlich Fehleranfälliger, sowohl durch Absprachefehler (Person A ordnet aufsteigend, Person B absteigend), als auch durch Implementierungsfehler. Klar, hier handelt es sich "nur" um zwei Zahlen, die geordnet werden sollen. Bei der Normalisierung von Alpha-Nummerischen Zeichenketten kann es schon schwerer werden:
"Hans Peter", "hans peter", "Hans peter", "hansPeter", "hans_peter", "hans-peter" ...

(2) Stell dir vor die IDs werden irgendwann komplexer, so wie ich das mit dem Namen bereits angedeutet habe. Dann willst du nicht an jeder Stelle im Code die Normalisierung anpassen. Selbst dann nicht, wenn du bei der Entwicklung peinlich genau geachtet hast, dass du Suchen-Ersetzen nutzen kannst.

--- [2017-05-25 00:46 CEST] Automatisch zusammengeführter Beitrag ---

Zur Not helfen zwei Ternary Vergleiche in einer Zeile, wenn "x < y ? x : y".... nicht unbedingt schön, aber auch richtig, wobei mir noch ein Logikhändling fehlen würde, ob die IDs gleich sind - warum auch immer ;)

Gleiche IDs müssen nicht unbedingt eine Verletzung der Anwendungslogik sein. Hierbei wäre eine "Neuanordnung" egal:
(x, x) kannst du beliebig "tauschen" und es wird (x, x) rauskommen. ;)
 

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
Okay, du hast Recht, ich fands unter anderem nur lustig das du den gleichen Gedankengang wie ich genommen hast... ich wollte es auch zuerst "normalisieren" nennen, bin aber davon abgewichen....

Das man durch eine Funktion die eine eindeutiges Ergebnis produziert, Code "wartbarer" macht, ergibt für mich allerdings auch Sinn, sollte es an mehreren Stellen gebraucht werden. Da gebe ich dir Recht. Hab ich so davor auch nicht gesehen - ist aber mehr als Nachvollziehbar.

Spätestens wenn man nach Zuordnung sucht, wird man die Funktion von dir wieder brauchen, um dann alle Bezüge von 1 zu 3,4, 10... zu suchen, zum Beispiel.
 

virtus

Gehasst

Registriert
24 Apr. 2015
Beiträge
1.689
Ort
AUF DEM MOND
Okay, du hast Recht, ich fands unter anderem nur lustig das du den gleichen Gedankengang wie ich genommen hast... ich wollte es auch zuerst "normalisieren" nennen, bin aber davon abgewichen....

Ja, vor allem die zeitliche Überschneidung war unserer beiden Beiträge war überraschend.. :D
Ich finde es nicht unbedingt verkehrt hier von Normalisierung zu sprechen. Auch wenn sie in dem Fall sehr trivial ist.
 
Zuletzt bearbeitet:

theSplit

1998
Veteran Barkeeper

Registriert
3 Aug. 2014
Beiträge
28.573
Ja, weil Normalisierung ja glaube ich den Kerngedanken besitzt, "Daten" in "ein eingängiges Format" zu bringen.... so wie ich das Konzept verstehe, was ja hier erfüllt wäre. :)
 

Timon3

Team ModMii

Registriert
17 Juli 2013
Beiträge
499
Ich vermute nicht, dass ein einfaches "kleinere ID in 1, größere in 2" ausreicht. Was ist, wenn man die Wertepaare (5, 20) und (20, 100) hat?

Wir brauchen einfach mehr Informationen.
 
Oben