Dubletten anhand von longtext finden

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Dubletten anhand von longtext finden

    Einen Guten Morgen wünsche ich!!

    Meine Situation:
    Ich möchte über ein cronjob mehrere hundert Datensätze täglich in eine Tabelle schreiben. Ein Datensatz besteht unter anderem aus einem Longtext (einer description), einem Titel und einer zugehörigen location (PLZ und Ort). Es kann nun vorkommen, dass Titel und location gleich sind, jedoch die description verschieden ist. Es bleibt mir also leider nichts übrig als vor jedem Insert zu prüfen, ob diese description bereits vorhanden ist. Problem ist, dass jeweils mehrere tausende Datensätze verglichen werden müssen und das dauert bei der Prüfung ewig denke ich...

    Meine Frage:
    Wie prüft man sowas am besten?
    Oder bleibt mir nur eine Variante wie:

    PHP-Code:
    $sql 'SELECT title, locationdata_id, description FROM tbl WHERE title = "'.$title.'" AND locationdata_id = '.$locationdata_id.' AND description = "'.$description.'"';
    $result mysql_query($sql);
    $rowcheck mysql_fetch_assoc($result);

    if(!
    $rowcheck) {
        
    // Inserte

    Was haltet ihr von einem unique auf die description spalte in der DB?

    Ich habe noch folgendes gelesen:
    Ich hab noch nen interessanten Ansatz für nen Work around, man verwendet nen Sha1 Hashwert den man in nen VarChar schreibt und diesen auf Unique setzt. Dadurch kann man dann auch Elemente vom Typ "SmallText", "LongText" und "Text" einwandfrei auf Duplicate prüfen.
    Ist das evtl eine Lösung?

    Bisher musste ich so große Texte noch nicht vergleichen vielleicht habt ihr einen Guten Ansatz für mich.
    Grüße

  • #2
    Zitat von Peh4pe Beitrag anzeigen
    Es kann nun vorkommen, dass Titel und location gleich sind, jedoch die description verschieden ist. Es bleibt mir also leider nichts übrig als vor jedem Insert zu prüfen, ob diese description bereits vorhanden ist.
    Hast du das aus Versehen falsch formuliert oder versteh ich es nur nicht?
    Wenn Titel und location ggf. gleich sind und nur die description unterscheidet sich, warum willst du dann die description auf mögliche Duplikate prüfen?
    Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
    Schön - etwas Geschichte kann ja nicht schaden.
    Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

    Kommentar


    • #3
      Eher unverständlich formuliert..

      also es Darf sein, dass Titel und Location gleich sind.. wenn dazu noch die description gleich wäre, wäre es eine dublette..

      ich will checken:

      wenn
      titel_aus_db, location_aus_db,description_aus_db
      gleich
      titel_neu, location_neu,description_neu
      dann
      gebe mir datensatz_aus_db wieder um etwas zu mergen.

      theoretisch würde es auch langen nur die description zu checken.. aber so wie gerade beschrieben wäre es optimal.
      Mein Bedenken ist nur, dass so wie ich es aktuell prüfen will (mit dem $rowcheck) wahrscheinlich sehr unperformant sein wird?

      Kommentar


      • #4
        Zitat von Peh4pe Beitrag anzeigen
        Eher unverständlich formuliert..

        also es Darf sein, dass Titel und Location gleich sind.. wenn dazu noch die description gleich wäre, wäre es eine dublette.
        ...
        Mein Bedenken ist nur, dass so wie ich es aktuell prüfen will (mit dem $rowcheck) wahrscheinlich sehr unperformant sein wird?
        Erstmal solltest du es ausprobieren, sprich: messen. Dann kannst du versuchen, die Geschwindigkeit zu steigern, falls nötig.

        Alle deine Vorschläge|Ideen|gelesenen Tricks lassen sich kombinieren.
        Um einen sehr langen Text mit einer Liste von sehr langen Texten effizient zu vergleichen, geht man in der Reihenfolge vom geringsten zum höchsten Aufwand vor:

        1.) Länge vergleichen. Sind die Texte nicht gleich lang, sind sie auch nicht gleich.

        2.) Prüfsumme|Hash-Wert oder ähnliches berechnen und vergleichen. Sind sie unterschiedlich, sind es auch die Texte. Hier musst du beachten, dass die verwendete Hash-Funktion über den gesamten Text läuft.

        3.) Schließlich der mühsame Vergleich des Volltextes. Hier hilft die Datenbank, wenn sie entsprechende Indizes erstellen kann. Dann werden die Texte quasi vorsortiert und der Vergleich kann effizienter erfolgen. Im komfortabelsten Fall hat die entsprechende Spalte in der Tabelle den Constraint UNIQUE, so dass die Datenbank schon beim Einfügen eines neuen Datensatzes bescheid geben kann. Wie sich MySQL hier anstellt, musst du allerdings selbst rausfinden ... Dieses Gewürge mit den unterschiedlichen String|Text-Typen; die sich in Verbindung mit den unterschiedlichen Storage-Engine-Typen unterschiedlich verhalten, würde ich mir nur ungern antun.

        Ein Problem mit Dubletten-Erkennung von Texten ist allerdings, dass Texte, die (in der Rohfassung) für Maschinen ungleich sind, für menschliche Betrachter trotzdem gleich "aussehen" können. Dann müssen alle drei Vergleichsstufen daran angepasst werden. Also bspw.:

        1.) Länge: Nicht nur Bytes zählen, sondern nur Nicht-Whitespace-Zeichen.

        2.) Prüfsumme|Hash-Wert: Groß-Klein-Schreibung, Whitespace usw. ignorieren.

        3.) Volltextvergleich: wie 2.

        --

        Gemecker zum Schluss: Verwende PDO oder mysqli und binde Benutzereingaben als Parameter an Prepared Statements (siehe auch). Wenn du die ungeprüft mit SQL-Syntax zusammenklebst, musst du dir keine Sorgen um Effizienz machen, weil du dir vorher größere Probleme einhandelst.
        Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

        Kommentar


        • #5
          @fireweasel

          ich hab auch grad die ganze Zeit überlegt - ein Volltextindex bringt bei seiner Frage eher wenig bzw. ist unnütz oder täusch ich da? Es muss ja nur die komplette Zeichenkette geprüft werden und nicht einzelne "Wörter".
          Ihr habt ein Torturial durchgearbeitet, das auf den mysql_-Funktionen aufbaut?
          Schön - etwas Geschichte kann ja nicht schaden.
          Aber jetzt seht euch bitte php.net/pdo oder php.net/mysqli bevor ihr beginnt!

          Kommentar


          • #6
            Also erstmal danke für die Denkanstöße!

            Ich habe es aktuell so gelöst, dass ich eine neue Spalte mit dem md5 hash von der description angelegt habe und beim insert die dann auch checke.

            Läuft fix und macht das was es sollte.

            PDO und/oder mysqli stehen auf der Todo

            Danke!

            Kommentar


            • #7
              Leg’ auf die MD5-Spalte einen Unique Index, und baue den MD5-Wert dann gleich ins INSERT-Statement mit ein … dann kriegst du im Falle der Verletzung des U.I. eine eindeutige Fehlernummer, die sich gezielt auswerten lässt.
              I don't believe in rebirth. Actually, I never did in my whole lives.

              Kommentar

              Lädt...
              X