Powl: Doppelte Einträge vermeiden

Hallo,

Konkret geht es um eine MySQL Datenbank, die Daten über ein PHP Skript bekommt. Um z.B. zu verhindern, dass Benutzernamen doppelt vorkommen können, soll bei bereits vorhandenem Wert in Spalte "Name" eine entsprechende Meldung generiert werden. Dafür habe ich 2 Ansätze:

1.
Mittels "SELECT COUNT(*)  FROM tabelle WHERE Name == ".$_POST['name'].";" ermitteln, ob der Wert schon vorkommt. Wenn das Ergebniss grösser 0 ist, dann nicht speichern und Fehlermeldung "Doppelter Wert" ausgeben.

2.
Bei der Erstellung der Tabelle die Spalte Name als UNIQUE angeben:
CREATE TABLE IF NOT EXISTS tabellenname (
    ID   INT AUTO_INCREMENT PRIMARY KEY,
    Name VARCHAR(100) UNIQUE,
    ...
);

Wenn dann über INSERT ein vorhandener Wert gespeichert werden soll, wird ein Fehler mit der Nummer 1062 zurückgegeben. Den kann man mit errno() abfragen und wenn $errno == 1062, dann Fehlermeldung "Doppelter Wert" ausgeben. Gespeichert wird dann ja sowieso nicht.

Das zu programmieren wäre kein Problem, ich frage mich nur für welche Lösung ich mich entscheiden soll.
Ich würde vermuten Lösung 2 wäre bei besonders bei grossen Datenmengen performanter? Wie steht es mit der Kompatibilität zu verschiedenen MySQL Versionen?

Welche Lösung würdet Ihr aus welchem Grund bevorzugen?

netten Tag
^da Powl

--
===============================
powl.hat-gar-keine-homepage.de/
  1. Mahlzeit Powl,

    Das zu programmieren wäre kein Problem, ich frage mich nur für welche Lösung ich mich entscheiden soll.

    Auf jeden Fall letzteres. Wenn Du bestimmte Werte nicht doppelt in der Datenbank haben willst, solltest Du auch genau an der Stelle ansetzen: beim UNIQUE-Constraint auf das entsprechende Feld. Wenn Du Dich auf die fehlerfreie Funktionalität Deiner Oberfläche (die ja nur EINE Möglichkeit ist, Daten in die Tabelle einzufügen!) verlässt, bist Du u.U. irgendwann verlassen ...

    MfG,
    EKKi

    --
    sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
    1. Hallo Ekki,

      Auf jeden Fall letzteres.

      Ja, Du hast recht. Alternativen zum PHP-Skript für das einfügen von Daten hatte ich gar nicht bedacht.
      Aber z.B. MyPHP-Admin gibt's ja auch noch. Da ist das UNIQUE natürlich unabdingbar.

      Danke für die schnelle Antwort.

      netten Tag
      ^da Powl

      --
      ===============================
      powl.hat-gar-keine-homepage.de/
    2. Hi,

      Auf jeden Fall letzteres.

      richtig. Ein bereits vorhandener Name kann ohne Weiteres als Ausnahme definiert werden; Ausnahme heißt auf Englisch "exception". Dies ist also *exakt* der Grund, weshalb Exception Handling erfunden wurde.

      Äh, und natürlich auch Unique Constraints :-)

      Cheatah

      --
      X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
      X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
      X-Will-Answer-Email: No
      X-Please-Search-Archive-First: Absolutely Yes
  2. echo $begrüßung;

    Mittels "SELECT COUNT(*)  FROM tabelle WHERE Name == ".$_POST['name'].";" ermitteln, ob der Wert schon vorkommt. Wenn das Ergebniss grösser 0 ist, dann nicht speichern und Fehlermeldung "Doppelter Wert" ausgeben.

    Da du diesen Vorgang sicher nicht atomar anlegen willst, kann es hier passieren, dass zwischen Abfrage und Eintragen eine weitere Abfrage ebenfalls 0 ergibt. Dieser Fall ist zwar relativ unwahrscheinlich, doch warum solltest du dich darauf verlassen, wenn du mit der Unique-Index-Lösung zum vergleichbaren Aufwand auf der sicheren Seite bist. Wenn du 1. richtig atomar anlegen willst, bist du mit 2. sogar deutlich günstiger im Rennen.

    Ich würde vermuten Lösung 2 wäre bei besonders bei grossen Datenmengen performanter?

    Das dürfte egal sein. In beiden Fälle muss nur im Index nachgesehen werden. Du hättest doch bei 1. einen angelegt, nicht?

    Wie steht es mit der Kompatibilität zu verschiedenen MySQL Versionen?

    Unique Index gibt es mindestens schon seit ewig. Stored Procedures (bei denen ich grad nicht weiß, ob die atomar arbeiten - vermutlich nicht von Haus aus) und Transactions gibt es erst ab V5.0 bzw. nur mit der InnoDB Storage Engine.

    echo "$verabschiedung $name";