Hướng dẫn mysql insert binary - mysql chèn nhị phân

12

Mới! Lưu câu hỏi hoặc câu trả lời và sắp xếp nội dung yêu thích của bạn. Tìm hiểu thêm.Learn more.
Learn more.

Tôi đã nghe một tin đồn rằng khi chèn dữ liệu nhị phân (tệp và tương tự) vào MySQL, bạn nên sử dụng hàm bin2hex() và gửi nó làm giá trị được mã hóa hex, thay vì chỉ sử dụng mysql_real_escape_string trên chuỗi nhị phân và sử dụng nó.

// That you should do
$hex = bin2hex($raw_bin);
$sql = "INSERT INTO `table`(`file`) VALUES (X'{$hex}')";

// Rather than
$bin = mysql_real_escape_string($raw_bin);
$sql = "INSERT INTO `table`(`file`) VALUES ('{$bin}')";

Nó được cho là vì lý do hiệu suất. Một cái gì đó để làm với cách MySQL xử lý các chuỗi lớn so với cách xử lý các giá trị được mã hóa hex

Tuy nhiên, tôi đang gặp khó khăn trong việc xác nhận điều này. Tất cả các bài kiểm tra của tôi cho thấy oposite chính xác; rằng phương pháp bin2hex chậm hơn ~ 85% và sử dụng bộ nhớ nhiều hơn ~ 24%. . (I am testing this on PHP 5.3, MySQL 5.1, Win7 x64 - Using a farily simple insert loop.)
(I am testing this on PHP 5.3, MySQL 5.1, Win7 x64 - Using a farily simple insert loop.)

Chẳng hạn, biểu đồ này hiển thị việc sử dụng bộ nhớ riêng của quy trình MySQLD trong khi mã kiểm tra đang chạy:

Hướng dẫn mysql insert binary - mysql chèn nhị phân


(Nguồn: advefir.com)

Có ai có bất kỳ cách giải thích hoặc hội nghị nào sẽ làm rõ điều này không?

Thanks.

Glorfindel

21.2K13 Huy hiệu vàng77 Huy hiệu bạc101 Huy hiệu đồng13 gold badges77 silver badges101 bronze badges13 gold badges77 silver badges101 bronze badges

Hỏi ngày 1 tháng 4 năm 2010 lúc 6:07Apr 1, 2010 at 6:07Apr 1, 2010 at 6:07

3

Điều này nghe có vẻ như một huyền thoại đô thị đối với tôi.

bin2hex() ánh xạ từng byte trong đầu vào thành hai byte trong đầu ra ('a' -> '61'), do đó bạn nên nhận thấy sự gia tăng bộ nhớ đáng kể của tập lệnh thực hiện truy vấn - nó sẽ sử dụng ít nhất Dữ liệu nhị phân sẽ được chèn.

Hơn nữa, điều này ngụ ý rằng việc chạy bin2hex() trên một chuỗi dài mất nhiều thời gian hơn so với chạy mysql_real_escape string(), như - như được giải thích trong tài liệu của MySQL - chỉ thoát 6 ký tự: NULL, bin2hex()0, bin2hex()1, bin2hex()2, bin2hex()3 và 'Control -Z'.

Đó là cho phần PHP, bây giờ cho MySQL: máy chủ cần thực hiện thao tác ngược để lưu trữ dữ liệu một cách chính xác. Đảo ngược một trong hai hàm mất gần như hoạt động ban đầu - hàm ngược của bin2hex()4 cần thay thế các giá trị thoát (bin2hex()5) bằng các giá trị không được phân loại (bin2hex()2) Byte mới.

Vì việc gọi bin2hex()4 trên dữ liệu nhị phân là an toàn (theo tài liệu của MySQL và PHP hoặc ngay cả khi chỉ xem xét rằng hoạt động không thực hiện bất kỳ chuyển đổi nào khác ngoài những chuyển đổi được liệt kê ở trên), sẽ hoàn toàn không có ý nghĩa khi thực hiện hoạt động tốn kém như vậy.

Đã trả lời ngày 10 tháng 4 năm 2010 lúc 10:14Apr 10, 2010 at 10:14Apr 10, 2010 at 10:14

Soulmergesoulmergesoulmergesoulmerge

72.1K19 Huy hiệu vàng117 Huy hiệu bạc152 Huy hiệu đồng19 gold badges117 silver badges152 bronze badges19 gold badges117 silver badges152 bronze badges

4

Tôi đã tự mình thử nghiệm điều này và tôi đã đưa ra kết quả khá nhất quán. (Mặc dù các bài kiểm tra của tôi là một phần thô.)

Tôi đã thử nghiệm ba máy tính

  1. Windows 7 (x64), Php 5.3, MySQL 5.1
  2. Ubuntu 9.10 (x64) Php 5.2, MySQL 5.1
  3. Ubuntu 10.04 (x32) Php 5.3, MySQL 5.1

