2009-03-19 42 views
36

Đây là câu hỏi đã được hỏi trước đây (large-text-and-images-in-sql) nhưng chủ yếu cho dữ liệu sẽ được thay đổi. Trong trường hợp của tôi, dữ liệu sẽ được lưu trữ và không bao giờ thay đổi. Có vẻ hợp lý để giữ mọi thứ lại với nhau.Bạn có lưu trữ dữ liệu nhị phân trong cơ sở dữ liệu hoặc trong hệ thống tệp không?

Có bất kỳ lý do nào khiến tôi không nên lưu trữ dữ liệu nhị phân tĩnh trong cơ sở dữ liệu không?

Giả sử đó là một điều hợp lý để làm, có lợi thế nào để lưu trữ dữ liệu đó trong các bảng riêng biệt không? (Bạn có thể bắt đầu nhận ra bây giờ rằng tôi không phải là chuyên gia DB ...)

Làm rõ: Có thể sẽ không có nhiều hơn 10-20 người dùng nhưng chúng sẽ ở Hoa Kỳ và Vương quốc Anh. Dữ liệu nhị phân sẽ phải được chuyển trong mọi trường hợp.

Trả lời

32

Ưu điểm của việc lưu trữ dữ liệu trong DB là tận dụng các cơ chế bảo mật DB và giảm chi phí bảo trì (bản sao lưu, ...). Điểm bất lợi của nó là tăng tải DB và kết nối tiêu thụ (có thể tốn kém cho các máy chủ cơ sở dữ liệu được cấp phép trên mỗi kết nối). Nếu bạn đang sử dụng SQL Server 2008, FILESTREAM có thể là một lựa chọn tốt đẹp.

Nhân tiện, đối với ứng dụng web (hoặc bất kỳ ứng dụng nào khác có thể cần truyền trực tuyến dữ liệu), dữ liệu lưu trữ bên ngoài DB thường hợp lý hơn.

+2

Tôi không chắc làm thế nào để giảm chi phí bảo trì/sao lưu. Nếu bất cứ điều gì nó làm tăng chúng bởi vì thường sao lưu một cơ sở dữ liệu là tốn kém hơn và đòi hỏi hơn sao lưu một hệ thống tập tin. Bạn có thể xây dựng? – jrwren

+3

@jrwren Điểm của tôi là bạn không cần phải sao lưu các tập tin một cách riêng biệt và tự giữ chúng trong đồng bộ để đảm bảo tính toàn vẹn với các dữ liệu có trong bản sao lưu cơ sở dữ liệu. Nó * có thể * đơn giản hơn và rẻ hơn theo cách này hay cách khác tùy theo hoàn cảnh. –

8

Sự bất lợi lớn nhất nếu bạn lưu trữ BLOBS là mức tiêu thụ bộ nhớ. Bạn có thể tưởng tượng điều gì đã chọn * từ x sẽ làm cho hàng ngàn bản ghi với hình ảnh 45k trong mỗi không?

Như Mehrdad cho biết cũng có những lợi thế. Vì vậy, nếu bạn quyết định đi theo cách tiếp cận đó, bạn nên cố gắng thiết kế cơ sở dữ liệu của mình để hầu hết các truy vấn trả về ít kết quả hơn với dữ liệu BLOB trong chúng. Ví dụ, có thể tạo ra một mối quan hệ một cho một mục đích này.

+0

+1 Điểm tốt - có lẽ một lý do chính đáng để đặt các đốm màu trong bảng riêng biệt và nhận thông qua id? – paul

+0

Thành thật mà nói, tôi luôn sợ sử dụng BLOB, bởi vì tôi hút ở sql. Nhưng nếu tôi phải làm một mối quan hệ riêng biệt cho từng đốm màu. Khá nhiều bằng cách sử dụng nó khi tôi sử dụng tài liệu tham khảo cho các tập tin. Ngoại trừ những điều này sẽ được lưu trữ trong db. Lưu ý: xin vui lòng không làm điều này trong các ứng dụng web. – Vasil

+7

IMHO, nó không phải là một đối số hợp lệ. Thực hiện 'select * from x' là một ý tưởng tồi trong hầu hết các trường hợp, ngoại trừ trường hợp bạn cần sử dụng * mọi * cột của bảng trong ứng dụng của bạn. Đặt các đốm màu trong một bảng riêng biệt thậm chí còn tồi tệ hơn, bởi vì nó sẽ yêu cầu tham gia và làm phức tạp các yêu cầu. –

