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ẻ.
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ẻ.
Ả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)
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
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
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.
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
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.
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:
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:
Hi vọng nhận được lời giải thích rõ hơn từ cậu.
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.
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 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.
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
Tớ sẽ conclude thành 2 point dưới đây:
Hope it helps!
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.
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.
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)
Đâ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 ?
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
Đố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