Knud Schröder: (SQL)(PHP) Prüfung auf Existenz von Datensätzen

Hallo Forummer !

Über ein PHP-Script möchte ich dem Anwender die Möglichkeit geben, Adressen zu erfassen.
Diese werden dann in einer SQL-Datenbank gespeichert.
Dabei soll das Script doppelte Eingaben verweigern.
Ich suche nun nach einer (DER!) effektiven Prüffunktion, die dieses überprüft.
Dabei sollte auch "Meier, Karl" und "Karl Meier" abgefangen werden.
Aber es könnte auch möglich sein, dass es tatsächlich zwei Karl Meier gibt, also müsste wohl
die Postleitzahl mit berücksichtigt werden. (Ich denke, es ist nahezu auszuschliessen, dass es zwei
Karl Meier gibt, die auch noch im gleichen Haus/Ort wohnen und bei mir erfasst werden müssen.

Meine erste Idee war, wie ich es schonmal in dBase/Foxpro realisiert habe, einen kombinierten Index
auf Postleitzahl und den ersten 5 Buchstaben der Strasse zu legen.
geht das überhaupt mir SQL, kombinierte Indexe?

Es gibt auch eine Funktion bei Foxpro, die "Meier" und "Maier" oder "Straße" und "Strasse" als gleich
erkennt und sogar auch "Karl Meier" und "Meier Karl", selbst ein "mEiEr - , KaRL" würde er als gleich
erkennen.
Wäre echt toll, wenn es so eine ähnliche Funktion auch gebe?

Hat vielleicht jemand noch eine andere Idee, wie ich mit der höchstmöglichen Sicherheit doppelte
Adress-Eingaben verhindern kann?

Danke schonmal,

Knud

  1. Hi,

    Meine erste Idee war, wie ich es schonmal in dBase/Foxpro realisiert habe, einen kombinierten Index
    auf Postleitzahl und den ersten 5 Buchstaben der Strasse zu legen.
    geht das überhaupt mir SQL, kombinierte Indexe?

    mit einen Primary Key, wie er unter MySQL heisst, wuerde ich auhc arbeiten.
    Eine Einfuehrung in MySQL und dessen Unterschiede gibt es unter http://www.little-idiot.de/mysql/
    Dort wird dann auch klar, wie Du einen kombinierten Index aufbauen kannst

    Jan

    1. Eine Einfuehrung in MySQL und dessen Unterschiede gibt es unter http://www.little-idiot.de/mysql/
      Dort wird dann auch klar, wie Du einen kombinierten Index aufbauen kannst

      Also etwa so ?

      CREATE UNIQUE INDEX adresse ON kunden (PLZ, STRASSE(5) )

      baut den Index auf bestehend aus PLZ + die ersten 5 Zeichen von STRASSE ?

      Gruß,

      Knud

      1. Hi,
        ich teste das jetzt nicht fuer Dich und ich bin auhc kein MySQL Profi.

        Also etwa so ?

        CREATE UNIQUE INDEX adresse ON kunden (PLZ, STRASSE(5) )

        Warum testest Du das nicht einfach, dann siehst Du ob das geht und wenn nicht, was fuer Fehlermeldungen oae. kommen.

        Jan

      2. CREATE UNIQUE INDEX adresse ON kunden (PLZ, STRASSE(5) )
        baut den Index auf bestehend aus PLZ + die ersten 5 Zeichen von STRASSE ?

        Zunächst mal: Ein PRIMARY KEY im Sinne von SQL ist *das* nicht. (Nur ein eindeutiger Index - davon kann eine Tabelle mehrere haben, PRIMARY KEY nur einen.)

        Andererseits würde mich wundern, wenn es möglich wäre, einen Index (bzw. eine Komponente davon) auf einen Teil einer Tabellenspalte zu legen. Denn so, wie ein Indexbaum intern strukturiert ist, macht das wenig Sinn.
        Wenn Du wirklich *nur* genau die ersten fünf Zeichen als indexrelevant ansiehst, solltest Du eine separate (inhaltlich redundante) Spalte mit diesem Wert (ggf. concateniert mit anderen Schlüsselkomponenten) anlegen und darüber den PRIMARY KEY der Tabelle legen.

        1. Hallo Michael !

          Andererseits würde mich wundern, wenn es möglich wäre, einen Index (bzw. eine Komponente davon) auf einen Teil einer Tabellenspalte zu legen. Denn so, wie ein Indexbaum intern strukturiert ist, macht das wenig Sinn.
          Wenn Du wirklich *nur* genau die ersten fünf Zeichen als indexrelevant ansiehst, solltest Du eine separate (inhaltlich redundante) Spalte mit diesem Wert (ggf. concateniert mit anderen Schlüsselkomponenten) anlegen und darüber den PRIMARY KEY der Tabelle legen.

          Das habe ich von little-idiot.de:

          Für CHAR und VARCHAR Spalten werden stets nur die ersten 10 Buchstaben indiziert. Beispiel:

          mysql> CREATE INDEX part_of_name ON customer (name(10));

          Da die meisten Namen sich innerhalb der ersten 10 Buchstaben unterscheiden, sollte der INDEX nicht kleiner sein, als der
          INDEX für die ganze Namensspalte.

          Das heißt doch schon soviel wie nur ein Teil des Spalteninhalts wird "verindext", oder ?

          Ein wenig ratlos,

          Knud

          1. Das heißt doch schon soviel wie nur ein Teil des Spalteninhalts wird "verindext", oder ?
            Ein wenig ratlos,

            Sorry, ich bezog mich auf SQL, nicht auf eine abgespeckte Freeware-Implementierung.

  2. Hallo Knud

    Meine erste Idee war, wie ich es schonmal in dBase/Foxpro realisiert habe, einen kombinierten Index
    auf Postleitzahl und den ersten 5 Buchstaben der Strasse zu legen.
    geht das überhaupt mir SQL, kombinierte Indexe?

    In der Regel ja, das Anlegen des Indexes hängt jedoch vom verwendeten SQL-Server ab.
    Bei MS-SQL sieht dies z.B. so aus:

    CREATE UNIQUE
         INDEX [idx_test] ON [dbo].[tblHaendler] ([lngHaendlernummer], [strStrasse], [strPLZ])

    Funktionen in der Indexdefinition (z.B.convert() oder case() zum ermitteln der ersten 5 Zeichen eines Feldes) sind, zumindest bei MS-SQL, nicht erlaubt.

    Natürlich könnte man jedoch in der Tabelle ein Feld einbauen, dass nur die ersten 5 Buchstaben des Feldes enthält, bzw. direkt einen "eindeutigen" Matchcode aus einer beliebiegen Feld- und Funktionskombination enthält.
    Dieses Feld "Matchcode" müsste über Triggers bei jedem Update/Insert, der in die Matchcodebildung einbezogenen Felder, erzeugt werden.

    Anschliessend setzt Du den Index nur noch auf dieses Feld.

    Ich hoffe, dass ich Dir damit einen Lösungsansatz vermitteln konnte.

    Grüsse
    Tom

    1. Hallo Tom !

      Wie ich schon Michael geantwortet habe, fand ich den folgenden Textabschnitt bei
      little-idot.de/mysql (oder so):

      Für CHAR und VARCHAR Spalten werden stets nur die ersten 10 Buchstaben indiziert. Beispiel:

      mysql> CREATE INDEX part_of_name ON customer (name(10));

      Da die meisten Namen sich innerhalb der ersten 10 Buchstaben unterscheiden, sollte der INDEX nicht kleiner sein, als der
      INDEX für die ganze Namensspalte.

      Das heisst für mich, dass in dem Fall doch nur die ersten 10 Buchstaben relevant werden, oder versteh
      ich das falsch?

      Mit offenem Mund,

      Knud

      1. Hallo Knud

        Für CHAR und VARCHAR Spalten werden stets nur die ersten 10 Buchstaben indiziert. Beispiel:

        mysql> CREATE INDEX part_of_name ON customer (name(10));

        Da die meisten Namen sich innerhalb der ersten 10 Buchstaben unterscheiden, sollte der INDEX nicht kleiner sein, als der
        INDEX für die ganze Namensspalte.

        Das heisst für mich, dass in dem Fall doch nur die ersten 10 Buchstaben relevant werden, oder versteh
        ich das falsch?

        So wie es geschrieben steht, scheint dies bei MySQL so der Fall zu sein.
        Dies ist jedoch kein Standard sondern MySQL-spezifisch.
        Darum lege Dich jetzt auf ein bestimmten SQL-Server fest, bevor Du Lösungen realisierst, die danach nicht funktionieren.
        Zu MySQL kann ich Dir jedoch in keiner Weise weiterhelfen.

        Grundsätzlich empfehle ich Dir bei dieser Problematik, dass Du tatsächlich ein weiteres (inhaltlich reduntandes, -> Michael) Feld führst, indem Du Dir frei von allen Einschränkungen des jeweiligen SQL-Servers Deinen Matchcode (eindeutiger Key) selbst erzeugst.
        Dieses Feld lässt sich dan auch problemlos mit einem Index belegen.

        Grüsse
        Tom