1

Đây có phải là chính xác những gì LOB hoặc CLOB hoặc .... được thiết kế không?

Chúng tôi đã sử dụng CLOB để lưu trữ các giao dịch thẻ tín dụng lớn cho một hệ thống hãng hàng không lớn.

Mức tiêu thụ bộ nhớ là thủ phạm lớn nhất của bạn.

HTH

cổ vũ,

5

Tôi nghĩ rằng điều này phụ thuộc vào các ứng dụng xây dựng của bạn. Nếu bạn đang xây dựng hệ thống CMS và việc sử dụng dữ liệu sẽ hiển thị hình ảnh trong trình duyệt web, có thể có ý nghĩa để lưu hình ảnh vào đĩa thay vì được đưa vào cơ sở dữ liệu. Mặc dù thành thật tôi sẽ làm cả hai, có thể cho phép thêm một máy chủ vào một trang trại mà không cần phải sao chép các tập tin trên khắp nơi.

Trường hợp sử dụng khác có thể là một đối tượng phức tạp, chẳng hạn như luồng công việc hoặc thậm chí là đối tượng kinh doanh có nhiều phụ thuộc lẫn nhau. Bạn có thể tuần tự hóa cả hai dạng này thành định dạng nhị phân hoặc văn bản và lưu chúng trong DB. Sau đó, bạn có được lợi ích của DB: ATOMIC, Sao lưu, v.v ...

Tôi không nghĩ mọi người nên sử dụng các truy vấn select * ngay từ đầu. Những gì bạn làm là cung cấp hai cách để lấy dữ liệu, Một phương thức trả về thông tin tóm tắt, thứ hai sẽ trả về blob. Tôi không thể tưởng tượng tại sao bạn sẽ cần phải trả lại hàng ngàn hình ảnh cùng một lúc.

+0

+1 Dành cho các ý tưởng. Giới thiệu về lựa chọn * từ phần. Bạn không cần phải viết truy vấn đó bằng tay. Một số ORM sử dụng các loại truy vấn này theo mặc định, vì vậy nếu ai đó không cẩn thận ... ouch. – Vasil

+0

Heh, bạn biết ORM nào sử dụng các truy vấn đó không? Tôi muốn tránh xa họ. nHibernate Tôi biết không – JoshBerke

+0

Tôi đã nhìn thấy trong một số khuôn khổ php, không thể nhớ lại. Nhưng kể từ khi họ đang ở trong một ứng dụng web, họ có thể nghĩ rằng chọn * là ít dữ liệu trên dây hơn chọn foo, bar, xúc xích. Tôi cá là họ không bao giờ nghĩ về BLOBS. – Vasil

1

Một số cơ sở dữ liệu (ví dụ: Postgresql) tự động nén các trường, có lẽ nhanh hơn khi đọc chúng trực tiếp từ db.Và cũng có thể, chương trình có thể đọc tất cả các lĩnh vực và hình ảnh trong một swoop.

+1

Vâng, nếu tôi từng sử dụng các đốm màu, nó sẽ là postgres. Bạn tiết kiệm trong băng thông. Nhưng dữ liệu phải được giải nén trong quá trình của ứng dụng tại một số điểm. – Vasil

+3

Nhiều đốm màu (hình ảnh, mp3, v.v.) về cơ bản vẫn được nén trước. – dkretz

2

Chúng tôi lưu trữ tệp đính kèm trong hệ thống của chúng tôi và bạn không thể thay đổi tệp đính kèm, vì vậy tôi nghĩ chúng tôi cùng trang w/dữ liệu "sẽ được lưu trữ và không bao giờ thay đổi". Chúng tôi đã quyết định cụ thể không phải để lưu trữ nó trong cơ sở dữ liệu. Chúng tôi đã làm điều này vì hai lý do, đơn giản và thời gian sao lưu/phục hồi.

Đơn giản trước tiên: Trong trường hợp của chúng tôi, các tệp đính kèm này được tải lên từ trình duyệt của người dùng cuối và đơn giản hơn là chỉ cần viết chúng vào thư mục (trên máy chủ DB) hơn sau đó truyền chúng xuống đường ống SQL. Có một bản ghi của chúng trong DB, nhưng DB chỉ chứa siêu thông tin về tệp đính kèm và tên của tệp trên đĩa (một hướng dẫn trong trường hợp của chúng tôi)

