在DB中存储图像 - 联网桌面应用程序

时间:2009-12-07 18:54:53

标签: c# .net database image

  

相关:   Storing Images in DB - Yea or Nay?

在阅读上述问题后,似乎使用数据库进行图像存储的首选方法是仅存储数据库中的文件路径。但是,大多数答案似乎都集中在Web服务器上。

就我而言,我正在开发一个桌面应用程序,该应用程序将在Intranet中的多台计算机上使用。专用服务器将托管数据库,其中包含与在各种设备上执行测试相关的信息。

图像需要以某种方式存储在服务器上。在这种情况下,将图像存储在数据库中是否是正确的方法,甚至是唯一的方法?

优点:

  • 备份仅限于数据库。
  • 无需打开服务器的文件系统到网络。
  • 服务器信息访问的单一协议。
  • 受保护的文件访问权限。 (用户无法进入并删除所有图像)

缺点

  • 如果图像太多,将来会出现性能问题。

编辑:如标记中所述,应用程序是用C#/ .NET编写的。如果在这种情况下将图像写入文件系统是一个选项,我可以使用一些帮助来理解这是如何完成的。

编辑2:正如下面的评论中详细阐述的那样,现在我假设一个MySQL数据库,尽管SQL Server 2008的FileStream功能可能会改变它。

同样在我的情况下,图像将经常添加,并且在此之后可以被认为是只读的,因为它们永远不应该被更改,并且只在需要时被读出。图像可能很小(每个约70k),我也在考虑服务器上的其他二进制格式存储,每个文件大约20k,我可以使用相同的方法进行存储和检索。

11 个答案:

答案 0 :(得分:7)

我建议将这些文件保存在文件系统的磁盘上,而不是数据库中。文件的文件系统,关系数据的数据库等

按网络服务提供

考虑通过在该数据库计算机上托管Web服务/应用程序,将这些图像传送到您的桌面应用程序。该应用程序的工作是仅提供图像。使用ASP.NET应用程序在该计算机上设置Web服务器。让.ashx处理请求并流式传输二进制映像。像这样:

http://myserver/myapp/GetImage.ashx?CustomerID=123&ImageID=456

安全性

如果内部网安全性存在问题,则可以确保用户经过身份验证并获得对映像的读取权限。审计跟踪也可以在这里实施。

文件系统安全性

关于这些图像的安全性,请考虑NTFS为您提供了许多措施,以确保只有经过授权的人才能根据需要读取/删除/放置文件。然后,任务是定义这些角色并实现Windows安全组。

未来需求

此方法允许您从Intranet上的任何位置安全地使用这些图像。也许这个应用程序会在某个时候迁移到Web应用程序?特征请求可能来自客户,其中Web解决方案是合适的吗?

这可能听起来有点过分而不是从数据库中读取blob,但从安全角度来看它很棒。考虑您的客户和患者对隐私和安全的期望。

<%@ WebHandler Language="C#" Class="Handler" %>

public class Handler : IHttpHandler {

public void ProcessRequest (HttpContext context) 
{
    //go to the DB and get the path for this ID.
    string filePath = GetImagePath(context.Request.QueryString["ImageID"]);

    //now you have the path on disk; read the file
    byte[] imgBytes=GetBytesFromDisk(filePath);

    // send back as byte[]
    context.Response.BinaryWrite(imgBytes);
}

答案 1 :(得分:4)

如果您可以使用Sql Server 2008,请查看此链接

Saving and Retrieving File Using FileStream SQL Server 2008

答案 2 :(得分:3)

我认为答案是没有正确的答案。与编程(和生活)中的大多数事情一样,它取决于

以下是存储在DB中的优点和缺点:

<强>赞成

  • 在您的应用程序中轻松备份,管理和一站式购买数据
  • 您的应用中较少的依赖关系和较少的移动部件。 KISS原则
  • 适用于1GB以下的小文件。
  • 嘿,它是一个数据库,因此可以在事务内部进行保存,如果存在网络问题则可以回滚
  • Sharepoint和TFS将所有内容存储在数据库中并且工作正常。 即使是大男孩也会这样做
  • 安全性可以通过应用轻松控制,而不涉及文件/文件夹权限

<强>缺点

