Dữ liệu nhị phân trong MySQL [đã đóng]


186

Làm cách nào để lưu trữ dữ liệu nhị phân trong MySQL ?



2
@Nevir: Bạn có thông tin gì cụ thể sau? Bạn cảm thấy thiếu gì từ câu trả lời của @ phpguy@ Mat ?
eggyal

Xin lỗi, tôi không có ý định trả tiền này (gặp phải lỗi UI với SO), nhưng không thể xóa tiền thưởng
Nevir

bạn sẽ có thể xóa tiền thưởng
Akshay Giri FR

Câu trả lời:


138

Câu trả lời của phpguy là chính xác nhưng tôi nghĩ có rất nhiều nhầm lẫn trong các chi tiết bổ sung ở đó.

Câu trả lời cơ bản là trong một BLOBmiền dữ liệu / thuộc tính. BLOB là viết tắt của Binary Large Object và kiểu dữ liệu cột đó là cụ thể để xử lý dữ liệu nhị phân.

Xem trang hướng dẫn liên quan cho MySQL .


57

Đối với một bảng như thế này:

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

Đây là một ví dụ về 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
Mã này trông giống như PHP3 (hoặc có thể là 4), được kích hoạt register_globals. Bạn không muốn chạy mã này và nó cũng sẽ không hoạt động trên bản cài đặt PHP bán cập nhật (phiên bản 5).
Đến

26
-1 cho addlash () trong đó cần mys mys_real_escape_opes (). Chúng tôi có thể vui lòng ngừng cung cấp mã cho mọi người với các lỗ hổng SQL tiêm trong đó không? (Không, addlash () KHÔNG đủ tốt.)
hỗn loạn

40

Tôi đề nghị chống lại việc lưu trữ dữ liệu nhị phân trong một cơ sở dữ liệu quan hệ. Cơ sở dữ liệu quan hệ được thiết kế để làm việc với dữ liệu kích thước cố định; đó là nơi sức mạnh hiệu suất của họ là: hãy nhớ bài viết cũ của Joel về lý do tại sao cơ sở dữ liệu quá nhanh? bởi vì phải mất chính xác 1 con trỏ để di chuyển từ một bản ghi sang một bản ghi khác. Nếu bạn thêm dữ liệu BLOB có kích thước không xác định và rất khác nhau, bạn sẽ tăng hiệu suất.

Thay vào đó, lưu trữ tệp trong hệ thống tệp và lưu trữ tên tệp trong cơ sở dữ liệu của bạn.


11
Tôi đã không downvote, nhưng có thể là do anh ta ngụ ý rằng bạn KHÔNG BAO GIỜ nên làm điều đó, trái ngược với việc nói rằng đó là một ý tưởng tồi trong hầu hết thời gian. Tôi đồng ý với anh ta nói chung, nhưng không phải trong 100% trường hợp. Có thể có những cân nhắc khác hơn hiệu suất. Ví dụ: tôi đang làm việc gì đó ngay bây giờ khi hiệu suất không thành vấn đề. Các yếu tố khác như tập trung, đơn giản và sao lưu có nghĩa là trong trường hợp này lưu trữ trong cơ sở dữ liệu có ý nghĩa. Một lý do phổ biến khác là nhân rộng.
LaVache

4
Mặt khác, việc lưu trữ dữ liệu trong db là độc lập với hệ điều hành, có thể tốt cho các tên tệp lạ. db có thể lưu trữ nhiều tệp với cùng tên tệp, hệ điều hành không thể. Nó không có vấn đề đọc / ghi / xóa. Nó không cần một hệ thống sao lưu bổ sung. Và, nó không công khai. Vì vậy, đôi khi nó phát triển nhanh. Btw. không ai bắt bạn phải lưu trữ mọi thứ trong cùng một cơ sở dữ liệu, cuối cùng tất cả kết thúc trên một đĩa.
Joeri

7
@AlexWeinstein, Bạn đang nhầm lẫn dữ liệu nhị phân với dữ liệu chiều rộng cố định. Dữ liệu nhị phân có thể được cố định chiều rộng là tốt. Và dữ liệu chiều rộng cố định là không tốt cho tất cả các tình huống. Thật vậy, trong nhiều tình huống bạn sẽ được hưởng lợi từ dữ liệu độ rộng thay đổi: đọc đoạn cuối của dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html
Pacerier

4
Đồng ý với @Pacerier về điều này, BINary (16) được lưu trữ cố định. Đối với BLOB: BLOB có một con trỏ có chiều rộng cố định cho dữ liệu được lưu trữ bên ngoài bảng. Điều đó không giống như varchar hoặc varbinary lưu trữ nội tuyến. Tìm kiếm một blob yêu cầu một số bước bổ sung, nhưng bỏ nó ra khỏi mệnh đề WHERE của bạn và nó vẫn ổn.
Garr Godfrey

4
tôi cũng nghĩ rằng việc lưu trữ các tập tin trong hệ thống tập tin là rất hỏng và không thể mang theo được. Nếu tập tin bị xóa thì sao?
Garr Godfrey

22

Mặc dù bạn chưa nói những gì bạn đang lưu trữ và bạn có thể có một lý do tuyệt vời để làm như vậy, nhưng câu trả lời thường là "như một tài liệu tham khảo hệ thống tập tin" và dữ liệu thực tế nằm trên hệ thống tập tin ở đâu đó.

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


17

Nó phụ thuộc vào dữ liệu bạn muốn lưu trữ. Ví dụ trên sử dụng LONGBLOBkiểu dữ liệu, nhưng bạn nên biết rằng có các định dạng dữ liệu nhị phân khác:

TINYBLOB/BLOB/MEDIUMBLOB/LONGBLOB
VARBINARY
BINARY

Mỗi có trường hợp sử dụng của họ. Nếu đó là một chiều dài đã biết (ngắn) (ví dụ: dữ liệu được đóng gói) thường xuyên BINARYhoặc VARBINARYsẽ hoạt động. Họ có thêm lợi ích của việc có thể tấn chỉ số trên chúng.


14

Mặc dù không cần thiết, bạn có thể thử base64mã hóa dữ liệu và giải mã nó. Điều đó có nghĩa là db sẽ chỉ có các ký tự ascii. Sẽ mất thêm một chút không gian và thời gian, nhưng mọi vấn đề liên quan đến dữ liệu nhị phân sẽ được loại bỏ.



10

Câu hỏi cũng đặt ra làm thế nào để lấy dữ liệu vào BLOB. Bạn có thể đặt dữ liệu vào một câu lệnh INSERT, như ví dụ PHP hiển thị (mặc dù bạn nên sử dụng mysql_real_escape_opes thay vì thêm vào). Nếu tệp tồn tại trên máy chủ cơ sở dữ liệu, bạn cũng có thể sử dụng LOAD_FILE của MySQL


Liên kết đó nói rằng MySQL_real_escape_opes không được dùng nữa.
Poul Bak

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.