Trên mặt sao lưu/khôi phục: Các đốm màu này có thể sẽ trở thành một trong những phần lớn nhất trong cơ sở dữ liệu của bạn. Bất cứ khi nào bạn chạy một sao lưu đầy đủ bạn sẽ được sao chép các bit này hơn và hơn, mặc dù bạn biết sau đó không bao giờ có thể thay đổi. Đối với chúng tôi, có vẻ đơn giản hơn để có nhiều bản sao lưu nhỏ hơn và thực hiện xcopy của thư mục đính kèm với máy chủ phụ làm bản sao lưu.

1

Vấn đề hiệu suất ở đây là địa chỉ ở trên, vì vậy tôi sẽ không lặp lại nó. Nhưng tôi nghĩ rằng một mẹo hay nếu bạn đang lưu trữ những thứ sẽ được phát trực tuyến rất nhiều (chẳng hạn như hình ảnh/tài liệu trên trang web) là xây dựng trong hệ thống bộ nhớ đệm. Điều này có nghĩa là lưu trữ tất cả dữ liệu trong cơ sở dữ liệu của bạn, nhưng khi ai đó yêu cầu tập tin đó, hãy kiểm tra xem nó có tồn tại trên đĩa hay không (nếu không, lấy nó từ DB) và viết nó vào thư mục, sau đó truyền nó cho người dùng. Đối với yêu cầu tiếp theo đối với cùng một tệp, vì nó tồn tại trên đĩa, nó có thể được phục vụ từ đó mà không cần nhấn DB. Nhưng nếu bạn cần phải xóa các tập tin này (hoặc máy chủ web của bạn đi kapput!), Nó không quan trọng vì chúng sẽ được xây dựng lại từ DB khi mọi người yêu cầu chúng. Điều này sẽ nhanh hơn nhiều so với việc phục vụ từng yêu cầu cho cùng một tệp từ DB.

4

Tôi quen thuộc với một dự án OSS khá tốt đã đưa ra quyết định ngay từ đầu để lưu trữ hình ảnh trong cơ sở dữ liệu MySQL và được chứng minh là một trong 3 ý tưởng tồi tệ nhất mà họ đã đối phó. (Trầm trọng thêm bởi thực tế là "cấu trúc lại không thương tiếc" là ghét cay ghét đắng, nhưng đó là một câu chuyện khác.)

Trong số những vấn đề nghiêm trọng này đã gây ra:

  1. Vượt quá kích thước tối đa cơ sở dữ liệu hiệu quả (mysql). (Tổng không gian cần thiết cho hình ảnh vượt quá tất cả các không gian khác bởi ít nhất 2 đơn vị độ lớn).

  2. Tệp hình ảnh mất "độ nhạy" của chúng. Không có kích thước ngày vv trừ khi được lưu trữ (dư thừa) là ngày (yêu cầu mã để quản lý).

  3. Chuỗi byte tùy ý không xử lý độc đáo mọi lúc, để lưu trữ hoặc thao tác.

  4. "Chúng tôi sẽ không bao giờ cần phải truy cập hình ảnh bên ngoài" là một giả định nguy hiểm.

  5. Dễ vỡ. Bởi vì toàn bộ sự sắp xếp là không tự nhiên và nhạy cảm, và bạn không biết nó sẽ cắn ở đâu tiếp theo (góp phần vào tâm lý chống tái cấu trúc).

Lợi ích? Không có gì tôi có thể nghĩ đến, ngoại trừ nó có thể là con đường của sự kháng cự ít nhất vào thời điểm đó.

+0

Tôi giả định quyết định tồi tệ là để lưu trữ các đốm màu. Chính xác? – paul

+0

Đúng - làm rõ. – dkretz

+1

Một lợi ích đáng kể là tính nhất quán của dữ liệu: với các khóa thích hợp, "các tệp" không thể xóa được nếu không có dữ liệu meta và ngược lại. Đối với các tệp đĩa không có ràng buộc như vậy và việc thêm/xóa các tệp và dữ liệu meta của chúng là một ứng dụng (hoặc hàm) riêng biệt phải được thiết kế, triển khai và sử dụng. – NVRAM

6

