ข้อมูลไบนารีใน MySQL [ปิด]


186

ฉันจะเก็บข้อมูลไบนารีในMySQL ได้อย่างไร



2
@Nevir: คุณมีข้อมูลอะไรเป็นพิเศษหลังจากนั้น? คุณรู้สึกอย่างไรที่ขาดคำตอบของ@ phpguy'sและ@ Mat ?
eggyal

ขออภัยฉันไม่ได้ตั้งใจที่จะได้รับรางวัลนี้ (พบข้อผิดพลาด UI กับ SO) แต่ไม่สามารถลบรางวัลได้
Nevir

คุณควรจะสามารถลบค่าหัว
Akshay Giri FR

คำตอบ:


138

คำตอบโดย phpguy นั้นถูกต้อง แต่ฉันคิดว่ามีความสับสนมากมายในรายละเอียดเพิ่มเติมที่นั่น

คำตอบพื้นฐานอยู่ในBLOBโดเมนชนิดข้อมูล / แอตทริบิวต์ BLOBย่อมาจาก Binary Large Object และชนิดข้อมูลคอลัมน์นั้นมีลักษณะเฉพาะสำหรับการจัดการข้อมูลไบนารี

ดูหน้าคู่มือที่เกี่ยวข้องสำหรับ MySQL


57

สำหรับตารางเช่นนี้

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)
);

นี่คือตัวอย่าง PHP:

<?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
รหัสนี้ดูเหมือน PHP3 (หรืออาจจะ 4) ซึ่งเปิดใช้งาน register_globals คุณไม่ต้องการเรียกใช้รหัสนี้และมันจะไม่ทำงานในการติดตั้ง PHP แบบกึ่งล่าสุด (ซึ่งเป็นเวอร์ชัน 5)
จนถึง

26
-1 สำหรับ addlashes () โดยที่ mysql_real_escape_string () เป็นสิ่งจำเป็น เราสามารถหยุดให้รหัสผู้ใช้กับช่องโหว่การฉีด SQL ได้หรือไม่? (ไม่, addlashes () ไม่ดีพอ)
โกลาหล

40

ฉันขอแนะนำอย่างยิ่งต่อการจัดเก็บข้อมูลไบนารีในฐานข้อมูลเชิงสัมพันธ์ ฐานข้อมูลเชิงสัมพันธ์ได้รับการออกแบบให้ทำงานกับข้อมูลขนาดคงที่ นั่นคือจุดแข็งของประสิทธิภาพการทำงานของพวกเขา: จำบทความเก่าของโจเอลว่าทำไมฐานข้อมูลถึงรวดเร็วขนาดนี้? เนื่องจากต้องใช้ตัวชี้เพิ่มขึ้น 1 ครั้งเพื่อย้ายจากเร็กคอร์ดไปยังเร็กคอร์ดอื่น หากคุณเพิ่มข้อมูล BLOB ที่ไม่ได้กำหนดและมีขนาดแตกต่างกันอย่างมากมายคุณจะเพิ่มประสิทธิภาพ

ให้เก็บไฟล์ไว้ในระบบไฟล์แทนและเก็บชื่อไฟล์ไว้ในฐานข้อมูลของคุณแทน


11
ฉันไม่ได้ลงคะแนน แต่อาจเป็นเพราะเขาบอกว่าคุณไม่ควรทำอย่างนั้นแทนที่จะพูดว่ามันเป็นความคิดที่แย่ตลอดเวลา ฉันเห็นด้วยกับเขาโดยทั่วไป แต่ไม่ใช่ในกรณี 100% อาจมีข้อควรพิจารณานอกเหนือจากประสิทธิภาพ เช่นตอนนี้ฉันกำลังทำงานบางอย่างที่การแสดงไม่สำคัญเลย ปัจจัยอื่น ๆ เช่นการรวมศูนย์ความเรียบง่ายและการสำรองข้อมูลหมายความว่าในกรณีนี้การจัดเก็บในฐานข้อมูลเหมาะสม อีกสาเหตุหนึ่งคือการจำลองแบบ
LaVache

4
ในทางกลับกันการจัดเก็บข้อมูลใน db เป็นอิสระจากระบบปฏิบัติการซึ่งสามารถดีสำหรับชื่อไฟล์แปลก ๆ db สามารถจัดเก็บหลายไฟล์ด้วยชื่อไฟล์เดียวกันระบบปฏิบัติการไม่สามารถ ไม่มีปัญหาการอ่าน / เขียน / ลบ ไม่จำเป็นต้องมีระบบสำรองข้อมูลเพิ่มเติม และมันไม่ได้เป็นแบบสาธารณะ ดังนั้นบางครั้งมันก็กำลังพัฒนาอย่างรวดเร็ว Btw ไม่มีใครบังคับให้คุณจัดเก็บทุกสิ่งในฐานข้อมูลเดียวกันในท้ายที่สุดทุกอย่างจะจบลงบนดิสก์
Joeri

