2015-03-26 17 views
12

Vì mục đích đơn giản, giả sử tôi đang phát triển một ứng dụng dành cho thiết bị di động như Instagram. Người dùng có thể tải xuống hình ảnh từ máy chủ và tải lên hình ảnh của riêng họ. Hiện tại, máy chủ lưu trữ tất cả các hình ảnh (trong thực tế, chỉ các hình nhỏ) trong cơ sở dữ liệu MySQL dưới dạng BLOB. Dường như cách phổ biến nhất để chuyển hình ảnh là sử dụng mã hóa Base64, để lại cho tôi hai tùy chọn:MySQL - Base64 vs BLOB

  1. Máy chủ lưu trữ tất cả hình ảnh dưới dạng BLOB. Để tải lên một hình ảnh, khách hàng mã hóa nó thành chuỗi Base64, sau đó gửi nó đến máy chủ. Máy chủ giải mã hình ảnh BACK thành định dạng nhị phân và lưu trữ nó dưới dạng BLOB trong cơ sở dữ liệu. Khi khách hàng yêu cầu một hình ảnh, máy chủ sẽ mã hóa lại hình ảnh dưới dạng chuỗi Base64 và gửi nó cho khách hàng, sau đó giải mã nó trở lại dạng nhị phân để hiển thị.
  2. Máy chủ lưu trữ tất cả hình ảnh dưới dạng chuỗi Base64. Để tải lên một hình ảnh, khách hàng mã hóa nó thành chuỗi Base64 và gửi nó đến máy chủ. Máy chủ không mã hóa hoặc giải mã, nhưng chỉ lưu trữ chuỗi trong cơ sở dữ liệu. Khi khách hàng yêu cầu một hình ảnh, chuỗi Base64 được trả lại cho khách hàng, sau đó giải mã nó để hiển thị.

Rõ ràng, tùy chọn # 1 yêu cầu xử lý đáng kể hơn trên máy chủ, vì hình ảnh phải được mã hóa/giải mã với mọi yêu cầu. Điều này làm cho tôi nghiêng về phía tùy chọn # 2, nhưng một số nghiên cứu đã gợi ý rằng việc lưu trữ chuỗi Base64 trong MySQL kém hiệu quả hơn nhiều so với lưu trữ hình ảnh trực tiếp dưới dạng BLOB và thường không được khuyến khích.

Tôi chắc chắn không phải là người đầu tiên gặp phải tình huống này, vì vậy không ai có đề xuất về cách tốt nhất để thực hiện công việc này?

+2

Tùy chọn # 3 không có hình ảnh trong cơ sở dữ liệu ở nơi đầu tiên. Họ có một hệ thống cho việc này: Hệ thống tập tin. – tadman

+0

Tôi bắt đầu lưu trữ đường dẫn tệp, nhưng một số nghiên cứu về các phiên bản gần đây nhất của MySQL đã gợi ý rằng nó thực sự hiệu quả hơn để lưu trữ các tệp nhỏ (dưới 1 hoặc 2 mb) dưới dạng BLOB. Hình ảnh của tôi chỉ là một vài kb, vì vậy nó dễ dàng hơn nhiều để duy trì theo cách này. – hundley

+0

Sao lưu cơ sở dữ liệu đầy BLOB là một cơn ác mộng tuyệt đối. Nó đắt tiền để tái tạo những thứ này, tốn kém để sao lưu chúng, cực kỳ đau đớn để khôi phục chúng, và kích thích để phân chia chúng khi chúng trở nên quá lớn. Trừ khi bạn đang đối phó với số lượng dữ liệu không quan trọng, điều này sẽ thổi lên bạn cuối cùng. Các tệp trên đĩa có thể được sao chép dễ dàng bằng cách sử dụng một cái gì đó thô sơ như 'rsync'. Tương tự cũng không đúng cho MySQL. – tadman

Trả lời

5

JSON giả định utf8, do đó không tương thích với hình ảnh trừ khi chúng được mã hóa theo một cách nào đó.

Base64 gần gấp 8/6 lần số nhị phân (BLOB). Người ta có thể tranh luận rằng nó có thể dễ dàng phải chăng. 3000 bytes trở thành khoảng 4000 bytes.

Mọi người nên có thể chấp nhận mã 8 bit tùy ý, nhưng không phải mọi người đều làm. Base-64 có thể là sự thỏa hiệp tốt nhất và tổng thể tốt nhất để không phải xử lý dữ liệu 8 bit.

Vì đây là "nhỏ", tôi sẽ lưu trữ chúng trong một bảng chứ không phải tệp. Tuy nhiên, tôi sẽ lưu trữ chúng trong một bảng riêng biệt và JOIN bởi một id thích hợp khi bạn cần chúng. Điều này cho phép các truy vấn không cần hình ảnh chạy nhanh hơn vì chúng không bước qua các BLOB.

Về mặt kỹ thuật, TEXT CHARACTER SET ascii COLLATE ascii_bin sẽ làm, nhưng BLOB làm cho rõ ràng hơn rằng không thực sự có bất kỳ văn bản có thể sử dụng nào trong cột.

+0

Để làm rõ, bạn có gợi ý rằng tôi lưu trữ hình ảnh dưới dạng Base64 trong BLOB hoặc dữ liệu nhị phân và mã hóa trên mọi lần tìm nạp không? Đối với đề xuất của bạn với JOINing - đó là chính xác những gì tôi đang làm, cùng với một chỉ số Sphinx. – hundley

+0

Base64 trong suốt cuộc đời của nó. Sau đó, bạn không cần phải thoát khỏi bất cứ nơi nào. Vì vậy, có, Base64 trong một BLOB mà không mã hóa ngoại trừ INSERT ban đầu. Đây là ý kiến ​​của tôi_. –

+0

Thú vị, có lẽ tôi sẽ chụp ảnh đó. Nó chắc chắn sẽ tiết kiệm rất nhiều CPU kể từ khi tải xảy ra thường xuyên hơn nhiều so với chèn. – hundley

1

Tại sao bạn nên mã hóa base64 hình ảnh trên dây? Tôi nghĩ rằng bạn đang nhìn chằm chằm từ một giả định sai lầm.

+0

Bạn có thể làm rõ? Ngay bây giờ tôi đang gửi tất cả các hình ảnh như các đối tượng JSON được mã hóa Base64, với một số siêu dữ liệu (vì vậy máy khách biết phải làm gì với hình ảnh khi nhận được). Có cách nào để gửi các hình ảnh như các đối tượng nhị phân (không mã hóa) VỚI siêu dữ liệu? Điều gì về khách hàng POSTing một hình ảnh mới? Máy chủ của tôi sử dụng Node.js với Express cho HTTP, cũng như [ws] (https://github.com/websockets/ws) đối với một số tính năng của WebSocket. – hundley