Giải quyết vấn đề từ quan điểm nguyên tắc, cơ sở dữ liệu quan hệ (chủ yếu) có để lưu trữ dữ liệu có cấu trúc. Nếu bạn không thể tạo điều kiện truy vấn hoặc tham gia vào một phần tử dữ liệu, nó có thể không thuộc về cơ sở dữ liệu. Tôi không thấy một hình ảnh BLOB được sử dụng trong một mệnh đề WHERE, vì vậy tôi muốn nói giữ nó bên ngoài cơ sở dữ liệu. Mặt khác, CLOB có thể được sử dụng trong các truy vấn.

+0

+1 khía cạnh thú vị – paul

+2

Có lẽ chúng tôi sẽ không sử dụng số điện thoại trong mệnh đề WHERE, vì không thường xuyên tìm kiếm bất kỳ thứ gì theo số điện thoại (trừ khi bạn đang làm việc trên hệ thống tra cứu ngược). Điều đó nói rằng, chúng tôi lưu trữ số điện thoại trong DB, không phải trong các tệp bên ngoài mặc dù nó hiếm khi được sử dụng làm điều kiện tham gia hoặc bộ lọc. Ý tôi là lý do đó là không đủ để loại bỏ khả năng lưu một hình ảnh bên trong một DB quan hệ. – Seb

+2

Nhưng bạn * có thể * tạo điều kiện truy vấn trên số điện thoại hoặc sử dụng nó để tham gia, điều mà bạn không thể làm một cách hợp lý với cột BLOB. –

8

Tất cả điều này nói về việc "chọn * từ bảng" gây ra các vấn đề về bộ nhớ và/hoặc băng thông lớn khi bảng có LOB trong đó không phải là vấn đề. Tất cả những gì được trả về là một con trỏ tới LOB được đề cập. Không đủ danh tiếng để đưa ra nhận xét trong bối cảnh, nhưng mọi người nhìn vào điều này nên biết nó KHÔNG phải là một vấn đề.

+0

"LOB" là gì? –

+0

@Matthew Tôi nghĩ anh ấy có nghĩa là [Large OBject] (https://docs.oracle.com/cd/B28359_01/appdev.111/b28393/adlob_glossary.htm#sthref1212). –

3

Bất kỳ ai có ý tưởng lưu trữ hình ảnh (hoặc tài liệu nhị phân khác) trong cơ sở dữ liệu không phải là người tôi rất hài lòng. Cơ sở dữ liệu có nghĩa là để lưu trữ dữ liệu INDEXABLE, DISCRETE [chủ yếu?]? Không phải BLOB của dữ liệu nhị phân vô nghĩa. Nếu bạn đã từng làm việc với BLOB cho dữ liệu nhị phân, thì bạn đã biết điều này.

Bạn nên lưu trữ tham chiếu đến tệp trong hệ thống tệp. Thực hành tốt nhất trong số đó là tên tệp, không phải là đường dẫn tuyệt đối (hoặc thậm chí là tương đối).

+0

Theo như "SELECT *" đi, tôi nghĩ rằng trong hầu hết các trường hợp hợp lý của nó. Tôi đã xây dựng một ORM sử dụng nó trên tất cả, nhưng bạn có thể ghi đè lên điều đó. Và nếu bạn thực sự quan tâm đến hiệu suất, bạn có thể bỏ qua hoàn toàn ORM và sử dụng trình tạo truy vấn ORM sử dụng phía sau hậu trường. Vấn đề là cuộc trò chuyện này không liên quan gì đến "SELECT * ...". Nó phải làm với thiết kế cơ sở dữ liệu âm thanh. –

+0

Làm cách nào để bạn truy xuất tệp nếu tên tệp chỉ được lưu trữ chứ không phải đường dẫn? Bạn sẽ có một thư mục mà tất cả các tập tin sẽ được đặt? Điều gì sẽ xảy ra nếu có hàng triệu tệp trong db của tôi? – Vincnetas

+0

Trong cấu hình ở đâu đó trong ứng dụng, bạn nên lưu trữ đường dẫn đến thư mục chứa các tệp. Nếu bạn lo lắng về việc có quá nhiều tệp trong cùng một thư mục, hãy tạo đường dẫn động. Thông thường bạn có thể sử dụng một ID cho điều này, chẳng hạn như/path/to/files/{ID here} /filename.ext. Bạn chỉ cần lưu trữ tên tệp. –

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