7
@AlexWeinstein คุณสับสนข้อมูลไบนารีด้วยข้อมูลความกว้างคงที่ ข้อมูลไบนารีสามารถกำหนดความกว้างได้เช่นกัน และข้อมูลความกว้างคงที่นั้นไม่ดีสำหรับทุกสถานการณ์ แน่นอนในหลาย ๆ สถานการณ์คุณจะได้รับประโยชน์จากข้อมูลความกว้างของตัวแปร: อ่านย่อหน้าสุดท้ายของdev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html
Pacerier

4
เห็นด้วยกับ @Pacerier เกี่ยวกับเรื่องนี้ BINARY (16) ได้รับการแก้ไขแล้ว สำหรับ BLOB: BLOB มีตัวชี้ความกว้างคงที่สำหรับข้อมูลที่เก็บไว้นอกตาราง ซึ่งแตกต่างจาก varchar หรือ varbinary ซึ่งเก็บไว้แบบอินไลน์การค้นหาหยดต้องใช้ขั้นตอนพิเศษบางอย่าง แต่ปล่อยให้มันออกมาจากส่วนคำสั่ง WHERE ของคุณและมันก็โอเค
Garr Godfrey

4
ฉันยังคิดว่าการจัดเก็บไฟล์ในระบบไฟล์นั้นเสียและไม่สามารถพกพาได้ เกิดอะไรขึ้นถ้าไฟล์ถูกลบ
Garr Godfrey

22

ในขณะที่คุณไม่ได้พูดในสิ่งที่คุณกำลังจัดเก็บและคุณอาจมีเหตุผลที่ดีในการทำเช่นนั้นบ่อยครั้งคำตอบก็คือ 'เป็นการอ้างอิงระบบไฟล์' และข้อมูลจริงอยู่บนระบบไฟล์อยู่ที่ไหนซักแห่ง

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


17

ขึ้นอยู่กับข้อมูลที่คุณต้องการจัดเก็บ ตัวอย่างข้างต้นใช้LONGBLOBชนิดข้อมูล แต่คุณควรระวังว่ามีรูปแบบข้อมูลไบนารีอื่น ๆ :

TINYBLOB/BLOB/MEDIUMBLOB/LONGBLOB
VARBINARY
BINARY

แต่ละคนมีกรณีใช้งาน หากเป็นความยาว (สั้น) ที่ทราบ (เช่นข้อมูลที่บรรจุ) บ่อยครั้งBINARYหรือVARBINARYจะใช้งานได้ พวกเขาได้รับประโยชน์เพิ่มเติมจากการที่สามารถทำดัชนีตันได้


14

แม้ว่ามันไม่จำเป็น แต่คุณสามารถลองbase64เข้ารหัสข้อมูลและถอดรหัสมันได้ นั่นหมายความว่าฐานข้อมูลจะมีอักขระ ASCII จะใช้พื้นที่และเวลาเพิ่มขึ้นเล็กน้อย แต่ปัญหาใด ๆ ที่เกี่ยวข้องกับข้อมูลไบนารีจะถูกกำจัด


11

หากฟิลด์- ไม่แนะนำ - มี BLOB อยู่คุณสามารถบันทึกข้อมูลด้วยวิธีนี้:

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

ความคิดที่นำมาจากที่นี่


10

คำถามก็เกิดขึ้นว่าจะนำข้อมูลเข้าสู่ BLOB ได้อย่างไร คุณสามารถใส่ข้อมูลในคำสั่ง INSERT ได้ตามตัวอย่างของ PHP ที่แสดง (แม้ว่าคุณควรใช้mysql_real_escape_stringแทนที่จะเป็น addlashes) หากไฟล์มีอยู่บนเซิร์ฟเวอร์ฐานข้อมูลคุณสามารถใช้LOAD_FILEของ MySQL ได้เช่นกัน


ลิงค์นั้นบอกว่า MySQL_real_escape_string เลิกใช้แล้ว
Poul Bak Bak

10

เมื่อฉันต้องเก็บข้อมูลไบนารีฉันมักจะใช้รูปแบบตามที่แนะนำVARBINARYbyd0nut

คุณสามารถค้นหาเอกสารได้ที่เว็บไซต์ MySQL ภายใต้หัวข้อเอกสาร12.4.2 The BINARY และ VARBINARY Types

หากคุณกำลังถามว่าอะไรคือข้อได้เปรียบโปรดดูคำถามที่ว่าทำไม - varbinary- แทนที่จะเป็น - varchar

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.