Binärdaten in MySQL [geschlossen]


186

Wie speichere ich Binärdaten in MySQL ?



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 .


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>

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.


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


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.


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.



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


Dieser Link besagt, dass MySQL_real_escape_string veraltet ist.
Poul Bak

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.