  • 吃掉数据库空间
  • 如果做得不对,可能会影响效果
  • 如果总是存储大文件(> 1GB),除非在SQL Server 2k8中使用Filestream,否则不是一个好主意
  • 要求你实施一个体面的缓存策略(尽管你可能还是想要这个)
  • 文件系统感觉比数据库更自然,更容易手动替换/查看文件。

我想当谈到你的情况时,我会倾向于在数据库中存储的简单性

答案 3 :(得分:2)

架构的角度来看,通过将解决方案分为两部分,您将获得最佳性能:数据库服务器和图像服务器

您既可以将行大小保持在较小的位置,也可以将事务环境与内容分开。 SQL Server和mysql的关系数据库将支持大型BLOB,但不针对它们进行优化。

大多数人将“图像服务器”等同于“Web服务器”,因为它们在Web应用程序上工作,因此具有事实上的图像存储库(本地磁盘上的目录)。但是,这不是 的情况。可以通过任何协议从任何位置提供图像。

您提到了C#/ .NET平台和Intranet。我们可以假设一个Windows环境,可能是Active Directory吗?

如果是这样,普通的vanilla文件服务器可能是您的图像服务器。设置文件共享,为此应用的所有用户设置读取/创建(但不修改/删除)权限,将UNC路径存储在数据库中的某个位置(因此,如果您决定使用,则无需重新部署应用程序重新定位它,并让您的客户端应用程序使用像Guid这样可靠的东西生成唯一的相对路径。

它不像Web服务那样优雅(这是我的首选方法),也不像纯数据库方法那样免维护,但我对这个主题的印象是你的预算紧张交付截止日期,Windows或NFS文件服务器比完整的Web服务器更便宜,更容易,更快速地设置和维护(包括备份),因此它可能正是您在这里寻找的。

大多数企业已经拥有文件服务器,因此通常不需要任何新的基础架构。但即使你不这样做,我也看到文件服务器运行在旧的翻新工作站上 - 这不是很花哨,但在低流量的环境中,它可以完成工作。

如果选择这种方法,我会在文件共享上建议某种目录结构,以简化备份,存档等。例如:

\\ImageServer\MyAppRepository\yyyy-mm\{image-file-name-or-guid}.{ext}

希望有所帮助。

答案 4 :(得分:1)

我们说的是多少张照片?它们是否经常独特/更新?如果没有,您可以将图像打包到您要分发到多台计算机的客户端吗?

就个人而言,我会避免将图像存储在数据库中,而是像你所说的那样存储文件路径。

如果您已阅读所有其他类似问题(Thisthisthis),但仍在询问这是否是一个好主意,那么也许您的问题是不同,这将是一个好主意。

答案 5 :(得分:1)

我的公司开发了一个Windows窗体c#应用程序,它将图像存储在一个数据库中,效果非常好。自2003年以来,我们一直在积极地使用它,并且在系统中有大约150个数据。

首先,我要说这不是最佳的性能架构。我们在保持数据库统计信息最新并保持索引正确调整方面遇到了一些问题。我们基本上必须每月重新索引系统。您需要知道,大多数RDBMS服务器的内置优化系统没有为大型二进制对象集合设置。

我们选择将图像放入数据库的原因是数据库级复制。我们的系统遍布五个州的七个办事处,我需要将数据同步到每个站点。因此,我在每个站点和公司办公室之间建立了VPN,并在数据库上设置SQL合并复制。通过这种方式,我可以同时同步数据和图像,只需在办公室之间打开一个频道。 所以,我想说数据库中的图像在大多数情况下不是最佳解决方案,但它符合我们的要求。

答案 6 :(得分:0)

如果您正在寻找替代方案,我的最爱之一是十行HTTP POST文件上传处理程序(PHP,.NET,Java等)+一个网络服务器。当脚本验证最大文件大小时,可能会提取宽度和宽度。高度,它在数据库中插入一行。检索不需要通过脚本。标准文件托管将起作用。这将需要您打开端口80.您不需要使用SOAP或任何东西使其复杂化。常规上传处理程序可以完成这项工作。

然后是WebDAV,沿着相同的路线。当然,使用此方法,您必须监视文件系统并相应地调整数据库。您可以使用轮询服务或挂钩到文件系统事件。实际上,您还可以注入ISAPI过滤器或Apache处理程序来执行数据库更新。

您可以使用FTP。为ProFTPd添加一个扩展,它将更新数据库并使所有内容保持同步。

避免将图像数据放入表中的方法很多。

如果您选择数据库解决方案,请确保将BLOB分成单独的表。如果可以,单独的表空间/设备/分区。或者,使用Oracle并忽略我所说的一切。

答案 7 :(得分:0)

我认为存储图像的位置并不重要。选择最简单的方法。但是你应该有一个架构,如果它被证明是错误的,你可以改变它。

为了实现这一点,我将把数据和图像存储放在Web服务接口之后。选择一项技术 - 没关系。所有对数据(和图像)的访问都是相同的 - 通过Web服务。

通过执行此操作,您已从桌面应用程序中分离存储数据的位置。桌面应用程序并不在意。它只知道某个地址的服务器可以获取数据。

然后将数据和图像存储在任何地方。为您选择最简单的东西。如果你最终遇到问题,那么(并且只有那时)你应该增加额外的复杂性才能解决问题。好消息是额外的复杂性和工作根本不应该影响桌面应用程序。您可以在服务器上进行更改,而无需部署新版本的桌面应用程序。

答案 8 :(得分:0)

将Amazon S3存储用于您的图像

只需将GUID或其他文件名存储在DB

亚马逊简单,快速,便宜。安全等等

它可以很好地扩展,并可选择直接从S3提供类似边缘服务的CDN

随着时间的推移,将图像存储在数据库中似乎总是变成一场噩梦

答案 9 :(得分:0)

在我看来,你想做的事情就像Infovark做的那样。

他们使用Firebird,我会给你一个关于Firebird的链接和storing image

答案 10 :(得分:0)

您应该尝试MS SQl 2008,它附带一个Type:FileStream,它会自动将blob存储在文件系统中。