Monday 20 November 2017

Mysql Moving Average Abfrage


MySQL Trigger: Auto-generieren zusätzliche Informationen in der Datenbank MySQL Trigger sind eine der neueren Funktionen in MySQL, die helfen, es eine tragfähige Alternative für große Unternehmen Anwendungen zu machen. Vor nicht allzu langer Zeit haben diejenigen, die ihr Leben mit großen kommerziellen Datenbanken wie Oracle und DB2, darauf hingewiesen, dass MySQL war eine schöne, schnelle kleine Datenbank, aber es fehlte wichtige Funktion wie gespeicherte Prozeduren, Transaktionen und Trigger. Ab Version 5.0 von MySQL können diese Funktionen von dieser Liste abgekreuzt werden. Also, was ist MySQL-Trigger, und warum MySQLs Fähigkeit, sie zu nutzen machen es attraktiver für seriöse Datenbank-Benutzer Einfach ausgedrückt, Trigger sind kleine Programme, die in der Datenbank selbst gespeichert sind, und werden durch Datenbank-Ereignisse, die oft entstanden bei der Anwendung aktiviert Schicht. Diese fällende Datenbankereignisse sind UPDATE, DELETE oder INSERT Abfragen. Der Trigger selbst kann vor oder nach der Abfrage ausgeführt werden, die ihn initiiert. Trigger werden häufig verwendet, um die Integrität von Daten über Tabellen einer Anwendung aufrechtzuerhalten. Wenn ein Benutzer auf einer Website einen Kauf tätigt, kann beispielsweise die erste Aktion, die in der Datenbank auftritt, sein, dass ein Kredit in eine Buchhaltungstabelle eingefügt wird. Durch einen Auslöser könnte diese Aktion eine Kettenreaktion von Ereignissen in anderen Tabellen während der gesamten Anwendung auslösen. Die Produktzählung eines Artikels könnte in einer Bestands-Tabelle dekrementiert werden, eine Belastung, die von einem Kunden-Kontostand in einer anderen Tabelle abgezogen wird, ein Ladenkredit, der auf eine andere Tabelle angewendet wird. Sie können sagen, dass Sie dies alles in Ihrer Anwendung mit PHP oder Perl oder Python oder ASP-Code getan haben. Was ist die große Sache über die Verwendung von MySQL-Trigger Nun, es gibt einige Vorteile bei der Verwendung von Auslösern über Anwendungscode für die Aufrechterhaltung der Integrität der Daten über Tabellen. Ein Trigger führt in der Regel die Arten von Aufgaben schneller als Anwendungscode, und kann einfach und schnell hinter den Kulissen aktiviert werden und muss nicht ein Teil Ihres Anwendungscodes sein. Das spart Zeit und erspart dich von redundanter Codierung. Wenn Sie jemals Ihre Anwendung auf eine andere Sprache portieren, sind die Chancen, dass Ihre Auslöser ohne Veränderung bleiben können, zusammen mit Ihren Tabellen und anderen Datenbankobjekten. Um zu demonstrieren, wie MySQL auslöst Arbeit, können Sie zwei einfache Tabellen auf einer Datenbank gut aufrufen 8220salesrecords8221, die Daten, die interdependent sind. Stellen Sie sich eine Datenbank vor, die die Verkaufsrekorde von drei Verkäufern in einem Kaufhaus verfolgt. Sie arbeiten in der Elektronikabteilung, die Sachen wie Fernsehapparate verkauft. Stereos und MP3-Player. Wir haben die Haupttabelle, die einen Rekord von jedem Verkauf hält. Er zeichnet den Betrag des Verkaufs (Verkaufsdatum), das Datum (Datum), den Namen des Verkäufers (Name), seine ID-Nummer (employeeid) und die Produkt-ID (prodid) auf. Nun nennen Sie diesen Tisch (geschickt genug) 8220sales8221. In der zweiten Tabelle wollen wir einige Daten behalten, die es uns erlauben, leicht zu verfolgen, wie jeder Verkäufer tut. Es wird die Verkäufer ID (employeeid), Name (Name), Gesamtzahl der Verkäufe (totalsales) und eine Spalte, die jeden Verkäufer durchschnittlichen Betrag pro Verkauf (avesale) hält. Wir wollen sehen, wer die High-End-Artikel bewegt. Nun nennen Sie diesen Tisch 8220performance8221. Jetzt kommt der harte Teil. Wie ich schon erwähnt habe, sind Auslöser Datenbankobjekte wie Tabellen. Trigger sind jedoch in der Lage, Prozedurcode auszuführen, der Daten in Ihren Tabellen ändert. In diesem Fall wollen wir, dass unser Auslöser vor einer INSERT-Anweisung ausgelöst wird, die in der Verkaufstabelle ausgeführt wird. Wenn ein Verkaufsrekord in die Verkaufstabelle eingefügt wird, müssen die Verkaufssummen in der Leistungstabelle aktualisiert werden. Der folgende Code kann in Ihren Lieblingstexteditor eingegeben werden und in die Konsole an der MySQL-Eingabeaufforderung eingefügt werden. Bevor du das machst, dann möchtest du diese Zeile ausführen: Unser Prozedurcode verwendet Semikolons am Ende der Aussagen, also müssen wir ein anderes Trennzeichen setzen, damit MySQL wissen kann, wann unser Codeblock vorbei ist und damit die Verarbeitung nicht beendet wird Unser Block, wenn es ein Semikolon trifft. Denken Sie daran, dass Sie, nachdem Sie Ihren Block beendet haben, das Trennzeichen auf das Semikolon zurücksetzen oder alle nachfolgenden Befehle mit dem neuen Trennzeichen beenden müssen. Wenn Sie zum Beispiel Fehler in Ihrem CREATE TRIGGER-Block gemacht haben und ihn löschen möchten, funktioniert DROP TRIGGER nicht, wenn Sie das Trennzeichen nicht auf das Semikolon setzen. Hier ist der Code für den Trigger: OK, lass uns über den Code sprechen. Mit der CREATE TRIGGER-Anweisung initiierte wir den Trigger und nannte ihn salesbitrg. MySQL-Trigger können vor oder nach einem INSERT-, UPDATE - oder DELETE-Ereignis auslösen. Dieser wird ausgelöst, bevor irgendwelche Daten in die Verkaufstabelle eingefügt werden. Die FÜR JEDE ROW-Klausel bedeutet, dass der Block auf jede Zeile wirkt, die die Kriterien unserer SQL-Anweisungen erfüllt. Die Schlüsselwörter BEGIN und END schließen die Trigger-Anweisungen ein, die ausgeführt werden, wenn der Trigger ausgelöst wird. Es werden zwei Variablen deklariert. Die erste ist numrow, die überprüft, ob der Mitarbeiter hat, wer hat den Verkauf, der eingegeben werden soll, hat einen Verkauf in der Performance-Tabelle zuvor eingegeben hat. Wenn es keine Mitarbeiter gibt, die passen, dann ist dies der Angestellte ersten Verkauf, und dies entspricht der ELSE Bedingung unserer 8220IF Aussage. Diese Daten werden als Insert in der Performance-Tabelle und nicht als Update eingegeben. Wenn die Anzahl größer als 0 ist, wird die Leistungstabelle aktualisiert. Die zweite Variable, totrows, ist eine Anzahl von, wie viele Verkäufe der Mitarbeiter in der Verkaufstabelle hat. Dieser Wert wird verwendet, um den durchschnittlichen Verkauf der Mitarbeiter zu berechnen. Die Zählung erfolgt, bevor der Verkauf in den Verkaufstisch eingefügt wird, also müssen wir einen dazu hinzufügen. Wenn die Performance-Tabelle aktualisiert wird der durchschnittliche Verkauf totalsales (totrows1). Wenn unser MySQL-Trigger ordnungsgemäß funktioniert, wird die Performance-Tabelle eine laufende Summe von jedem Verkäufer Gesamtumsatz und auch die durchschnittliche Menge ihrer Gesamtverkäufe zu halten. Es wird dies unabhängig von Ihrem Anwendungscode tun und auf jede Anwendungsplattform portierbar sein. Um ihm einen Whirl zu geben, legen Sie einige Daten in die Verkaufstabelle ein und überwachen den Inhalt der Performance-Tabelle. Hier ist die Aussage: Ändern Sie die Zahlen und Namen und versuchen Sie es ein paar Mal. (Denken Sie daran, ein Mitarbeiter hält die gleiche Mitarbeiterzahl für jeden seiner Verkäufe.) Wenn Sie sich abenteuerlich fühlen, denken Sie darüber nach, wie der MySQL-Auslöser erweitert werden müsste, um für UPDATE - und DELETE-Anweisungen auf der Verkaufstabelle zu berücksichtigen. Free eBook Abonnieren Sie meinen Newsletter und erhalten Sie mein ebook auf Entity Relationship Modeling Principles als kostenloses Geschenk: Was die Besucher sagen. Ich stolperte nur über Ihre Website auf der Suche nach einer Normalisierungstheorie und ich muss sagen, dass es fantastisch ist. Ich bin seit 10 Jahren im Datenbank-Bereich und habe noch nie zuvor eine so nützliche Seite gefunden. Vielen Dank, dass Sie sich die Zeit genommen haben, diese Seite zusammenzustellen. PHP bietet drei verschiedene APIs, um eine Verbindung zu MySQL herzustellen. Dies sind die mysql (entfernt von PHP 7), mysqli. Und PDO-Erweiterungen. Die mysql-Funktionen waren sehr beliebt, aber ihre Verwendung wird nicht mehr gefördert. Das Dokumentations-Team diskutiert die Datenbank-Sicherheits-Situation, und die Erziehung von Benutzern, sich von der häufig verwendeten extmysql-Erweiterung zu entfernen, ist ein Teil davon (check php. internals: deprecating extmysql). Und das spätere PHP-Entwicklerteam hat die Entscheidung getroffen, EDEPRECIERTE Fehler zu generieren, wenn Benutzer mit MySQL verbinden, sei es durch mysqlconnect (). Mysqlpconnect () oder die implizite Verbindungsfunktionalität in extmysql eingebaut. Extmysql wurde offiziell abgelehnt ab PHP 5.5 und wurde ab PHP 7 entfernt. Wenn du auf eine mysql-Funktions-Manual-Seite gehst, siehst du eine rote Box und erklärst, dass sie nicht mehr benutzt werden sollte. Der Weg von extmysql geht es nicht nur um die Sicherheit, sondern auch um den Zugriff auf alle Funktionen der MySQL-Datenbank. Extmysql wurde für MySQL 3.23 gebaut und bekam nur sehr wenige Ergänzungen seit damals, während meistens die Kompatibilität mit dieser alten Version beibehalten, die den Code etwas schwieriger macht. Fehlende Funktionen, die von extmysql nicht unterstützt werden, sind: (aus PHP-Handbuch). Grund, keine MySQL-Funktion zu verwenden: Nicht unter aktiver Entwicklung Entfernt von PHP 7 Fehlt eine OO-Schnittstelle Nicht unterstützt non-blocking, asynchrone Abfragen Unterstützt nicht vorbereitete Anweisungen oder parametrisierte Abfragen Unterstützt nicht gespeicherte Prozeduren Unterstützt nicht mehrere Anweisungen Unterstützt keine Transaktionen Stützt nicht alle Die Funktionalität in MySQL 5.1 Mangel an Unterstützung für vorbereitete Aussagen ist besonders wichtig, da sie eine klarere, weniger fehleranfällige Methode zum Entweichen und Zitieren von externen Daten bereitstellen, als manuell mit einem separaten Funktionsaufruf entschlüsseln. Unterdrückung von Abschreibungswarnungen Während Code in MySQLi PDO umgewandelt wird. EDEPRECATED-Fehler können durch die Einstellung von errorreporting in php. ini unterdrückt werden, um EDEPRECATED auszuschließen: Beachten Sie, dass dies auch andere Ablehnungswarnungen ausblenden wird. Was aber für andere Dinge als MySQL sein kann. (Von PHP manuell) Und ein besserer Weg ist PDO. Und ich schreibe jetzt ein einfaches PDO Tutorial. Ein einfaches und kurzes PDO-Tutorium Q. Erste Frage in meinem Kopf war: Was ist PDO A. PDO PHP Data Objects ist eine Datenbank-Zugriffsschicht, die eine einheitliche Methode des Zugriffs auf mehrere Datenbanken bietet. Verbinden mit MySQL Mit MySQL-Funktion oder wir können es sagen, die alte Weise (veraltet in PHP 5.5 und höher) Mit PDO. Alles was Sie tun müssen, ist ein neues PDO-Objekt zu erstellen. Der Konstruktor akzeptiert Parameter für die Angabe der Datenbankquelle PDO s Konstruktor nimmt meistens vier Parameter, die DSN (Datenquellenname) und optional Benutzername sind. Passwort Hier denke ich, du bist vertraut mit allen außer DSN das ist neu in PDO. Ein DSN ist grundsätzlich eine Reihe von Optionen, die PDO mitteilen, welche Treiber zu verwenden ist, und Verbindungsdetails. Weitere Informationen finden Sie unter PDO MySQL DSN. Hinweis: Sie können auch charsetUTF-8 verwenden. Aber manchmal verursacht es einen Fehler, also ist es besser, utf8 zu benutzen. Wenn es einen Verbindungsfehler gibt, wird ein PDOException-Objekt geworfen, das zwischengespeichert werden kann, um Exception weiter zu behandeln. Sie können auch mehrere Treiberoptionen als Array an den vierten Parameter übergeben. Ich empfehle, den Parameter zu übergeben, der PDO in den Exception-Modus bringt. Weil einige PDO-Treiber nicht native vorbereitete Aussagen unterstützen, so PDO führt Emulation der Vorbereitung. Außerdem können Sie diese Emulation manuell aktivieren. Um die nativen serverseitig vorbereiteten Anweisungen zu verwenden, sollten Sie sie explizit falsch setzen. Die andere ist zu deaktivieren Vorbereitung Emulation, die in der MySQL-Treiber standardmäßig aktiviert ist, aber vorbereiten Emulation sollte ausgeschaltet werden, um PDO sicher zu verwenden. Ich werde später erklären, warum die Vorbereitung der Emulation ausgeschaltet werden sollte. Um Grund zu finden, bitte diesen Beitrag überprüfen. Es ist nur nutzbar, wenn man eine alte Version von MySQL benutzt, die ich nicht empfehlen kann Unten ist ein Beispiel dafür, wie du es machen kannst: Können wir Attribute nach der PDO-Konstruktion setzen Ja. Wir können auch einige Attribute nach der PDO-Konstruktion mit der setAttribute-Methode festlegen: Fehlerbehandlung Fehlerbehandlung ist viel einfacher in PDO als mysql. Eine gängige Praxis bei der Verwendung von MySQL ist: ODER sterben () ist kein guter Weg, um den Fehler zu behandeln, da wir das Ding nicht verarbeiten können. Es wird einfach das Skript abrupt beenden und dann den Fehler auf den Bildschirm, den Sie normalerweise nicht wollen, um Ihre Endbenutzer zu zeigen, und lassen Sie blutige Hacker entdecken Sie Ihr Schema. Alternativ können die Rückgabewerte von mysql-Funktionen oft in Verbindung mit mysqlerror () verwendet werden, um Fehler zu behandeln. PDO bietet eine bessere Lösung: Ausnahmen. Alles, was wir mit PDO machen, sollte in einen try - catch - Block eingehüllt werden. Wir können PDO in einen von drei Fehlermodi zwingen, indem wir das Fehlermodusattribut setzen. Drei Fehlerbehandlungsmodi sind unten. PDO :: ERRMODESILENT Es ist einfach Einstellung Fehlercodes und handelt ziemlich ähnlich wie MySQL, wo Sie jedes Ergebnis überprüfen müssen und dann auf db-gterrorInfo () schauen, um die Fehlerdetails zu erhalten. PDO :: ERRMODEWARNING Heben Sie das Erinnern an. (Laufzeitwarnungen (nicht schwerwiegende Fehler) Die Ausführung des Skripts wird nicht gestoppt.) PDO :: ERRMODEEXCEPTION. Ausnahmen auswerfen Es stellt einen Fehler dar, der durch PDO aufgeworfen wird. Du solltest keine PDOException aus deinem eigenen Code werfen. Siehe Ausnahmen für weitere Informationen über Ausnahmen in PHP. Es wirkt sehr ähnlich oder stirbt (mysqlerror ()). Wenn es nicht gefangen ist. Aber anders als sterben (). Die PDOException kann gefangen und behandelt werden anmutig, wenn Sie sich dafür entscheiden. Und du kannst es in try - catch einpacken. Wie unten: Du musst jetzt nicht mit try - catch umgehen. Sie können es jederzeit einholen, aber ich empfehle Ihnen dringend, den Versuch zu verwenden. Auch kann es sinnvoller sein, es an der Außenseite der Funktion zu fangen, die das PDO-Zeug anruft: Auch kannst du mit oder sterben () oder wir können wie mysql sagen. Aber es wird wirklich abwechslungsreich. Sie können die gefährlichen Fehlermeldungen in der Produktion ausblenden, indem Sie die Displayfehler ausschalten und gerade Ihr Fehlerprotokoll lesen. Nun, nach dem Lesen all die Dinge oben, sind Sie wahrscheinlich denken: was zum Teufel ist das, wenn ich nur anfangen möchte, einfach zu lehnen SELECT. EINFÜGEN. AKTUALISIEREN. Oder DELETE Aussagen Sorgen Sie sich nicht, hier gehen wir: Daten auswählen So was machst du in mysql ist: Jetzt in PDO. Du kannst das so machen: Note. Wenn Sie die Methode wie unten (query ()) verwenden, gibt diese Methode ein PDOStatement-Objekt zurück. Also, wenn du das Ergebnis holen willst, benutze es wie oben. In PDO-Daten wird es über die - gtfetch () erhalten. Eine Methode Ihrer Anweisung behandeln. Vor dem Aufruf, der beste Ansatz würde sagen, PDO wie youd wie die Daten zu holen. Im folgenden Abschnitt erkläre ich das. Abruf-Modi Beachten Sie die Verwendung von PDO :: FETCHASSOC im Fetch () und FetchAll () Code oben. Dies teilt PDO mit, dass die Zeilen als assoziatives Array mit den Feldnamen als Schlüssel zurückgegeben werden. Es gibt auch viele andere Abruf-Modi, die ich eins nach dem anderen erklären werde. Zuerst erkläre ich, wie man den Abrufmodus auswählt: Im obigen hab ich fetch () benutzt. Sie können auch: PDOStatement :: fetchAll () - Gibt ein Array zurück, das alle Ergebnismengen enthält PDOStatement :: fetchColumn () - Gibt eine einzelne Spalte aus der nächsten Zeile einer Ergebnismenge zurück PDOStatement :: fetchObject () - holt die Nächste Zeile und gibt sie als Objekt zurück. PDOStatement :: setFetchMode () - Setzt den Standard-Abruf-Modus für diese Anweisung Jetzt komme ich zum Abruf-Modus: PDO :: FETCHASSOC. Gibt ein Array zurück, das durch Spaltenname indiziert wird, wie es in Ihrer Ergebnismenge zurückgegeben wird. PDO :: FETCHBOTH (Standard): gibt ein Array zurück, das von Spaltennamen und 0-indizierter Spaltennummer indiziert ist, wie in Ihrer Ergebnismenge zurückgegeben. Es gibt noch mehr Auswahlmöglichkeiten In PDOStatement Fetch Dokumentation. . Getting the row count: Anstatt mit mysqlnumrows die Anzahl der zurückgegebenen Zeilen zu erhalten, kannst du eine PDOStatement bekommen und rowCount () ausführen. Wie: Erste die eingefügte ID Einfügen und Aktualisieren oder Löschen von Anweisungen Was wir in der MySQL-Funktion machen ist: Und in pdo kann diese gleiche Sache getan werden durch: In der obigen Abfrage PDO :: exec führen eine SQL-Anweisung aus und gibt die Nummer zurück Der betroffenen Reihen. Einfügen und Löschen wird später abgedeckt. Die obige Methode ist nur dann sinnvoll, wenn Sie in der Abfrage keine Variable verwenden. Aber wenn du eine Variable in einer Abfrage verwenden musst, probier immer nicht wie die oben und dort für vorbereitete Aussage oder parametrisierte Aussage. Vorbereitete Aussagen Q. Was ist eine vorbereitete Aussage und warum brauche ich sie A. Eine vorbereitete Anweisung ist eine vorkompilierte SQL-Anweisung, die mehrmals ausgeführt werden kann, indem nur die Daten an den Server gesendet werden. Der typische Workflow der Verwendung einer vorbereiteten Aussage ist wie folgt (zitiert aus Wikipedia drei 3 Punkte): Vorbereiten. Die Anweisungsvorlage wird von der Anwendung erstellt und an das Datenbankmanagementsystem (DBMS) gesendet. Bestimmte Werte sind nicht spezifiziert, sogenannte Parameter, Platzhalter oder Bindungsvariablen (nachfolgend markiert): INSERT INTO PRODUCT (Name, Preis) VALUES (.) Das DBMS analysiert, kompiliert und führt die Abfrageoptimierung auf der Anweisungsvorlage aus und speichert das Ergebnis Ohne es auszuführen. Ausführen . Zu einem späteren Zeitpunkt liefert die Anwendung (oder bindet) Werte für die Parameter, und das DBMS führt die Anweisung (ggf. Rückgabe eines Ergebnisses) aus. Die Anwendung kann die Anweisung so oft ausführen, wie sie mit verschiedenen Werten will. In diesem Beispiel könnte es Brot für den ersten Parameter und 1,00 für den zweiten Parameter liefern. Sie können eine vorbereitete Anweisung verwenden, indem Sie Platzhalter in Ihre SQL einfügen. Es gibt grundsätzlich drei ohne Platzhalter (versuch nicht diese mit Variable seine oben), eine mit unbenannten Platzhaltern und eine mit benannten Platzhaltern. Q. Also jetzt, was sind Platzhalter und wie benutze ich sie A. Benannte Platzhalter. Verwenden Sie beschreibende Namen, denen ein Doppelpunkt vorausgeht, anstelle von Fragezeichen. Wir kümmern uns nicht um Positionsbestand des Wertes im Namen Platzhalter: Sie können auch mit einem Execute Array auch binden: Ein weiteres schönes Feature für OOP-Freunde ist, dass namhafte Platzhalter die Möglichkeit haben, Objekte direkt in Ihre Datenbank einzufügen, vorausgesetzt, die Eigenschaften entsprechen dem Namen Felder. Zum Beispiel: Q. Also jetzt, was sind unbenannte Platzhalter und wie benutze ich sie A. Lets haben ein Beispiel: Im obigen können Sie die sehen. Anstelle eines Namens wie in einem Namen Platzhalter. Im ersten Beispiel weisen wir den verschiedenen Platzhaltern Variablen zu (stmt-gtbindValue (1, name, PDO :: PARAMSTR)). Dann weisen wir diesen Platzhaltern Werte zu und führen die Anweisung aus. Im zweiten Beispiel geht das erste Arrayelement zum ersten. Und die zweite zur zweiten. HINWEIS . Bei unbenannten Platzhaltern müssen wir uns um die richtige Reihenfolge der Elemente im Array kümmern, die wir an die PDOStatement :: execute () - Methode übergeben. WÄHLEN. EINFÜGEN. AKTUALISIEREN. DELETE vorbereitete Abfragen Amine, nein, das ist nicht. Während NullPoite wirklich einen tollen Job gemacht hat, es zu schreiben, ist dies sicherlich nicht eine gute Lektüre, denn es ist viel zu lang. I39m ziemlich sicher, dass 8 von 10 Besuchern einfach überspringen wird. Und du hast auch eine Erklärung, weshalb diese Antwort nicht stimmt. Ein tldr Teil am Anfang wäre eine gute Idee, denke ich. Ndash trejder Jul 4 14 um 11:00 Zuerst beginnen wir mit dem Standardkommentar, den wir jedem geben: Bitte verwenden Sie keine MySQL-Funktionen im neuen Code. Sie werden nicht mehr beibehalten und sind offiziell veraltet. Siehe das rote Feld. Erfahren Sie über vorbereitete Aussagen stattdessen und verwenden Sie PDO oder MySQLi - dieser Artikel wird Ihnen helfen zu entscheiden, welche. Wenn du PDO wählst, hier ist ein gutes Tutorium. Lets gehen durch diese, Satz durch Satz, und erklären: Sie sind nicht mehr beibehalten, und sind offiziell veraltet Das bedeutet, dass die PHP-Community allmählich Unterstützung für diese sehr alten Funktionen fallen lässt. Sie sind wahrscheinlich nicht in einer zukünftigen (letzten) Version von PHP bestehen. Die fortgesetzte Nutzung dieser Funktionen kann Ihren Code in der (nicht so) weit Zukunft brechen. Neuere extmysql wurde in PHP 7 entfernt. Stattdessen sollten Sie von vorbereiteten Anweisungen lernen - mysql-Erweiterung unterstützt keine vorbereiteten Anweisungen. Was unter anderem eine sehr effektive Gegenmaßnahme gegen SQL Injection ist. Es behinderte eine sehr ernste Verwundbarkeit in MySQL-abhängigen Anwendungen, die es Angreifern ermöglicht, Zugriff auf Ihr Skript zu erhalten und jede mögliche Abfrage in Ihrer Datenbank durchzuführen. Wenn du auf eine mysql-Funktions-Manual-Seite gehst, siehst du eine rote Box und erklärst, dass sie nicht mehr benutzt werden sollte. Verwenden Sie entweder PDO oder MySQLi Es gibt bessere, robuster und gut aufgebaute Alternativen, PDO - PHP Database Object. Die einen vollständigen OOP-Ansatz für Datenbank-Interaktion und MySQLi bietet. Das ist eine MySQL-spezifische Verbesserung. Benutzerfreundlichkeit Die analytischen und synthetischen Gründe wurden bereits erwähnt. Für Newcomer theres ein wichtiger Anreiz, die Verwendung der veralteten MySQL-Funktionen zu stoppen. Zeitgenössische Datenbank-APIs sind einfacher zu bedienen. Es sind meist die gebundenen Parameter, die den Code vereinfachen können. Und mit hervorragenden Tutorials (wie oben gesehen) ist der Übergang zum PDO nicht zu schwierig. Umschreiben einer größeren Code-Basis sofort braucht aber Zeit. Raison dtre für diese Zwischen-Alternative: Äquivalente pdo-Funktionen anstelle von mysql Mit lt pdomysql. php gt können Sie von den alten mysql-Funktionen mit minimalem Aufwand wechseln. Es fügt pdo-Funktion Wrapper, die ihre MySQL-Pendants ersetzen. Einfach includeonce (pdomysql. php) in jedem Aufrufskript, das mit der Datenbank interagieren muss. Entfernen Sie die MySQL-Funktion Präfix überall und ersetzen Sie es mit pdo. () Mysql-Abfrage () wird zu pdo-Verschlüsselung () wird zu pdo-Umsetzer () wird zu pdo-Einfüllungen () wird zu pdo-Einfügung () wird pdo-Fetcharray () wird pdo fetcharray () mysql fetchassoc () wird Pdo fetchassoc () mysql realescapestring () wird pdo realescapestring () und so weiter. Dein Code wird gleich funktionieren und sieht meistens immer noch gleich aus: Et voil. Dein Code benutzt PDO. Jetzt ist es an der Zeit, es zu nutzen. Gebundene Parameter können einfach zu bedienen Sie brauchen nur eine weniger unhandliche API. Pdoquery () fügt sehr einfache Unterstützung für gebundene Parameter hinzu. Konvertieren von alten Code ist einfach: Verschieben Sie Ihre Variablen aus der SQL-Zeichenfolge. Füge sie als kommagetrennte Funktionsparameter zu pdoquery hinzu (). Stellen Sie Fragezeichen ein. Als Platzhalter, wo die Variablen vorher waren. Befreien Sie sich von einfachen Anführungszeichen, die zuvor String valuesvariables eingeschlossen haben. Der Vorteil wird für längere Code deutlicher. Häufig String-Variablen arent nur in SQL interpoliert, aber verkettet mit Escaping-Anrufe dazwischen. Mit. Platzhalter angewendet Sie haben nicht zu stören, dass: Denken Sie daran, dass pdo noch erlaubt entweder oder. Einfach nicht entkommen einer Variablen und binden sie in der gleichen Abfrage. Die Platzhalter-Funktion wird von der echten PDO hinter sich gestellt. So auch erlaubt: benannte Platzhalterlisten später. Noch wichtiger ist, dass Sie REQUEST-Variablen sicher hinter jeder Abfrage passieren können. Wenn gesendet ltformgt Felder entsprechen die Datenbank-Struktur genau seine noch kürzer: So viel Einfachheit. Aber lass uns zurück zu einigen mehr umschreibenden Ratschlägen und technischen Gründen, warum Sie vielleicht loswerden mysql und Flucht. Fix oder entfernen Sie alle oldschool sanitize () - Funktion Sobald Sie alle MySQL-Anrufe in pdoquery mit gebundenen Params umgewandelt haben, entfernen Sie alle redundanten pdorealescapestring Anrufe. Insbesondere sollten Sie irgendwelche sanitize oder saubere oder filterThis oder cleandata Funktionen wie beworben durch datierte Tutorials in einer Form oder der anderen zu beheben: Die meisten grellen Fehler hier ist der Mangel an Dokumentation. Noch deutlicher war die Reihenfolge der Filterung in genau der falschen Reihenfolge. Richtige Ordnung wäre gewesen: verarmte Streifen als der innerste Ruf, dann trimmen. Danach stripags Htmlentities für Output-Kontext, und nur endlich die escapestring als seine Anwendung sollte direkt vor der SQL-Intersparsing. Aber als ersten Schritt nur loszuwerden, die realescapestring rufen. Möglicherweise müssen Sie den Rest Ihrer sanitize () - Funktion für jetzt behalten, wenn Ihre Datenbank und Anwendungsfluss HTML-Kontext-sichere Strings erwarten. Fügen Sie einen Kommentar hinzu, dass es nur HTML-Escaping angewendet wird. Stringvalue Handling wird an PDO und seine parametrisierten Anweisungen delegiert. Wenn es irgendwelche Erwähnung von stripslashes () in Ihrer sanitize Funktion gibt, kann es eine höhere Niveauüberwachung angeben. Das war gewöhnlich dort, um Schaden (doppelte Flucht) von den veralteten magischen Zitaten zu beseitigen. Welches ist aber am besten zentral gelegt. Nicht String nach String Verwenden Sie einen der Userland Reversal Ansätze. Dann entfernen Sie die stripslashes () in der Sanitize-Funktion. Historische Anmerkung auf magicquotes. Das Merkmal ist zu Recht veraltet. Es ist oft falsch als fehlgeschlagene Sicherheitsmerkmal dargestellt. Aber Magicquotes sind so viel ein fehlgeschlagenes Sicherheitsmerkmal wie Tennisbälle als Nährstoffquelle versagt haben. Das war einfach nicht ihr Zweck. Die ursprüngliche Implementierung in PHP2FI eingeführt es explizit mit nur Anführungszeichen wird automatisch entkommen, so dass es einfacher, Formulare Daten direkt an msql Abfragen übergeben. Besonders war es versehentlich sicher mit mSQL zu verwenden. Da das nur ASCII unterstützt hat. Dann hat PHP3Zend Magicquotes für MySQL wieder eingeführt und es falsch dokumentiert. Aber ursprünglich war es nur eine Bequemlichkeit. Nicht für die Sicherheit beabsichtigen. Wie vorbereitete Aussagen unterscheiden Wenn Sie String-Variablen in die SQL-Abfragen scramble, wird es nicht einfach mehr kompliziert für Sie zu folgen. Es ist auch eine externe Anstrengung für MySQL, um Code und Daten wieder zu trennen. SQL-Injektionen sind einfach, wenn Daten in Code-Kontext bluten. Ein Datenbank-Server kann nicht später, wo PHP ursprünglich verklebte Variablen zwischen den Abfrage-Klauseln. Mit gebundenen Parametern trennen Sie SQL Code und SQL-Kontext-Werte in Ihrem PHP-Code. Aber es wird nicht wieder hinter den Kulissen geschluckt (außer bei PDO :: EMULATEPREPARES). Ihre Datenbank erhält die unveränderten SQL-Befehle und 1: 1 Variablenwerte. Während diese Antwort betont, dass Sie sich um die Lesbarkeit Vorteile von fallen lassen mysql. Theres gelegentlich auch ein Leistungsvorteil (wiederholte INSERTs mit nur unterschiedlichen Werten) aufgrund dieser sichtbaren und technischen Datacode Trennung. Hüten Sie sich, dass die Parameterbindung noch keine magische One-Stop-Lösung gegen alle SQL-Injektionen ist. Es behandelt die häufigste Verwendung für Datavalues. Aber Cant Whitelist Spalte Namen Tabelle Identifikatoren, Hilfe mit dynamischen Klausel Bau, oder einfach nur Array-Wert-Listen. Hybrid PDO Verwendung Diese pdo Wrapper Funktionen machen eine Codierung-freundliche Stop-Lücke API. (Sein ziemlich viel, was MYSQLI hätte sein können, wenn es nicht für die idiosynkratische Funktion Signatur Verschiebung). Sie setzen die echte PDO zu den meisten Zeiten aus. Rewriting muss nicht auf die Verwendung der neuen pdo-Funktionsnamen zu stoppen. Du kannst eins nach dem anderen jeden pdoquery () in einen einfachen pdo-prepare () - execute () call. Sein Bestes, um bei der Vereinfachung aber wieder zu beginnen. Zum Beispiel das gemeinsame Ergebnis holen: Kann mit nur einer foreach Iteration ersetzt werden: Oder besser noch eine direkte und vollständige Array-Retrieval: Youll erhalten mehr hilfreiche Warnungen in den meisten Fällen als PDO oder MySQL in der Regel nach fehlgeschlagenen Abfragen. Andere Optionen So hoffte dies hoffentlich einige praktische Gründe und einen lohnenden Weg, um MySQL zu fallen. Einfache Umstellung auf pdo macht es nicht ganz aus. Pdoquery () ist auch nur ein Frontend darauf. Sofern Sie auch keine Parameterbindung einführen oder etwas anderes aus der schöneren API nutzen können, ist es ein sinnloser Schalter. Ich hoffe, es ist einfach genug, um die Entmutigung für Neuankömmlinge nicht weiter zu verfolgen. (Bildung funktioniert in der Regel besser als Verbot.) Während es sich für die einfachste Sache - das-könnte-möglicherweise-Arbeit Kategorie, seine auch noch sehr experimentellen Code qualifiziert. Ich habe es nur über das Wochenende geschrieben. Theres eine Fülle von Alternativen aber Nur google für PHP-Datenbank Abstraktion und grasen ein wenig. Es gab immer viele ausgezeichnete Bibliotheken für solche Aufgaben. Wenn Sie Ihre Datenbank-Interaktion weiter vereinfachen möchten, sind Mapper wie ParisIdiorm einen Versuch wert. So wie niemand das langweilige DOM in JavaScript benutzt, muss man heute keine rohe Datenbankschnittstelle babysitten. Antwort vom 24. Dezember 13 um 23:30 Uhr Aus technischen Gründen, gibt es nur wenige, extrem spezifisch und selten verwendet. Wahrscheinlich wirst du sie niemals in deinem Leben benutzen. Vielleicht bin ich zu unwissend, aber ich hatte nie die Gelegenheit, sie Dinge wie non-blocking zu verwenden, asynchrone Abfragen gespeicherte Prozeduren, die mehrere Resultsets zurückgeben Verschlüsselung (SSL) Kompression Wenn du sie brauchst - das sind zweifellos technische Gründe, sich von mysql zu entfernen Erweiterung auf etwas stilvolles und modernes. Trotzdem gibt es auch einige nicht-technische Fragen, die Ihre Erfahrung ein bisschen härter weiter nutzen können diese Funktionen mit modernen PHP-Versionen werden verurteilt-Level-Notizen zu erhöhen. Sie können einfach ausgeschaltet werden. In einer fernen Zukunft können sie möglicherweise aus dem Standard-PHP-Build entfernt werden. Nicht eine große Sache auch, wie mydsql ext wird in PECL verschoben werden und jeder Hoster wird glücklich sein, PHP mit ihm zu verletzen, da sie nicht wollen, um Kunden zu verlieren, deren Standorte seit Jahrzehnten arbeiten. Starker Widerstand aus der Stackoverflow-Community. Sehr Zeit, die Sie diese ehrlichen Funktionen erwähnen, wird Ihnen gesagt, dass sie unter strengen Tabu sind. Ein durchschnittlicher PHP-Benutzer zu sein, wahrscheinlich ist Ihre Idee, diese Funktionen zu benutzen, fehleranfällig und falsch. Gerade wegen all dieser zahlreichen Tutorials und Handbücher, die dir einen falschen Weg lehren. Nicht die Funktionen selbst - ich muss es betonen - aber wie sie benutzt werden. Diese letztere Frage ist ein Problem. Aber meiner Meinung nach ist die vorgeschlagene Lösung auch nicht besser. Es scheint mir zu idealistisch ein Traum, dass alle diese PHP-Benutzer lernen, wie man SQL-Abfragen richtig auf einmal zu behandeln. Wahrscheinlich würden sie nur ändern mysql zu mysqli mechanisch, so dass der Ansatz das gleiche. Vor allem, weil mysqli macht vorbereiteten Aussagen Verwendung unglaublich schmerzhaft und lästig. Nicht zu erwähnen, dass native vorbereitete Aussagen arent genug, um vor SQL-Injektionen zu schützen, und weder mysqli noch PDO bietet eine Lösung. Also, anstatt diese ehrliche Erweiterung zu bekämpfen, bevorzugen Id, falsche Praktiken zu bekämpfen und Menschen auf die richtige Weise zu erziehen. Auch gibt es einige falsche oder nicht signifikante Gründe, wie Doesnt unterstützt Stored Procedures (wir waren mit mysqlquery (CALL myproc) für Altersgruppen) Unterstützt nicht Transaktionen (wie oben) unterstützt nicht mehrere Anweisungen (die sie benötigen) Nicht unter aktiver Entwicklung (Also was beeinflusst sie auf praktische Weise) Fehlt eine OO-Schnittstelle (um eine zu erstellen ist eine Frage von mehreren Stunden) Unterstützt nicht vorbereitete Aussagen oder parametrisierte Abfragen Ein letzteres ist ein interessanter Punkt. Obwohl mysql ext nicht native vorbereitete Aussagen unterstützen, sind sie für die Sicherheit erforderlich. Wir können leicht vorbereitete Aussagen mit manuell gehandhabten Platzhaltern (wie PDO tut): voila. Alles ist parametriert und sicher. Aber okay, wenn du den roten Kasten im Handbuch nicht magst, entsteht ein Problem der Wahl: mysqli oder PDO Nun, die Antwort wäre wie folgt: Wenn du die Notwendigkeit verstehst, eine Datenbank-Abstraktionsschicht zu verwenden. Und suche nach einer API, um eine zu schaffen, ist mysqli eine sehr gute Wahl, da es in der Tat viele mysql-spezifische Features unterstützt. Wenn, wie die meiste Mehrheit der PHP-Leute, Sie rohe API-Anrufe direkt im Anwendungscode verwenden (was im Wesentlichen falsche Praxis ist) - PDO ist die einzige Wahl. Da diese Erweiterung nicht nur API ist, sondern eher ein halb-DAL, noch unvollständig, sondern viele wichtige Features bietet, mit zwei von ihnen macht PDO kritisch von mysqli unterschieden: Im Gegensatz zu mysqli kann PDO Platzhalter nach Wert binden. Die dynamisch aufgebaute Abfragen macht, die ohne mehrere Bildschirme von ziemlich unordentlichem Code möglich sind. Im Gegensatz zu mysqli kann PDO immer das Abfrageergebnis in einem einfachen üblichen Array zurückgeben, während mysqli es nur bei mysqlnd-Installationen machen kann. Also, wenn Sie ein durchschnittlicher PHP-Benutzer sind und wollen Sie sich eine Tonne Kopfschmerzen bei der Verwendung von nativen vorbereiteten Aussagen, PDO - wieder - ist die einzige Wahl. Allerdings ist PDO auch keine Silberkugel und hat seine Nöte. So schrieb ich Lösungen für alle gängigen Fallstricke und komplexe Fälle im PDO-Tag-Wiki Dennoch, jeder, der von Erweiterungen spricht, fehlt immer die 2 wichtigen Fakten über Mysqli und PDO: Vorbereitete Aussage ist kein Silberkugel. Es gibt dynamische Identifikatoren, die nicht mit vorbereiteten Anweisungen gebunden werden können. Es gibt dynamische Abfragen mit unbekannter Anzahl von Parametern, die die Abfrage zu einer schwierigen Aufgabe macht. Weder mysqli noch PDO-Funktionen sollten im Anwendungscode erscheinen. Es sollte eine Abstraktionsschicht zwischen ihnen und Anwendungscode, die alle schmutzigen Job der Bindung, Schleifen, Fehlerbehandlung, etc. im Inneren, machen Anwendungscode TROCKEN und reinigen wird. Besonders für die komplexen Fälle wie dynamisches Abfragegebäude. Also, nur Umschalten auf PDO oder mysqli ist nicht genug. Man muss ein ORM oder einen Abfrage-Builder oder eine beliebige Datenbank-Abstraktionsklasse verwenden, anstatt rohe API-Funktionen in ihrem Code aufzurufen. Und im Gegenteil - wenn Sie eine Abstraktionsschicht zwischen Ihrem Anwendungscode und mysql API haben - es spielt keine Rolle, welcher Motor verwendet wird. Sie können mysql ext verwenden, bis es veraltet ist und dann einfach umschreiben Sie Ihre Abstraktion Klasse zu einem anderen Motor, mit allen Anwendungscode intakt. Hier sind einige Beispiele, die auf meiner Safemysql-Klasse basieren, um zu zeigen, wie eine solche Abstraktionsklasse sein sollte: Vergleichen Sie diese eine einzelne Zeile mit der Menge an Code, die Sie mit PDO benötigen. Dann vergleichen Sie mit verrückten Menge an Code, den Sie mit rohen Mysqli vorbereiteten Anweisungen benötigen. Beachten Sie, dass Fehlerbehandlung, Profilerstellung, Abfrageprotokollierung bereits eingebaut und ausgeführt wurde. Vergleichen Sie es mit üblichen PDO-Einsätzen, wenn jeder einzelne Feldname sechs - bis zehnmal wiederholt wird - in all diesen zahlreichen benannten Platzhaltern, Bindungen und Abfragedefinitionen. Sie können kaum ein Beispiel für PDO finden, um diesen praktischen Fall zu behandeln. Und es wird zu wortig und wahrscheinlich unsicher sein. Also, noch einmal - es ist nicht nur roher Fahrer sollte dein Anliegen sein aber Abstraktionsklasse, nützlich nicht nur für dumme Beispiele aus Anfänger-Handbuch, sondern um zu lösen, was auch immer echte Leben Probleme. Wie ist nicht unter aktiver entwicklung nur für das zusammengesetzt 390.0139 Wenn du etwas mit dieser Stand-Alone-Funktion baustest, aktualisier deine mysql-Version in einem Jahr und lade mit einem nicht funktionierenden System auf, ich bin sicher, dass es eine Menge ist Leute plötzlich in diesem 390.0139. Ich sage, dass veraltet und nicht unter aktiver Entwicklung eng verwandt sind. Sie können sagen, dass es Quittung würdig Grund für es ist, aber die Tatsache ist, dass, wenn eine Wahl zwischen den Optionen angeboten, keine aktive Entwicklung ist fast genauso schlimm wie veraltet I39d sagen ndash Nanne Feb 1 13 um 10:21 ShaquinTrifonoff: sicher, Es macht keine vorbereiteten Aussagen. Aber auch keine PDO. Welche die meisten Leute über MySQLi empfehlen. Also ich bin mir nicht sicher, dass das hier einen erheblichen Einfluss hat. Der obige Code (mit etwas mehr Parsing) ist das, was PDO tut, wenn man eine Anweisung standardmäßig vorbereitet. Ndash ircmaxell Diese Antwort wird geschrieben, um zu zeigen, wie trivial es ist, den schlecht geschriebenen PHP-Benutzer-Validierungscode zu umgehen, wie (und mit welchem) diese Angriffe arbeiten und wie man die alten MySQL-Funktionen durch eine sichere ersetzt Vorbereitete Aussage - und grundsätzlich, warum StackOverflow-Benutzer (vermutlich mit viel Rep) bei neuen Benutzern bellen, um Fragen zu stellen, um ihren Code zu verbessern. Zuerst aus, bitte fühlen Sie sich frei, diese Test-MySQL-Datenbank zu erstellen (ich habe meine Vorbereitung genannt): Damit können wir zu unserem PHP-Code wechseln. Nehmen wir an, dass das folgende Skript der Verifizierungsprozess für einen Admin auf einer Website ist (vereinfacht aber funktioniert, wenn Sie es kopieren und zum Testen verwenden): Scheint auf den ersten Blick legitim genug. Der Benutzer muss ein Login und Passwort eingeben, rechts Brilliant, geben Sie nicht in die folgenden: Die Ausgabe ist wie folgt: Super Arbeiten wie erwartet, jetzt können wir versuchen, die tatsächlichen Benutzernamen und Passwort: Amazing Hi-Fives rundum, der Code korrekt überprüft Ein admin Sein vollkommenes Gut, nicht wirklich. Lets sagen, der Benutzer ist ein kluger kleiner Mensch. Lets sagen, die Person ist mir. Geben Sie in die folgenden: Und die Ausgabe ist: Congrats, Sie erlaubte mir nur, Ihre super-geschützten Admins nur Abschnitt mit mir eingeben, um einen falschen Benutzernamen und ein falsches Passwort einzugeben. Im Ernst, wenn Sie mir nicht glauben, erstellen Sie die Datenbank mit dem Code, den ich zur Verfügung gestellt habe, und führen Sie diesen PHP-Code - was auf den Blick WIRKLICH scheint, den Benutzernamen und das Kennwort ziemlich schön zu überprüfen. Also, in der Antwort, DAS IST, WARUM SIE SELBST WERDEN. Also, lass uns einen Blick darauf werfen, was schief gelaufen ist und warum ich gerade in deine Super-Admin-Bat-Höhle gekommen bin. Ich habe eine Vermutung genommen und davon ausgegangen, dass du mit deinen Eingaben vorsichtig bist und sie einfach direkt an die Datenbank weitergegeben hast. Ich habe die Eingabe in einer Weise konstruiert, die die Abfrage, die du tatsächlich ausgeführt hast, Also, was sollte es sein, und was hat es am Ende Sein Das ist die Abfrage, aber wenn wir die Variablen durch die tatsächlichen Eingaben ersetzen, die wir verwendet haben, erhalten wir folgendes: Sehen Sie, wie ich mein Passwort so konstruiert habe, dass es zuerst wäre Schließe das einfache Zitat um das Passwort, dann stelle ich einen völlig neuen Vergleich vor Dann gerade für die Sicherheit, fügte ich einen anderen String hinzu, damit das einzelne Zitat wie erwartet in dem Code, den wir ursprünglich hatten, geschlossen wurde. Allerdings ist dies nicht über Leute schreien bei Ihnen jetzt, dies ist über zeigt Ihnen, wie Sie Ihren Code sicherer machen. Okay, also was ist schief gelaufen und wie können wir es beheben Dies ist ein klassischer SQL-Injection-Angriff. Eines der einfachsten für diese Angelegenheit. Auf der Skala der Angriffsvektoren ist dies ein Kleinkind, das einen Panzer angreift und gewinnt. Also, wie schützen wir euren heiligen Admin-Bereich und machen es nett und sicher Das erste, was zu tun ist, wird aufhören, diese wirklich alten und veralteten MySQL-Funktionen zu verwenden. Ich weiß, du folgst einem Tutorial, das du online gefunden hast und es funktioniert, aber sein altes, sein veraltetes und in wenigen Minuten bin ich nur an ihm vorbeigegangen, ohne so viel wie ein Schweiß zu brechen. Jetzt haben Sie die besseren Möglichkeiten der Verwendung von mysqli oder PDO. Ich bin persönlich ein großer Fan von PDO, also werde ich PDO in den Rest dieser Antwort verwenden. Es gibt Vor-und Nachteile, aber persönlich finde ich, dass die Profis weit überwiegen die Nachteile. Es ist tragbar über mehrere Datenbank-Engines - ob Sie mit MySQL oder Oracle oder nur über blutige alles - nur durch die Änderung der Verbindung String, hat es alle fancy Features, die wir verwenden möchten und es ist schön und sauber. Ich mag sauber. Nun können wir diesen Code noch einmal anschauen, diesmal mit einem PDO-Objekt geschrieben: Die großen Unterschiede sind, dass es keine weiteren MySQL-Funktionen gibt. Es geht alles über ein PDO-Objekt, zweitens ist es eine vorbereitete Anweisung. Nun, was ist eine vorbereitete Aussage, die Sie fragen, ist ein Weg, um die Datenbank vor dem Ausführen einer Abfrage zu erzählen, was die Abfrage ist, dass wir laufen werden. In diesem Fall sagen wir der Datenbank: Hallo, ich werde eine ausgewählte Anweisung ausführen, die id, userid und pass von den Tabellenbenutzern, wo die userid eine Variable ist und der Pass auch eine Variable ist. Dann in der execute-Anweisung , Übergeben wir der Datenbank ein Array mit allen Variablen, die es jetzt erwartet. Die Ergebnisse sind fantastisch. Lets versuchen, diese Benutzernamen und Passwort-Kombinationen von vor noch einmal: Benutzer wurde nicht überprüft. Genial. Oh, I just got a little excited, it worked: The check passed. We have a verified admin Now, lets try the data that a clever chap would enter to try to get past our little verification system: This time, we get the following: This is why you are being yelled at when posting questions - its because people can see that your code can be bypassed wihout even trying. Please, do use this question and answer to improve your code, to make it more secure and to use functions that are current. Lastly, this isnt to say that this is PERFECT code. There are many more things that you could do to improve it, use hashed passwords for example, ensure that when you store sensetive information in the database, you dont store it in plain text, have multiple levels of verification - but really, if you just change your old injection prone code to this, you will be WELL along the way to writing good code - and the fact that you have gotten this far and are still reading gives me a sense of hope that you will not only implement this type of code when writing your websites and applications, but that you might go out and research those other things I just mentioned - and more. Write the best code you can, not the most basic code that barely functions. answered Sep 18 13 at 12:28 Because (amongst other reasons) its much harder to ensure the input data is sanitized. If you use parametrized queries, as one does with PDO or mysqli you can entirely avoid the risk. As an example, some-one could use enhzflep) drop table users as a user name. The old functions will allow executing of multiple statements per query, so something like that nasty bugger can delete a whole table. If one were to use PDO of mysqli, the user-name would end-up being enhzflep) drop table users The old functions will allow executing of multiple statements per query - no, they won39t. That kind of injection is not possible with extmysql - the only way this kind of injection is possible with PHP and MySQL is when using MySQLi and the mysqlimultiquery() function. The kind injection that is possible with extmysql and unescaped strings is things like 39 OR 39139 391 to extract data from the database that was not meant to be accessible. In certain situations it is possible to inject sub queries, however it is still not possible to modify the database in this way. ndash DaveRandom Dec 30 12 at 20:58 The MySQL extension is the oldest of the three and was the original way that developers used to communicate with MySQL. This extension is now being deprecated in favor of the other two alternatives because of improvements made in newer releases of both PHP and MySQL. MySQLi is the improved extension for working with MySQL databases. It takes advantage of features that are available in newer versions of the MySQL server, exposes both a function-oriented and an object-oriented interface to the developer and a does few other nifty things. PDO offers an API that consolidates most of the functionality that was previously spread across the major database access extensions, i. e. MySQL, PostgreSQL, SQLite, MSSQL, etc. The interface exposes high-level objects for the programmer to work with database connections, queries and result sets, and low-level drivers perform communication and resource handling with the database server. A lot of discussion and work is going into PDO and its considered the appropriate method of working with databases in modern, professional code. answered Sep 2 15 at 7:20 I find the above answers really lengthy, so to summarize: The mysqli extension has a number of benefits, the key enhancements over the mysql extension being: Object-oriented interface Support for Prepared Statements Support for Multiple Statements Support for Transactions Enhanced debugging capabilities Embedded server support As explained in the above answeres, the alternatives of mysql are mysqli and pdo. API supports server-side Prepared Statements. Supported by MYSQLi and PDO API supports client-side Prepared Statements. Supported only by PDO API supports Stored Procedures. Both MySQLi and PDO API supports Multiple Statements and all MySQL 4.1 functionality - Supported by MySQLi and mostly also by PDO Both MySQLi and PDO where introduced in PHP5.0, whereas MySQL was introduced prior to PHP3.0. A point to note is MySQL is included in PHP5.x though deprecated in later versions. A full-text index in MySQL is an index of type FULLTEXT. Full-text indexes can be used only with InnoDB or MyISAM tables, and can be created only for CHAR. VARCHAR. or TEXT columns. As of MySQL 5.7.6, MySQL provides a built-in full-text ngram parser that supports Chinese, Japanese, and Korean (CJK), and an installable MeCab full-text parser plugin for Japanese. Parsing differences are outlined in Section 13.9.8, ngram Full-Text Parser. and Section 13.9.9, MeCab Full-Text Parser Plugin. A FULLTEXT index definition can be given in the CREATE TABLE statement when a table is created, or added later using ALTER TABLE or CREATE INDEX. For large data sets, it is much faster to load your data into a table that has no FULLTEXT index and then create the index after that, than to load data into a table that has an existing FULLTEXT index. Full-text searching is performed using MATCH(). AGAINST syntax. MATCH() takes a comma-separated list that names the columns to be searched. AGAINST takes a string to search for, and an optional modifier that indicates what type of search to perform. The search string must be a string value that is constant during query evaluation. This rules out, for example, a table column because that can differ for each row. There are three types of full-text searches: A natural language search interprets the search string as a phrase in natural human language (a phrase in free text). There are no special operators. The stopword list applies. For more information about stopword lists, see Section 13.9.4, Full-Text Stopwords. Full-text searches are natural language searches if the IN NATURAL LANGUAGE MODE modifier is given or if no modifier is given. For more information, see Section 13.9.1, Natural Language Full-Text Searches. A boolean search interprets the search string using the rules of a special query language. The string contains the words to search for. It can also contain operators that specify requirements such that a word must be present or absent in matching rows, or that it should be weighted higher or lower than usual. Certain common words (stopwords) are omitted from the search index and do not match if present in the search string. The IN BOOLEAN MODE modifier specifies a boolean search. For more information, see Section 13.9.2, Boolean Full-Text Searches. A query expansion search is a modification of a natural language search. The search string is used to perform a natural language search. Then words from the most relevant rows returned by the search are added to the search string and the search is done again. The query returns the rows from the second search. The IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION or WITH QUERY EXPANSION modifier specifies a query expansion search. For more information, see Section 13.9.3, Full-Text Searches with Query Expansion. For information about FULLTEXT query performance, see Section 9.3.4, Column Indexes. For more information about InnoDB FULLTEXT indexes, see Section 15.8.10, InnoDB FULLTEXT Indexes. The myisamftdump utility dumps the contents of a MyISAM full-text index. This may be helpful for debugging full-text queries. See Section 5.6.2, myisamftdump Display Full-Text Index information. Posted by Dyfed Lloyd Evans on October 21, 2002 Hyphen 039-039 characters break literals at the moment. A search for something like quotGATA-D22S690quot finds all entries containing GATA and not the full hyphenated text. The 039-039 character is treated as a word stop even within literals. The same is true if any of the special text search modifiers are used (eg found with full text searches. Posted by Patrick O039Lone on December 9, 2002 It should be noted in the documentation that IN BOOLEAN MODE will almost always return a relevance of 1.0. In order to get a relevance that is meaningful, you039ll need to: ltBRgtltBRgt SELECT MATCH(039Content039) AGAINST (039keyword1 keyword2039) as Relevance FROM table WHERE MATCH (039Content039) AGAINST(039keyword1 keyword2039 IN BOOLEAN MODE) HAVING Relevance gt 0.2 ORDER BY Relevance DESC ltBRgtltBRgt Notice that you are doing a regular relevance query to obtain relevance factors combined with a WHERE clause that uses BOOLEAN MODE. The BOOLEAN MODE gives you the subset that fulfills the requirements of the BOOLEAN search, the relevance query fulfills the relevance factor, and the HAVING clause (in this case) ensures that the document is relevant to the search (i. e. documents that score less than 0.2 are considered irrelevant). This also allows you to order by relevance. ltBRgtltBRgt This may or may not be a bug in the way that IN BOOLEAN MODE operates, although the comments I039ve read on the mailing list suggest that IN BOOLEAN MODE039s relevance ranking is not very complicated, thus lending itself poorly for actually providing relevant documents. BTW - I didn039t notice a performance loss for doing this, since it appears MySQL only performs the FULLTEXT search once, even though the two MATCH clauses are different. Use EXPLAIN to prove this. Posted by Nathan Ostgard on April 14, 2003 An easy solution to correct for spelling errors for small search items like the name of the city is to build a column that contains the SOUNDEX of each. I039ve found that using a 4 character SOUNDEX works the best. An example: ALTER TABLE cities ADD citysoundex VARCHAR(4) NOT NULL UPDATE cities SET citysoundexLEFT(SOUNDEX(cityname),4) And then to query against: SELECT FROM citites WHERE citysoundexLEFT(SOUNDEX(039Some City Name039),4) Posted by Jim Nguyen on June 18, 2003 The full-text search is slow when there are a lot of rows in the table. I have more than 2 million rows with text and multiple word searches (3 or more) take about 30 seconds to a minute or longer. I am running a Athlon 2.2 Ghz with 512 MB DDR RAM 400 Mhz. Hard drive has seek time of 9 ms. Posted by Alan Riley on July 14, 2003 We too have a database with close to 6 million rows in it. We would like to use the fulltext search, but it is painfully slow. The sad thing is that any one query we need to run only needs to be run on a subset of the rows (think of those 6 million rows as being divided between about 80 different categories, with results only needed to be returned from within a category). It is a shame that there isn039t some way for us to have a fulltext index within the rows of another column which is also indexed. Our next shot at this is going to be to create 80 different tables, one for each category (yuck), just to try to get decent performance on the within-category fulltext search. I would think there is enough interest in fulltext search for there to be an email list dedicated to it where those of us who need to use it on real-world web sites could interact with the developers to try to tune it for the good of the community at large. Posted by Donal McMullan on September 24, 2003 The nature of fulltext indexing is such that the more 039words039 (of greater than the minimum length) that appear in the columns you index, the greater will be size of the index, and the time it takes to create and search that index. 4 Million rows x 6 words per row 24 Million entries 4 Million rows x 30 words per row 120 Million entries If you index intelligently, you may well find that the feature meets your needs, despite what some users may have remarked above. quotNumber of rowsquot is useless as a benchmarking statistic on its own. Posted by Erlend Strmsvik on October 23, 2003 I039ve got a webshop running with mysql. We have 1.6 million booktitles in our database, and our fulltext index is from title and 039extra039 title. Maybe around 5-7 words on average per record. Any fulltext search in our database takes around 1-5ms. A three word search can take a few seconds but still faster than anything else. Even Amazon. This is from our main server which has several thousand hits every day. We are one of the biggest booksellers in my country. - This was in 039reply039 to someone posting earlier about poor performance in 039real world situation039. Posted by Jerome C on December 3, 2003 We have a vast database of products (totaling 3 million rows). The rebuild of the full-text index took 21 minutes to complete. As for the search, a multiple word search on the full-text index of 1 field is as follows: 20 rows returned Query took 1.0263 sec The size of the index is very big though. Index 449,529 KB We are going to eliminate unnecessary words which should make the index smaller. Posted by Ben Margolin on December 19, 2003 The indexing process definitely depends on your machine config. I indexed the same dataset, same mysql version (4.0.16, - standard on Linux, - nt on XP). First machine: a 512M Athlon 2100 running WinXP on a RAID1 array, and it took 9 mins 20 sec. Second machine: 1G RAM P4-2.0ghz, running Linux 7.3 (2.4.20-13.7 kernel), one-spindle (but fast) IDE disk, and it took 29 mins 11 sec. The query was quotalter table msgbodies add fulltext ftibodies (subject, body)quot, and the dataset is about 550M, 1.3 million rows. Both machines were mostly idle when the indexing occurred. I know it039s just anecdotal, but if you run a big alter as I did, don039t be surprised if it takes a while. oh yeah, and then be prepared for MUCH longer than normal insert times when you add large data to the FT indexed columns. This makes sense of course, but, at least on my dataset and hardware, is positively NOT neglible. FYI. Posted by Jeffrey Yuen on February 2, 2004 Full text searching in 4.1.1 For Chinese charset in UTF-8 encoding. It needed to set ftminwordlen 1 Posted by Eric Jacolin on February 4, 2004 (MySQL 4.1) To make FULLTEXT MATCH work with Japanese UTF-8 text, be careful that words from your Japanese text be separated by the ASCII space character, not Japanese UTF-8 (or other) spacing characters. (when using phpMyAdmin to manage data write a SQL query, you must switch away from your Japanese IME to insert a space char. ) Posted by Tom Cunningham on February 5, 2004 Tom039s fulltext tips: To get MySQL searching well for me I did: 1. Have a normalized versions of the important columns: where you039ve stripped punctuation and converted numerals to words (0391039 to 039one039). Likewise normalise the search string. 2. Have a combined fulltext index on your searchable columns to use in your 039WHERE039 clause, but then have separate fulltext indexes on each column to use in the 039ORDER BY039 clause, so they can have different weights. 3. For the scoring algorithm, include the independent importance of that record, and include a match of the inclusive index against stemmed versions of the search words (as: quotweddingquot gt quotwedquot, quotweddingsquot). 4. If there039s exactly one result, go straight to that record. 5. If you get no results, try matching against the start of the most important column (WHERE column LIKE 039term039), and put a 5-character index on that column. This helps if someone is searching on a very short word or a stopword. 6. Reduce minimum word length to 3, and make a new stopwords list just using quota an and the is in which we you to on this by of withquot. Use quotREPAIR TABLE xxx QUICKquot to rebuild the index and make a note of the index-file (xxx. MYI) size before and after you make changes. Then use ftdump to tune. Posted by Attila Nagy on April 19, 2004 More about performance: Fulltext search in MySQL isn039t slow really. It039s slower than normal index selects, but that039s not noticable. I039m playing tables that each contains ca 4million records, about 6GB of text that needs to be indexed. The problem lies in the optimization of the queries, that use the MATCH() and AGAINST() functions. So far as I found out MySQL can use in a query only one index. The optimizer looks for the index that will possibly give the smallest amount of rows, then goes trough all of these, and removes those records, that fall out because of the other WHERE statements. When you enter a fulltext search, the server has to use that index. Any other statments could be applied only to the rows that were returned by the search. If you have lots of records, most of the searches will return lots of results. The rest of your query will be executed like if you were executing it against a table that contains the results, and no indexes - obviously that will be processed sequentially. Same thing applies when you use the SQLCALCFOUNDROWS, or LIMIT with high offset values: first the server has to load all the results, then the limit could be applied. If you have to use the fulltext, these are some hints how you could get quite good results: - Try to avoid any group, where, order and any statements for what it039s necessary to get all the results. I know, usually this is impossible. - If you need to show the results on a web page, try to find other methods to get the total number of results than using SQLCALCFOUNDROWS. Better if you don039t tell the user at all how many results there are ) - If indexing text that is in other language than english, before doing anything create a stopword file for your language (That could reduce index size about 30) But most important: think a lot, before you decide to use fulltext search Posted by Peter Dunham on April 22, 2004 We are doing fulltext searches of around 200 tables of 14 -12 million rows each. Upgrading a twin cpu 2Ghz linux machine (running ES 3) from 1GB to 3GB RAM and increasing keybuffersize from 384MB to 512MB has seen load averages go from 1.5-2 to around 0.5, with same usage. Posted by Peter Grigor on May 29, 2004 I039m not sure I agree with your comment that Mysql always uses a fulltext index if you include match. against. I tried a sample query where I used match. against and another value in the where clause (on the primary keyed field) and Mysql039s optimizer picked the primary key index. The statement looked like quotselect something from sometable where match(col1, col2) against (039some text here039) and pkcol 44 Posted by JT Johnston on July 1, 2004 dev. mysqldocmysqlenFulltextBoolean. html states you cannot do a full-text search in Boolean Mode by relevancy. You can, but you need mysql version 4. Take note of quotORDER BY relevancy DESCquot. Here is my codeexample: SELECT, MATCH (YR, AU, ST, SD, SC, BT, BD, BC, AT, AD, AC, JR, KW, AUS, GEO, AN, RB, CO, RR) AGAINST (039Margaret Atwood039 IN BOOLEAN MODE) AS relevancy FROM cclmain WHERE MATCH (YR, AU, ST, SD, SC, BT, BD, BC, AT, AD, AC, JR, KW, AUS, GEO, AN, RB, CO, RR) AGAINST (039Margaret Atwood039 IN BOOLEAN MODE) ORDER BY relevancy DESC Posted by James Day on August 19, 2004 See The Full-Text Stuff That We Didn039t Put In The Manual at dev. mysqltech-resourcesarticlesfull-text-revealed. html for more information about full-text search. Posted by James R on August 31, 2004 Thought some benchmarks for a very large data set might be useful to people. I created a full-text index on a 100 gig database, where the index was on a column where the data totals 3 gig. The index added 2 gig to the database. The database has 2,741,000 records. The textual content is technical literature in US English. Machine: The machine is an Athlon XP 3200 w 1 gig RAM, one drive for the OS, and another 250GB EIDE drive for the MySQL data. OS is Redhat 9. Index creation: 3 hours 5 min. Most of that time was probably copying the table (since MySQL copies the table before it modifies it). The process was definitely disk-limited -- CPU usage was never regularly above 50. I believe that were it not for the excess data to copy, the index creation would have taken about 45 minutes. Queries were chosen to compare rare words, common words, and words of different lengths. All queries seemed to be disk-limited (CPU utilization hardly moved off baseline), which makes sense given that there is not enough RAM to hold the index in memory. All queries were done mutiple times and the average time reported. Results follow. Word, Rows, Seconds, SecondsRow ---------------------------------------- bilobed, 4, 0.15, 0.0375 mends, 4, 0.19, 0.0475 nanotechnology, 23, 0.64, 0.0278 bioluminescent, 53, 1.53, 0.0289 photosynthesis, 81, 2.21, 0.0273 graphite, 5070, 123.00, 0.0243 bicycle, 5385, 122.00, 0.0227 titanium, 13503, 350.00, 0.0259 (titanium, graphite), 18423, 425.00, 0.0231 metal, 151095, 4020.00, 0.0266 This is just a small test on the way to indexing the full 100 gig in the database that I am working on for freepatentsonline. I039ll post results for that once I have a new server built. Posted by noel darlow on September 3, 2004 In reply to Patrick O039Lone039s post, above: The first, non-boolean MATCH can039t keep pace with the second, boolean one since it does not recognise the boolean operators. A search for foo might turn up rows with foo, foobar, foofighters, etc but the non-boolean, relevance MATCH can039t quotcountquot anything except foo. Same problem with a phrase search. Since effectively you can039t use boolean operators in the second, boolean MATCH, it039s rendered pointless. Results could be post-processed with your own ranking algorithm but it039s kind of odd that you can039t do a boolean search AND rank results in the query. Posted by Dave M on September 12, 2004 Those looking to simply match a search phrase in a large group of words, try this: SELECT FROM data WHERE haystack LIKE (039needle039) AND haystack RLIKE 039:lt:needle:gt:039 This query will produce the same result as the following query, but is roughly 20X faster. SELECT FROM data WHERE haystack RLIKE 039:lt:needle:gt:039 For more than one word use: haystack LIKE (039word1word2039) AND haystack RLIKE 039:lt:word1:gt:.:lt:word2:gt:039 Posted by James Day on September 26, 2004 The Wikipedia encyclopedia uses MySQL boolean full text search and MySQL 4.0.20. You can assess the speed yourselves. About 350,000 articles rows in the English language version, roughtly 5GB total. For all languages, one million articles and 10GB of text. It039s very important to have a sufficiently large keybuffersize. Get much of the index in RAM and searches are typically very fast. Because we use InnoDB tables and can039t share cache between InnoDB and MyISAM, we039re moving to a setup which will use a dedicated and MyISAM tuned search server. We run a slow query killer which will kill queries once their allowed time expires. That time depends on server load (active thread count). Documented at wp. wikidevQuerybane It turns out that our current search often spends most time on things other than full text search - an improved version which is much more efficient is pending. Remember that you can use a self join to get around the one index per query limit of MySQL. Search remains our most problematic load feature, requiring a couple of quite capable slaves to keep up at busy time. If we039re working on the servers and the remainder can039t handle the load, we switch to Google or Yahoo search. This is from one of the top few hundred sites on the net, so it039s scaling pretty well for our application. One server was sufficiently fast to take us to the top 1,000. Posted by Andrew Panin on October 7, 2004 Hi all I had a problem with FULLTEXT search and after I solved it, I want to try to help you. I thought that FULLTEXT search is slow. That was. But I did a simple trick: 1. For example, we have 4 tables with fulltext index. We need to perform fast search on them. 2. Do the following: CREATE TEMPORARY TABLE xxx SELECT id, name, MATCH(name) AGAINST (039searchstring039) AS relevancy FROM table1 INSERT INTO xxx SELECT id, name, MATCH(name) AGAINST (039searchstring039) AS relevancy FROM table2. 3. Then, when the temporary table is filled with the data, do the simple select from it: SELECT id, name FROM xxx ORDER BY relevancy DESC I think, it is the optimal way to make a VERY FAST fulltext search from a number of tables. I hope, this will be helpful. Posted by Dennis van den Ende on December 27, 2004 Allthough my fulltext serach works fine, i still have problems with it. i compare products with there prices. i used the quotrelevancequot idea (written above). But it will not recognize it correctly. Heres my query: SELECT , MATCH( field ) AGAINST (039blabla039) as relevance FROM table WHERE MATCH( field ) AGAINST (039blabla039 IN BOOLEAN MODE ) HAVING relevance gt 0.2 for example it finds 18 rows. to increase the rows, i checked (manuelly) the relevance. 3 above 18 (all 18.xxx) and the rest about 10.3 or lower. If i increase the quothavingquot to 15, it finds only 2 of 3. The field i use is the only index-field and ofcourse a fulltext specific field. it seems that the relevance is taking part of the search results. i am still looking for another idea but the relevance would cover my needs 100 update I just updated the mysql version from 4.0.15 to 4.1.8 and it works perfectly. Posted by Mauricio Wolff on February 4, 2005 to set up minlen and stopwordfile in windows (win2k or xp): 1. run services. msc to check what. ini your mysql is reading (in my case, quotC:MySQLbinmysqld-ntquot --defaults-filequotC:MySQLmy. iniquot MySQL) 2. change your my. ini like this: mysqld ftminwordlen3 ftstopwordfilequotC:MySQLstop. txtquot 3. restart your mysqld at services. msc 4. reindex your table using REPAIR TABLE tblname QUICK Posted by Peter Laursen on April 28, 2005 it is legal to use two different arguments with the quotdouble match constructionquot, i. e. select . match (artist, album, title) against (039blues in orbit039) from musicfiles where match (artist, album, title) against (039ellington039) will FIND all records with 039ellington039 as substring of artist, album or title, but will RATE them as the search match039es 039blues in orbit039 You can even. ORDER BY or GROUP BY MATCH (kunstner, albumtitel, titel) AGAINST (039prelude to a kiss039). or against anything else Posted by Grant Harrison on June 9, 2005 Maybe a little off topic here. Alternatively, instead of doing all full-text search within MySql database, you can pull data out and create an index on it. It039s a much faster search. I am using DBSight to search on 1.7million records of 1.2G data, on a P3 450MHz, 256MRam, with sub-second performance. Taking search out of database also give you capability to customize stemmer and query parser. Posted by Erik Petersen on July 13, 2005 When using FULLTEXT queries on large set data sets it039s critical to LIMIT your results. Doing some experimentation has made this very clear. Using a data set of 5.5 million rows of forum message posts indexed with a single FULLTEXT index: select id, match(post) against(039foo039) as score from messages where match (body) against( 039foo039 ) . 155323 rows in set (16 min 7.51 sec) select id, match(post) against(039foo039) as score from messages where match (body) against( 039foo039 ) limit 100 . 100 rows in set (1.25 sec) I ran a number of other tests on various terms known to be in the text with similar results. These were run in reverse order shown. Make sure you return only the rows you need or you will suffer. For a search engine application returning pages of results keep in mind that nobody is going to ever see page 74 Cap the results to a reasonable maximum trading response time for completeness where possible. Posted by kim markegard on August 25, 2005 In regards to Dyfed Lloyd Evans comment, I believe that quot. quot will also cause this which is unfortunate because we have product name acronyms we039d like to seach. Posted by Nathan Huebner on October 29, 2005 After tons of hours today working on this, I HAVE FINALLY MASTERED THE TECHNIQUE OF USING THIS THING. This query is what you send to your MySQL to return the results. I put the LIMIT so that you don039t overflow. queryretquotSELECT ProductID, Title, Description, Price, RetailPrice, MATCH (Title) AGAINST (039keyword039) AS score FROM server. book HAVING score gt 0 LIMIT start, maxretquot This query will COUNT the number of rows it found. (I believe that039s correct), I don039t believe it counts occurrences, just rows. I saw that if you pull back without a LIMIT above, and count that way, it039s 100000x slower. So do your count like this: querycountquotSELECT count(MATCH(Title) AGAINST(039keyword039)) AS score FROM server. book WHERE MATCH (Title) AGAINST (039keyword039) HAVING score gt 0quot Make sure you have your Primary Key setup, your Title and Description as SEPARATE FULLTEXT INDEXES. I spent a few hours boggling over this. Posted by Saqib Aziz on November 24, 2005 There is no way to perdict what maximum relevance rank could be. While working with full text searches one may want to show percentages as the criteria for indicating how close a particular record was to the search query. To achieve this, one way is to select the maximum relevance rank or score and then use it( as a denominator ) with every single record score to get percentage equivalent of score. For the sake of example, consider we have 6 as maximum rank and 2,3,4.234 are scores for three different records. Now to get percentage we have to do simple maths i. e. we can divide each score by 6(max rank) and then mulitply the result with 100. Hope this helps someone. Posted by Nathan Huebner on January 12, 2006 Tips on how to maximize performance, and minimize return time. Let me guess: you have a lot of data, and you went ahead and FULLTEXT indexed a column within that large pile of data. To put it in simple words: not cool. How long does your data take to return from a FULLTEXT search. 5 seconds More If you039re returning data under 3 seconds, then you039re ok, but if you want it to return in 1.3 seconds, here039s what I did. 1. Dont fulltext index a column within a huge table. Instead, take a Unique Identifier, and the text you039re searching, and copy it to another table. Use this to export your columns: SELECT uniquecolumn, mytextsearchcolumn FROM mydatabase. mytable INTO OUTFILE quotc:pathoutfile. txtquot That will export your data to a file in Tab Delimited format. Now, create a new table somewhere, and call it fulltextengine or something, with only 2 columns (less is better), you could add one more if you need to. Now import your data: LOAD DATA INFILE quotc:pathoutfile. txtquot IGNORE INTO TABLE mydatabase. fulltextengine Now, create your FULLTEXT index on your search field. Groß. Now you have a separate table for searching. So if you want to try it out, go into MySQL, and try this, or PHPmyAdmin: SELECT SQLCALCFOUNDROWS uniquecolumn, searchcolumn, MATCH (searchcolumn) AGAINST (039Keyword Goes Here039) AS score FROM mydatabase. fulltextengine HAVING score gt 0 Hope this helps It may add extra maintenance, but I will give up my soul to increase search speeds by 6x. Posted by Joe Soap on July 11, 2006 Not sure if this is useful for people trying to reduce their search dataset. But what I039m doing is preprocessing the text before I add it to the database. So I add the full text to my FileData column, but I also preprocess the text and put this processed text into a Keywords column. Then I search only the keywords column and never the full text. This technique obviously (you039ll see why) doesn039t work for phrase matching but it may speed up the search time by reducing the size of the dataset to search. Here039s the algorithm I use. 1. extract the text 2. count each word of 2 or more characters in the text and record the frequency that each occurs 3. from this list of words 2 or more characters long, remove the k (k currently 500) most common words in the english dictionary 4. sort the list so that the most frequently occurring words appear first 5. take the first n words as the final keywords, where n gt 0 and n lt the total number of remaining words Posted by Tasuku SUENAGA on July 30, 2006 If you have performance problems on fulltext search, Please try Senna, fulltext search engine that can be embedded in MySQL. qwik. jpsenna Original MySQL fulltext search is slow for query SELECT COUNT() or SELECT FROM xx LIMIT largenumber, x. These queries are very fast with Senna039s 2ind patch. Posted by Gary Osborne on August 19, 2006 I039m not convinced that stop-words are of great value. Sure, they might reduce the size of the index and speed-up queries for some kinds of databases. But there are two fundamental flaws with quotmandatoryquot stop-words. Firstly, without knowing in advance the nature of the data, how can any programmer proclaim to know which words should be excluded because they have no value Secondly, if a user includes any stop word in a search query, then by definition that word039s value can not be zero. If the word039s value was zero, then why would the user use it in a search query If you need to disable stop-words without re-compiling, consider appending a character to the end of each word in your text before inserting your text into the database. I used quotqquot. I also right-padded all words shorter than 4 characters to a length of 4 characters by appending quotqquots. And I appended a quot quot to the end of my text string before inserting into the database. After retrieving my text from the database, I did a global replace on my text. I changed quotqqqquot to quotquot, quotqqquot to quotquot, and quotq quot to quot quot - in that order - to restore the text to it039s original form. That was not the best solution but it worked. Luckily for me, my text was simply a space delimited list of words without and punctuation. Otherwise, my quotqquot encoding and decoding would have been more difficult. Posted by Sebastian Alberoni on September 27, 2006 Combining MATCH with MAX, GROUP BY and ORDER BY can be of a lot of help when retrieving results in the correct order regarding relevance. For example, using this I could solve a problem with one table called 039Professional039, which had a many-to-many reference to another table 039Profession039. Although I was using DISTINCT I was getting duplicate results because of different relevance values that MATCH was giving to the different entrances in 039Professions039. Here I am copying the final query that worked OK (it039s a bit simplified): select distinct p. idProfessional, MAX(MATCH (pssion. name, pssion. description) AGAINST (039string to search039)) as professionRanking FROM professional p, professionalprofession pp, profession pssion WHERE pp. ProfessionalidProfessional p. idProfessional AND pp. ProfessionidProfession pssion. idProfession and ( MATCH (pssion. name, pssion. description) AGAINST (039string to search039) GROUP BY p. idProfessional ORDER BY professionRanking DESC Posted by Miguel Velilla meucat on May 20, 2007 The truth behind fulltext search, is that MySql first split text into single words, then indexes isolated words pointing to records. These are logical steps that many of us previously had tried before MySql fulltext commands creation. I created a PHP program some years ago to perform exactly the same split-and-index task. This is the reason MATCH command allows prefixed wildcards but not postfixed wilcards. Since single words are indexed, a postfix wildcard is impossible to manage in the usual way index does. You can039t retrieve 039nited states039 instantly from index because left characters are the most important part of index. Even so, I hope MySql developers some day implement postfix wildcars, because for many of us, it is important to perform a truly 039full text039 search. To say something, if I have a record with the word 039database039. I want retrieve this record when searching by 039tabas039, an impossible task for actual fulltext search command. It039s easy to see that such a command can gain lot of performance, even when MySql developers be obliged to search byte to byte into the indexed words. If you have a big table with text descriptions. to say 1 GB size, it is possible that quantity of different words into text will not pass from 500.000, maybe 1.000.000 words, averaging 8 bytes each, total 8 MB of data to be browsed, instead the 1 GB you should seek byte to byte to find what you want. This is a 1 GB 8 MB 125. or two orders of magnitude lower in terms of processing. Posted by Sergejzr Zr on July 27, 2007 Unfortunately it is not possible to combine Fulltext field and normal (i. e integer) field into one index. Since only one index per query can be used, that seems be a problem Table: id(integer primary key)content(text fulltext indexed)status(integer key) Note that executing folowing query, mysql will use only one index. Either fulltext, or status (Depending on intern statistics). Q1: SELECT FROM table WHERE MATCH(content) AGAINST(039searchQuery039) AND status 1 However it is still possible to use both indexes in one query. You will need a new index on id, status pair and use join. Thus mysql will be able to use one index for each table. Q2: SELECT t1. from table t1 LEFT JOIN table t2 ON(t1.idt2.id) WHERE MATCH(t1.content)AGAINST(039searchQuery039) AND status1 Q2 will run significantly faster than Q1 at least in my case :) Note the overhead: You will need an id for each row and a key wich is spanned over needed fields strating with id. Posted by Phoebe Bright on August 14, 2007 Using this for the first time I picked an unfortunate test and took a while before I worked out why it wasn039t working. In the hopes of saving other newbies some time: This will work: SELECT FROM myfile WHERE description LIKE 039sea039 But this will return nothing: SELECT FROM myfile WHERE MATCH (description) AGAINST (039sea039) BECAUSE THE DEFAULT MIN LENGTH IS 4 need to set ftminwordlen to 3 in the configuration file if you want it to work. Posted by Mohamed Mahir on September 28, 2007 To get the first exact matching record of the Full text search i wrote like this.. SELECT MATCH (column) AGAINST (039keyword039) relevancy FROM t1 WHERE MATCH (column) AGAINST (039keyword039) ORDER BY relevancy DESC LIMIT 1 Posted by Neil Delargy on October 19, 2007 One solution to find a word with a dashes or hyphens in is to use FULL TEXT SEARCH IN BOOLEAN MODE, and to enclose the word with the hyphen dash in double quotes. Posted by Derek Foreman on October 31, 2007 I use Mediawiki that makes use of the FullText searching and was not getting results I knew were in the database. After reading this page I realized that mysql won039t index words 3 characters or less by default. The solution is detailed clearly in this page Change the ftminwordlen setting. You can find what the server is using by running: SHOW VARIABLES LIKE 039ft039 Then you039ll have to rebuild the indexes on the tables that have FULLTEXT indices, because the server I039m using had several databases I needed a quick way to identify which tables these were. SELECT DISTINCT TABLESCHEMA, TABLENAME FROM COLUMNS WERE COLUMNKEY 039MUL039 I could then rebuild the tables. Posted by Jane Doe on November 28, 2007 Very fast and flexible, and works nice with MySQL. Eliminates many of the issues mentioned here in the comments, also ) MATCHAGAINST didn039t work how I intended. Here039s how I finally solved what I thought MATCHAGAINST should have been doing from the beginning: Posted by Carlos Dias on August 8, 2011 Basically this approach makes me think twice because of the next logical steps: 1- If your working in one table with a lot of records. each time the records are updated or new lines inserted the index must be (obviously)recreated. if it039s myisam. writing operations the table is locked. 2- I guess that the best approach towards this it039s probably the logic of: when tables are huge. not creating indexes for text search. create cachesql. (cachesql is one index). Somehow anticipating these problems. like i write are not problems to ignore. Why this is the best option. because if people use one file to log the last writing operations and compare it with the file that contains the results cache(best approach. cronjob). it039s only necessary to point to the file that contains the resultscache. The logic of:If there are 500 000 000 of conjugations of wordsphrases, etc what039s the need of indexing everything if only 50 000 conjugations are usedseeked, etc. Posted by Bradley Smith on February 21, 2012 Alan, instead of creating 80 different tables, one for each category, why not partition the table by the category so the records with that category would be grouped together within the partition and then your only searching within the specific category and more direct and faster route to the data you want to search Posted by Nasser W on September 2, 2013 MySQL fulltext search works well for Arabic. Just make sure of the following where needed: 1. COLLATION utf8unicodeci amp CHARACTER SET utf8. (Databases, Tables, and Columns). 2. Index words of 3 letters and more. This is Very Important for Arabic, ftminwordlen 3 (see show variables like quotftquot) 3. Check the version of MySQL (5.5 or 5.6), and Engine (InnoDb or MyIsam) Sign Up Login You must be logged in to post a comment.

No comments:

Post a Comment