Mysql - Duplicates abfangen, mit php oder mit unique keys?

Hausbesetzer

Aktives Mitglied
Thread Starter
Dabei seit
10.09.2008
Beiträge
10.816
Reaktionspunkte
2.832
Hi,

was ist eigentlich _die_ Methode, mit denen man Duplikate beim insert in die DB abfangen sollte?
Vor dem Insert ein select und schauen ob die Werte schon da sind oder einfach die entsprechenden Werte als UNIQUE setzen und der Datenbank das Problem zuschieben?
Bisher habe ich das immer mit php gemacht, neulich habe ich das mal mit dem UNIQUE keys probiert und komme mir komisch vor, dass Mysql da halt Warnings ausspuckt. Fühlt sich irgendwie falsch an.

Was sagen denn die Profis hier?

Gruß
 
Das ist eine ewige Diskussion!

Zum einen definierst Du in einer relationalen Datenbank ja Spalten mit Datentypen - mehr nicht ( etwas simpel gesprochen).
Entscheidungen welche Relationen mann dann dazwischen zieht und ob ein Datum vor dem 01.01.2000 erlaubt ist oder der Nachname "Meier" mehrfach vorkommen darf, sind dann eine Frage der Anwendung. Der strenge Anwendungsprogrammierer wird Dir dann sagen, es sei Sache der Software Regeln zu prüfen und einzuhalten und die Datenbank ja nur der Datencontainer. Sprich: alle Logik gehört in die Software.

Der DBler weiß mehr mit SQL anzufangen als nur ein paar CRUD-Operationen, wird Fremdschlüssel nutzen und Regeln aufstellen und somit sogenannte Constraints verwenden.

Beides hat Vor- und Nachteile! Habe das gerade aus einem größeren Softwarehaus gehört, die bei einem Produkt aus Performanz- und Konsistenzgründen verstärkt auf Constraints gesetzt haben und das nun zum Teil wieder rückabwicklen.

Als Pragmatiker würde ich sagen, es kommt auf das jeweilige Beispiel an. Prinzipiell tendiere ich aber eher zum ersten Lager und halte die Logik lieber in der Anwendungssoftware. Du wirst aber sehr leicht jemanden finden der eine andere Sicht vertritt!
 
Ich habe auf der OpenRheinRuhr vor zwei Jahren mal eine ERP-Software namens "SQL Ledger" in einem Vortrag und einem Stand vorgestellt. Viele von den Besuchern haben an der Software geschätzt, dass die Software auf einem Server liegt und dort ausgeführt wird. Allerdings bleibt mir auch der Kommentar eines Besuchers im Hinterkopf, der sagte "Je tiefer, desto besser."

Ich denke mit so Sachen wie PL/SQL (Oracle) oder "Stored Procedures" kann man sicherlich einiges machen. MySQL hatte so etwas sehr lange Zeit nicht aber mittlerweile gibt es auch da Möglichkeiten. Vorteil ist halt, dass der Code an einer bestimmten Stelle halt gewartet werden kann, falls die "Stored Procedure" nicht funktionieren sollte. Andererseits macht man sich aber auch sehr vom Datenbankserver abhängig. Bei Postgres gibt es beispielsweise auch die Möglichkeit, dass man seine Prozeduren auch direkt in Perl schreiben kann (PL/Perl). Das wäre dann so ein Zwischending, dass man eine Skriptsprache und den Datenbankserver kombiniert.
 
und komme mir komisch vor, dass Mysql da halt Warnings ausspuckt. Fühlt sich irgendwie falsch an.
Es kommt auf die Daten und deren Herkunft an.
Wenn es "normal" und bekannt ist, dass gleiche Daten mehrfach auflaufen und diese bewusst ignoriert werden sollen, würde ich die mysql eben warnen lassen und diese Warnung einfach ignorieren.
Wenn doppelte Daten eine "Ausnahmesituation/Fehler" darstellen, würde ich den Fehler vorher abfangen und entsprechend ausgeben.
 
Ich denke mit so Sachen wie PL/SQL (Oracle) oder "Stored Procedures" kann man sicherlich einiges machen. MySQL hatte so etwas sehr lange Zeit nicht aber mittlerweile gibt es auch da Möglichkeiten. Vorteil ist halt, dass der Code an einer bestimmten Stelle halt gewartet werden kann

Constraints sind Regeln die man direkt den Spalten bei der Tabellenerstellung mitgibt. Also Erweiterungen von 'unique key' oder 'not null' oder 'identity'. Damit ist es möglich z.B. eine unsigned int Spalte zu definieren udn festzulegen das nur int > 99000 erlaubt sind etc.

Das mit dem 'je tiefer verankert desto besser', spielt genau in den Aspekt hinein den ich erwähnt hatte. Das ist exakt eine der Sichtweisen ( und ganz sicher auch nicht falsch). Die andere Sichtweise ist eben, dass man so zwei Arten von Code verwalten muß und das man Datenfehler nicht mal einfach korrigieren kann ( was ein constraint nicht erlaubt kann auch nicht eingetragen werden, selbst wenn es in einem Sonderfall mal Sinn machen würde).
 
Das Problem beginnt ja schon bei der Frage, wie du ein Duplikat erkennst. Je komplexer hierfür die Regeln sind, z.b. weil du Ähnlichkeiten schon als Duplikat behandeln möchtest, umso eher willst du das in deiner Software abbilden und nicht in der Datenbank. Das erleichtert dann gegebenenfalls auch den Wechsel der Datenbank. Reine Primärschlüssel würde ich aber schon auf Datenbankebene definieren, das unterstützt auch jede SQL Datenbank, Constraints zur Sicherstellung der referenziellen Integrität (on delete cascade etc.) würde ich eher in die Software legen, da es hier sehr schnell DB-spezifisch wird. Bei massenhaften inserts/updates verlangsamt jeder Schlüssel oder Index, den du auf Datenbankebene definierst, den Schreibvorgang, da hier die Metadaten (der Index) mit gepflegt werden müssen, bei Lesezugriffen, vor allem komplexen Joins, sind Indizes dagegen natürlich unerlässlich. Im "Big Data" Bereich legt man dagegen alles was reinkommt ohne Index und Prüfung ab ("Rohdaten") und verdichtet, sortiert, filtert etc. dann später (Lesezugriffe gehen dann immer auf die Verdichtungen).
Fazit: wie oben mehrfach erwähnt: es kommt darauf an, was man mit den Informationen macht...
 
Wenn es "normal" und bekannt ist, dass gleiche Daten mehrfach auflaufen und diese bewusst ignoriert werden sollen, würde ich die mysql eben warnen lassen und diese Warnung einfach ignorieren.
Das sehe ich anders. Warnungen "einfach" ignorieren ist keine gute Idee. Die Warnung fangen und dann bewusst wegschmeißen ist deutlich besser, sonst läuft dir das Log mit Warnungen über und dein Kunde fragt dich (und sich), wie es denn um die Qualität deiner Software bestellt ist.
Edit: Die Warnung taucht ja vermutlich auf jeden Fall im mysql Log auf, da reicht dann fangen und wegwerfen nicht -> also vorher prüfen...
 
Zurück
Oben Unten