Lưu ảnh trực tiếp trong DB

Hello Mọi người,

Em đang làm thử 1 trang web bán trà sữa. Mọi người cho em hỏi là có nên lưu ảnh trực tiếp vào DB không ạ? Nếu không thì em phải lưu như thế nào ạ? (ngoại trừ lưu path của ảnh).

Em cảm ơn,
Buổi tối vui vẻ.

6 Likes

Ảnh không nên lưu trực tiếp vào database, database chỉ nên lưu text. trong database lưu đường dẫn tuyệt đối của ảnh. Ảnh sử dụng dịch vụ của bên khác VD : google drive API, firebase storage, AWS S3, … (daynhauhoc sử dụng AWS S3) hoặc ảnh nhỏ, ảnh cố định VD : logo, icon, … thì bạn mã hóa ảnh thành base64 rồi lưu text này vào DB.

Edit : nên lưu đường dẫn tương đối cho ảnh nếu ảnh đó ở lưu trong project (như @kisuluoibieng đã giải thích)

52 Likes
  1. say no với chuyện lưu file vào db trong bất kì trường hợp nào
  2. lưu file và luôn lưu đường dẫn tương đối, bạn cũng nên nhớ là máy bạn code là một chuyện, server deploy lại là một chuyện. Đường dẫn tương đối là đang xét tương đối với context như thế nào, khi thay đổi context thì chỉ cần cấu hình lại mà thôi
47 Likes

Mình nghĩ nên lưu đường dẫn tuyệt đối, vì sẽ có trường hợp như này : VD : web có 1 ảnh là

~/images/img123.png, thẻ <img tại trang home sử dụng ảnh này là ../images/img123.png (path được load lên từ database), trang login lại muốn sử dụng ảnh đó với đường đẫn đúng phải là ../../../..images/img123.png nhưng lúc này load từ database lên lại là ../images/img123.png

20 Likes

Bạn đã nghĩ sai rồi nhé
Trong project của bạn, có thư mục ~/images/123.png (tức là thư mục image ngay bên trong thư mục gốc của project)

thay vì bạn gọi file hình đó bằng những trên vẫn ra, nhưng nó lại không thống nhất một công thức nào cả.
trong trường hợp này, bạn nên lưu trong database là images/123.png
khi sử dụng, tất cả các case đó đều sử dụng là /images/123.png là đường dẫn tương đối tính từ thư mục gốc (thực tế thì trình duyệt hiểu là hostname/images/123.png)
hoặc khi bạn muốn sử dụng nó như đường dẫn tuyệt đối thì ngu_canh + / + image/123.png
ví dụ ngữ cảnh là thư mục gốc của localhost localhost/images/123.png, hoặc là thư mục gốc của trang daynhauhoc daynhauhoc.com/images/123.png, hoặc chỉ là sub path /images/123.png

dù cho file của bạn ở bất kì đâu, bạn chỉ cần gọi những công thức như trên là được, và tất cả cái đó đều là đường dẫn tuyệt đối, lưu là lưu tương đối, nhưng khi sử dụng thì gắn context cho nó thì nó sẽ thành tuyệt đối
thay vì bạn phải lưu localhost/images/123.png thì sẽ không sử dụng được khi deploy

50 Likes

lưu ảnh vào db thì mã hóa ảnh dưới dạng text nhưng mà cũng nên hạn chế
xét về web bán trà sữa cũng k nhiều hình ảnh lắm có thể lưu được tui nhiên khi load dữ liệu sẽ làm mất nhiều thời gian vì decode và load hình ảnh lên giao diện, giải pháp nên lưu đường dẫn tương đối đơn giản và hiệu quả cao.

43 Likes

nên lưu tên, hoặc id (unique) , dựa vào giá trị đó bạn sẽ tạo 1 file để show url ảnh, ví dụ get-img.php?id=ID_SAVE_IN_DB . rồi trong file đó bạn xử lí để hiện link ảnh, b có thể hiển thị ảnh bạn lưu ở bất cứ đâu driver, dropbox, mega… nếu return về link ảnh dạng text thì dùng curl để get, ko thì set header để reponse dưới dạng ảnh luon chỉ việc ném vào thẻ img

46 Likes

SQL Server thì có cho lưu ảnh.
Kích thước trường ảnh là 16 byte. Như vậy dự đoán nó đã lưu ảnh xuống file riêng và chỉ lưu lại ID ảnh trong table.

46 Likes

Theo quan điểm của mình lưu ảnh sẽ có nhiều loại nhưng mình dùng 2 kiểu chính:

  1. lưu ảnh dưới dạng đường dẫn tương đối, ảnh sẽ ko lưu trực tiếp vào db mà lưu ra folder đưuọc setup sau đó theo đường dẫn mà trỏ đến.
  2. là có lưu ảnh trong db các nhà mạng vẫn hay dùng với ảnh CMT: lưu dưới dạng BLOB. database có 1 kiểu dữ liệu là blob hoặc byte tùy db cho phép lưu ảnh dưới dạng stream data.