Cho đến nay các bài kiểm tra trên cả ba nền tảng đã chỉ ra cùng một TING:

  • Chèn vào một đốm màu là nhanh hơn 2 lần đến 8 lần trên Myisam so với trên innodb. Sự khác biệt dường như cao hơn trên các chuỗi nhị phân so với các chuỗi được mã hóa hex. (Xem dữ liệu bên dưới)
  • Sử dụng chuỗi được mã hóa hex (bin2hex thành mysql_real_escape_string0) sử dụng nhiều bộ nhớ hơn, trung bình, hơn là sử dụng chuỗi nhị phân đã thoát (mysql_real_escape_string trên dữ liệu thô). - Điều này có vẻ đúng với cả Myisam và Innodb.
  • Chuỗi nhị phân nhanh hơn trên Myisam, nhưng dữ liệu được mã hóa hex nhanh hơn trên Innodb.

Bài kiểm tra về cơ bản chỉ là một vòng lặp đơn giản thoát ra hoặc mã hóa hex dữ liệu thô (hình ảnh 2,4 mib được truy xuất một lần ở đầu tập lệnh), xây dựng chuỗi truy vấn và thực hiện nó thông qua các hàm mysql_real_escape_string2 hoặc mysql_real_escape_string3. - Tôi đã thử nghiệm với cả hai phần mở rộng. Dường như không có sự khác biệt nào.

Tôi đặt kết quả từ Ubuntu 10.04 (#3) lên trong bảng tính. Kết quả từ máy Ubuntu 9.10 (#2) khá giống nhau, vì vậy tôi không bận tâm đến việc thiết lập chúng: (Cuối cùng là một cái cớ để kiểm tra đúng điều của Google Docs! XD) (Finally an excuse to test the Google Docs thing properly! xD)
(Finally an excuse to test the Google Docs thing properly! xD)

  • Chuỗi nhị phân trên Myisam
  • Chuỗi mã hóa hex trên myisam
  • Chuỗi nhị phân trên innodb
  • Chuỗi mã hóa hex trên innodb

Các biểu đồ này hiển thị việc sử dụng bộ nhớ riêng bằng quy trình mysql_real_escape_string4 trên máy Win7 (#1).

  • Chuỗi nhị phân trên Myisam
  • Chuỗi mã hóa hex trên myisam
  • Chuỗi nhị phân trên innodb
  • Chuỗi mã hóa hex trên innodb

Các biểu đồ này hiển thị việc sử dụng bộ nhớ riêng bằng quy trình mysql_real_escape_string4 trên máy Win7 (#1).Apr 3, 2010 at 4:57

Các biểu đồ này hiển thị việc sử dụng bộ nhớ riêng bằng quy trình mysql_real_escape_string4 trên máy Win7 (#1).Apr 3, 2010 at 4:57Atli

Chuỗi mã hóa hex trên innodbAtli2 gold badges29 silver badges42 bronze badges

Đã trả lời ngày 3 tháng 4 năm 2010 lúc 4:572 gold badges29 silver badges42 bronze badges

Atliatli

Dù bằng cách nào, bạn nhận được một lợi ích bảo mật (và đơn giản) ngay tại đó.

Đã trả lời ngày 1 tháng 4 năm 2010 lúc 7:20Apr 1, 2010 at 7:20Apr 1, 2010 at 7:20

Skrebbelskrebbelskrebbelskrebbel

9.7636 huy hiệu vàng34 Huy hiệu bạc34 Huy hiệu đồng6 gold badges34 silver badges34 bronze badges6 gold badges34 silver badges34 bronze badges

3

Ví dụ: nếu bạn gặp phải vấn đề tương tự như mô tả ở đây: http://www.php.net/manual/en/function.mysql-real-escape-string.php#82015

ví dụ.Mặc dù mysql_real_escape_string dường như là "an toàn nhị phân", bạn không thể sử dụng nó (ví dụ) kết hợp với igbinary_serialize - unserialization sẽ thất bại.

Trong trường hợp đó, bạn cần bin2hex trước khi chèn dữ liệu vào MySQL.

Ngoài ra, thông thường bạn đọc dữ liệu thường xuyên hơn từ MySQL hơn là chèn :)

Đã trả lời ngày 12 tháng 4 năm 2012 lúc 17:46Apr 12, 2012 at 17:46Apr 12, 2012 at 17:46

LifeOfGuENTERLIFEOFUGUENTERlifeofguenterlifeofguenter

1.1351 Huy hiệu vàng13 Huy hiệu bạc20 Huy hiệu Đồng1 gold badge13 silver badges20 bronze badges1 gold badge13 silver badges20 bronze badges