2008-08-01 58 views
159

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

+0

[lưu trữ-hình ảnh-in-db-yea-hoặc-nay] (https://stackoverflow.com/questions/3748/) –

+1

@Nevir: Sau đây là thông tin gì? Bạn cảm thấy gì khi thiếu [@ phpguy's] (https://stackoverflow.com/questions/17/binary-data-in-mysql#18) và [@ Mat's] (https://stackoverflow.com/questions/ 17/binary-data-in-mysql # 26) câu trả lời? – eggyal

+0

Xin lỗi, tôi không có ý nói tiền thưởng này (chạy vào lỗi giao diện người dùng với SO), nhưng không thể xóa số tiền thưởng – Nevir

Trả lời

122

Câu trả lời bởi phpguy là đúng nhưng tôi nghĩ rằng có rất nhiều sự nhầm lẫn trong các chi tiết thêm có .

Câu trả lời cơ bản nằm trong miền số BLOB loại dữ liệu/thuộc tính. BLOB viết tắt của Đối tượng lớn nhị phân và loại dữ liệu cột đó là cụ thể để xử lý dữ liệu nhị phân.

Xem the relevant manual page for MySQL.

50

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

Dưới đây là một ví dụ PHP:

<?php 
    // store.php3 - by Florian Dittmer <[email protected]> 
    // 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> 
+8

Mã này trông giống như PHP3 (hoặc có thể 4), đã bậ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 một bản cập nhật cài đặt PHP được cập nhật (là phiên bản 5). – Till

+21

-1 cho addslashes() trong đó mysql_real_escape_string() là cần thiết. Chúng tôi có thể vui lòng ngừng cung cấp cho mọi người mã với lỗ hổng SQL injection trong đó không? (No, addslashes() là KHÔNG đủ tốt.) – chaos

19

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

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

8

Câu hỏi cũng nảy sinh cách đưa dữ liệu vào BLOB. Bạn có thể đặt dữ liệu trong 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_string thay vì các dấu cộng). 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

12

của MySQL trong khi không cần thiết, bạn có thể thử mã hóa và giải mã dữ liệu base64. Điều đó có nghĩa là db sẽ chỉ có các ký tự ascii. Nó sẽ mất nhiều không gian và thời gian hơn, nhưng bất kỳ vấn đề nào liên quan đến dữ liệu nhị phân sẽ bị loại bỏ.

7

Triển khai bộ nhớ tốt hơn nhiều trong số here. Bạn sẽ gặp vấn đề với việc triển khai Florian.

35

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

+10

Tôi đã không downvote, nhưng nó có thể là do ông ngụ ý rằng bạn KHÔNG BAO GIỜ làm điều đó, như trái ngược với nói rằng đó là một ý tưởng tồi 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% các trường hợp. Có thể có các cân nhắc khác với hiệu suất. Ví dụ tôi đang làm việc trên một cái gì đó bây giờ mà hiệu suất không quan trọng cả. 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à sao chép. – YeB

+1

Trường BLOB có kích thước cố định 64 kilobyte. Nó không phải là khác nhau, phải không? –

+0

64KB sẽ không vừa với nhiều tệp bên trong - vì vậy, bạn sẽ cần phải có nhiều hơn một khối 64KB để lưu trữ dữ liệu. –

15

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

TINYBLOB/BLOB/MEDIUMBLOB/LONGBLOB
VARBINARY
BINARY

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

9

Nếu - not recommended - lĩnh vực BLOB tồn tại, bạn có thể lưu dữ liệu theo cách này:

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

Idea lấy từ here.

Các vấn đề liên quan