16 Likes

Hi @tieuthien.cntt
Cậu có thể giải thích thêm về cách 2 mà cậu đề cập ở dưới đây được không?

Tớ muốn nghe một chúc background và phân tích về cách này:

  • Nhà mạng nào dùng cách này vậy cậu? :smile:
  • Về đề cập “database có kiểu dữ liệu blob hoặc byte tùy DB”, với “byte”, có phải ý cậu là BYTEA của postgreSQL?
  • Ưu điểm của cách này là gì vậy? :smile:
    Tớ có nghía qua ảnh thẻ của tớ có kích thước của nó là 176kb. Để dễ hình dung, kích thước của nó bằng 3 lần page này.
    Cá nhân tớ không nghĩ 1 record có độ lớn cồng kềnh như vậy là tốt cho việc tìm kiếm trên DB, khi cậu phải đưa một vài quyển sổ tay khắp network mỗi lần ai đó muốn lấy ảnh nào đó, tái tạo lại từ blob sang ảnh, rồi đưa vài quyển sổ tay đi lên giao diện 1 lần nữa :smile:

Hi vọng nhận được lời giải thích rõ hơn từ cậu.

41 Likes

Thực ra đó cách nghĩ của tuỳ người. Còn thực tế khi làm db hay dữ liệu họ đều có 1 cách đánh giá như sau:
1 dữ liệu đó có quan trọng hay ko? Nếu quan trọng ng ta ko ngần ngại lưu vào db cái đó để đảm bảo tính ok của dữ liệu. Và ảnh cmt nó ko có gì gọi lf mang sổ tay hay như nào cả.
2 là nhà mạng vietnamobile vinaphone và mobifone đều làm vậy.

12 Likes

Về vụ sổ tay, ý tớ là cái ảnh của cậu có kích thước tương đương với 1 cái sổ tay, cho cậu dễ hình dung :smile: Point của tớ là dữ liệu đó rất lớn, phòng TH cậu chưa hiểu.

Tớ đồng ý với cậu là tùy bài toán, cậu cần thiết kế khác nhau. Tuy nhiên, tớ sẽ diễn đạt lại ý trên của cậu (chính xác hơn là ý tớ hiểu về bài toán của Vinaphone/Mobile phone) như sau:

Vấn đề không phải dữ liệu đó có quan trọng hay không, vấn đề là yêu cầu về tính toàn vẹn dữ liệu.
Trong bài toán của Vinaphone, sự toàn vẹn dữ liệu xác thực rất quan trọng. Nếu 1 user mới được tạo ra, nó phải có ảnh CMT ngay lập tức, nhằm phục vụ xác thực.
Việc lưu trữ ảnh ở 1 external server khác có thể dẫn tới sự không toàn vẹn dữ liệu, khi ảnh đó có thể bị mất khi external server gặp vấn đề.

Tớ kỳ vọng sự giải thích cụ thể như vậy, hơn “dữ liệu đó quan trọng, nên nó được lưu vào DB” - quá abstract và khó thuyết phục. Và với vấn đề này, thiết kế đưa ảnh vào DB là hợp lý.

Cảm ơn cậu về mấy cái tên này nhé, tớ đoán chỉ trong TH CMT, sử dụng nhằm mục đích xác thực và yêu cầu cao về sự toàn vẹn dữ liệu xác thực, họ lưu ảnh như vậy. Chắc chắn in general, việc lưu ảnh trên DB ảnh hưởng rất lớn tới network consumption và performance.

Đây không phải vấn đề cách nghĩ của từng người đâu cậu.
Thiết kế là thứ được đưa ra để giải quyết vấn đề. Nếu thiết kế không có lý và giải quyết vấn đề, nó là rác rưởi.
Không có thứ gọi là “cách nghĩ từng người” để giải thích cho quyết định design.
Cậu không nên dùng cụm từ đó khi giải thích về quyết định thiết kế. Tất cả bọn tớ đều reasonable, và bọn tớ muốn nghe những thứ reasonable.

45 Likes

Thực ra thiết kế hay như nào cũng là cách nhìn nhận đánh giá của từng người. Còn ảnh lưu db mà suy rộng thì có nhiều giải pháp lắm. Còn đề xuất cách làm là để ng dùng lựa chọn tuỳ theo mục đích hệ thống của họ. Còn ảnh trc khi lưu vào db đều là ảnh quan trọng và tối giản đều đc resize trc khi lưu thôi. Còn nếu nói đến tốn network thì những cái upload download mới lo ngại đối với file lớn. Mình làm nhiều hệ thống r nội tại server của họ đầu tư rất mạnh nên ko có nhiều vde lắm

