Binärdaten in MySQL [geschlossen]

186

Wie speichere ich Binärdaten in MySQL ?

Geoff Dalgas
quelle
2
@Nevir: Nach welchen Informationen suchen Sie speziell? Was fehlt Ihrer Meinung nach in den Antworten von @ phpguy und @ Mat ?
Eggyal
Entschuldigung, ich wollte dies nicht bounty (stieß auf einen UI-Fehler mit SO), kann aber das Bounty nicht entfernen
Nevir
Sie sollten in der Lage sein, ein Kopfgeld zu entfernen
Akshay Giri FR

Antworten:

138

Die Antwort von phpguy ist richtig, aber ich denke, dass die zusätzlichen Details dort viel Verwirrung stiften.

Die grundlegende Antwort liegt in einer BLOBDatentyp- / Attributdomäne. BLOB ist die Abkürzung für Binary Large Object und dieser Spaltendatentyp ist spezifisch für die Verarbeitung von Binärdaten.

Siehe die entsprechende Handbuchseite für MySQL .

Matte
quelle
57

Für einen Tisch wie diesen:

CREATE TABLE binary_data (
    id INT(4) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    description CHAR(50),
    bin_data LONGBLOB,
    filename CHAR(50),
    filesize CHAR(50),
    filetype CHAR(50)
);

Hier ist ein PHP-Beispiel:

<?php
    // store.php3 - by Florian Dittmer <dittmer@gmx.net>
    // Example php script to demonstrate the storing of binary files into
    // an sql database. More information can be found at http://www.phpbuilder.com/
?>

<html>
    <head><title>Store binary data into SQL Database</title></head>

    <body>
        <?php
            // Code that will be executed if the form has been submitted:

            if ($submit) {
                // Connect to the database (you may have to adjust
                // the hostname, username or password).

                mysql_connect("localhost", "root", "password");
                mysql_select_db("binary_data");

                $data = mysql_real_escape_string(fread(fopen($form_data, "r"), filesize($form_data)));

                $result = mysql_query("INSERT INTO binary_data (description, bin_data, filename, filesize, filetype) ".
                                    "VALUES ('$form_description', '$data', '$form_data_name', '$form_data_size', '$form_data_type')");

                $id= mysql_insert_id();
                print "<p>This file has the following Database ID: <b>$id</b>";

                mysql_close();
            } else {

                // else show the form to submit new data:
        ?>
        <form method="post" action="<?php echo $PHP_SELF; ?>" enctype="multipart/form-data">
            File Description:<br>
            <input type="text" name="form_description"  size="40">
            <input type="hidden" name="MAX_FILE_SIZE" value="1000000">
            <br>File to upload/store in database:<br>
            <input type="file" name="form_data"  size="40">
            <p><input type="submit" name="submit" value="submit">
        </form>

        <?php
            }
        ?>
    </body>
</html>
Mauris
quelle
9
Dieser Code sieht aus wie PHP3 (oder vielleicht 4), das register_globals aktiviert hat. Sie möchten diesen Code nicht ausführen und er funktioniert auch nicht bei einer halbaktuellen PHP-Installation (Version 5).
Bis zum
26
-1 für addslashes (), bei denen mysql_real_escape_string () benötigt wird. Können wir bitte aufhören, Leuten Code mit SQL-Injection-Schwachstellen zu geben? (Nein, Addslashes () ist NICHT gut genug.)
Chaos
40

Ich empfehle dringend , gegen binäre Daten in einer relationalen Datenbank gespeichert werden . Relationale Datenbanken sind für die Arbeit mit Daten fester Größe ausgelegt. Hier liegt ihre Leistungsstärke: Erinnern Sie sich an Joels alten Artikel darüber, warum Datenbanken so schnell sind? weil es genau 1 Zeigerinkrement braucht, um von einem Datensatz zu einem anderen Datensatz zu wechseln. Wenn Sie BLOB-Daten von undefinierter und stark variierender Größe hinzufügen, wird die Leistung beeinträchtigt.

Speichern Sie stattdessen Dateien im Dateisystem und Dateinamen in Ihrer Datenbank.

Alex Weinstein
quelle
11
Ich habe nicht abgelehnt, aber es könnte daran liegen, dass er andeutet, dass Sie es NIEMALS tun sollten, anstatt zu sagen, dass es die meiste Zeit eine schlechte Idee ist. Ich stimme ihm im Allgemeinen zu, aber nicht in 100% der Fälle. Es kann andere Überlegungen als die Leistung geben. Zum Beispiel arbeite ich gerade an etwas, bei dem Leistung überhaupt keine Rolle spielt. Andere Faktoren wie Zentralisierung, Einfachheit und Sicherungen machen in diesem Fall das Speichern in der Datenbank sinnvoll. Ein weiterer häufiger Grund ist die Replikation.
LaVache
4
Auf der anderen Seite ist das Speichern von Daten in der Datenbank vom Betriebssystem unabhängig, was für seltsame Dateinamen hilfreich sein kann. db kann mehrere Dateien mit demselben Dateinamen speichern, das Betriebssystem nicht. Es gibt keine Lese- / Schreib- / Löschprobleme. Es wird kein zusätzliches Backup-System benötigt. Und es ist nicht öffentlich. Manchmal ist es also schnell in der Entwicklung. Übrigens. Niemand zwingt Sie, alles in derselben Datenbank zu speichern. Am Ende landet alles auf einer Festplatte.
Joeri
7
@AlexWeinstein, Sie verwechseln Binärdaten mit Daten fester Breite. Binärdaten können auch eine feste Breite haben. Daten mit fester Breite sind nicht für alle Situationen geeignet. In der Tat würden Sie in vielen Situationen von Daten mit variabler Breite profitieren: Lesen Sie den letzten Absatz von dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html
Pacerier
4
Stimmen Sie @Pacerier zu, BINARY (16) wird fest gespeichert. Wie bei BLOB: Ein BLOB hat einen Zeiger mit fester Breite auf Daten, die außerhalb der Tabelle gespeichert sind. Das ist anders als varchar oder varbinary, die es inline speichern. Das Durchsuchen eines Blobs erfordert einige zusätzliche Schritte, aber lassen Sie es aus Ihrer WHERE-Klausel heraus und es ist in Ordnung.
Garr Godfrey
4
Ich denke auch, dass das Speichern von Dateien im Dateisystem sehr kaputt und nicht portabel ist. Was ist, wenn die Datei gelöscht wird?
Garr Godfrey
22

Obwohl Sie nicht gesagt haben, was Sie speichern, und Sie haben möglicherweise einen guten Grund dafür, lautet die Antwort häufig "als Dateisystemreferenz" und die tatsächlichen Daten befinden sich irgendwo im Dateisystem.

http://www.onlamp.com/pub/a/onlamp/2002/07/11/MySQLtips.html

Issac Kelly
quelle
17

Dies hängt von den Daten ab, die Sie speichern möchten. Im obigen Beispiel wird der LONGBLOBDatentyp verwendet. Beachten Sie jedoch, dass es andere binäre Datenformate gibt:

TINYBLOB/BLOB/MEDIUMBLOB/LONGBLOB
VARBINARY
BINARY

Jeder hat seine Anwendungsfälle. Wenn es sich um eine bekannte (kurze) Länge handelt (z. B. gepackte Daten) , funktioniert dies oft BINARYoder VARBINARYfunktioniert. Sie haben den zusätzlichen Vorteil, dass sie in der Lage sind, sie zu indizieren.

d0nut
quelle
14

Obwohl dies nicht erforderlich sein sollte, können Sie versuchen base64, Daten ein- und auszukodieren. Das bedeutet, dass die Datenbank nur ASCII-Zeichen enthält. Es wird etwas mehr Platz und Zeit in Anspruch nehmen, aber jedes Problem mit den Binärdaten wird beseitigt.

user10117
quelle
11

Wenn das Feld - nicht empfohlen - BLOB vorhanden ist, können Sie Daten folgendermaßen speichern:

mysql_query("UPDATE table SET field=X'".bin2hex($bin_data)."' WHERE id=$id");

Idee von hier genommen .

Gemeinschaft
quelle
10

Es stellt sich auch die Frage, wie die Daten in das BLOB gelangen. Sie können die Daten in eine INSERT-Anweisung einfügen, wie das PHP-Beispiel zeigt (obwohl Sie mysql_real_escape_string anstelle von Addslashes verwenden sollten). Wenn die Datei auf dem Datenbankserver vorhanden ist, können Sie auch LOAD_FILE von MySQL verwenden

Scott Noyes
quelle
Dieser Link besagt, dass MySQL_real_escape_string veraltet ist.
Poul Bak