15 Likes

@Suong_Nguyen:

Tớ sẽ conclude thành 2 point dưới đây:

  • Best practice cho việc lưu trữ ảnh là lưu vào 1 nơi khác, và lưu địa chỉ của ảnh đó vào trong DB. Nó làm cho kích thước 1 record của cậu nhỏ đi, và cậu sẽ có rất nhiều benefit cho việc đó.
  • Nếu cậu có lý do đặc biệt, và cậu biết cậu đang làm gì, cậu có thể cân nhắc lưu cả ảnh vào trong DB.

Hope it helps!

46 Likes

Nếu ảnh đó là public, ai cũng truy cập access được thì lưu path cho nhanh.
Anh làm một số hệ thống enterprise nó ko cho public list ảnh ra ngoài, lưu trên cloud hay localdisk phải có cơ chế mã hóa đàng hoàng. Muốn lấy được ảnh phải xác thực có quyền access đàng hoàng. Trong trường hợp đó lưu ảnh trong db là dễ implement nhất.

49 Likes

Trên kia người ta nói là làm web bán trà sữa ông ơi, chỉ là không hiểu vì sao bạn đó lạ không muốn lưu path của hình thôi.

45 Likes

Từ lúc comment trên topic này xong, mình không có theo dõi lại topic, nay xem lại thì không ngờ lại có người đi xa như vậy, vẫn nghĩ việc hình ảnh lưu vào db là bình thường, còn đặt ra giả thiết nếu lưu ảnh ở external server tạch con server thì sao

Comment này không nhắm đến ai, chỉ muốn có chút chia sẻ thế này

Việc làm được một tính năng gì đó chạy được, không có nghĩa là giải pháp đó chấp nhận được
Thông thường, dự liệu lưu trong database khá ít khi lên đến kB cho mỗi record
Việc lưu ảnh vào database, sẽ làm cho data đó lớn lên rất nhiều, làm cho băng thông giao tiếp giữa database và lớp code cũng tăng theo, các bạn cũng nên nhớ,
việc serve file hình 1 MB qua nginx nhẹ nhàng hơn việc đọc từ db ra cái hình 100KB rất nhiều
Việc database phải đọc lượng lớn dữ liệu, rồi nó lại chuyển cho code rồi lại chuyển cho gateway/proxy/web server cũng cần nhiều tài nguyên xử lý hơn
Với những file thường sử dụng thì cache cũng dễ giải quyết hơn nhiều với static file
Cả con server dễ chết hơn hay database service dễ chết hơn
File trên server dễ bị mất hay crassh hay không toàn vẹn hơn hay database dễ bị phát sinh hơn
Việc replicate, backup hình khi lưu file với lưu db và file, cái nào dễ hơn
Xoay quanh việc này còn cả khối vấn đề có thể phát sinh, các bạn chưa thấy không có nghĩa là không có
không ai khuyến khích làm những cái trò như vậy trong database (trừ những trường hợp đặc biệt, nhưng làm pet project thấy làm được thì không phải trường đặc biệt đâu)

56 Likes

Đâu phải chỉ lưu vào database mới bảo mật đâu bác. Nếu lưu cả ảnh, video vào database thì database sẽ rất nặng. Mình thấy hosting người ta cho thuê dung lượng chỉ vài chục MB, đến vài trăm MB thôi.

làm sao bác biết được ?

4 Likes

Thực ra các nhà mạng đó lưu và xử lý vì bên mình là đối tác đơn vị tạo và bán sản phảm cho bên nhà mạng. Mình cũng đã làm cho các đối tác đó cũng trong ngành gần 10 năm r. Quan điểm mình là show giải pháp cho mọi ng lựa chọn còn cách làm nó phù hợp phải xem tuỳ hệ thống và ng quyết định bạn ah

2 Likes

Đối với mình, mình vẫn ưu tiên giải pháp lưu data dạng binary (hình ảnh, document, âm thanh,…) lên storage services như S3 hay cùng lắm thì một ổ cứng có dung lượng lớn. Lý do là vì việc query data + hình dưới db sẽ kéo thời gian query lâu hơn. Việc backup, migrate, bảo trì hệ thống cũng phức tạp hơn. Đặc biệt là backup/restore. 1 db 20 tables, mỗi table khoảng 1m records dump ra cũng gần 2GB rồi, lưu cả binary data thì vài chục GB dump là thường. Tuy nhiên nếu ít lưu binary hay file binary chỉ là optional như thumbnail trong một ô sản phẩm thì lưu dưới db vẫn OK

39 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?