代码之家  ›  专栏  ›  技术社区  ›  Chaitanya

提取图像存储设计方案

  •  1
  • Chaitanya  · 技术社区  · 16 年前

    这是一个设计上的疑问,我收集了1500个图片,这些图片将显示在一个ASP.NET页面上,显示的图片各不相同,这些图片的数量将随着时间的推移而增加。

    A.)在数据库上放图像是个好主意,但是从数据库中获取图像的往返时间可能很长。

    b.)将所有图像放在一个目录上,并在其上安装一个虚拟文件系统,应用程序是否可以从该目录访问这些图像?

    在传统的数据库中,我们是否有任何特别的设计策略来以最少的往返时间获取图像,是否存在除了使用传统数据库之外的任何解决方案?

    编辑1: 每幅图像每12小时都会被它的新条目替换一次,所以就我所能想到的来说,将它们放在数据库中可能不是一个好主意,但是使用数据存储和索引这些图像会有多好呢?

    编辑2: 是的,我们计划在集群上运行应用程序。如果我们尝试使用一个数据存储(如果它是一个很好的选择),那么它是否与C&ASP.NET兼容?

    PS:我使用SQL Server来存储这些图像。

    5 回复  |  直到 16 年前
        1
  •  2
  •   JoeGeeky    16 年前

    以前的评论都很好…在没有非常具体的要求的情况下,我们必须作出广泛的概括来说明您的选择。下面是几个例子。

    • 如果 原始速度 是你需要的,那么平面文件就是一个明显的赢家。无论您使用的是Apache还是IIS,它们都经过了优化,可以很快地为基于静态文件的内容提供服务。高性能站点都知道这一点,并且会在考虑动态处理的情况下存储大部分内容,但随后会定期或事件驱动的方式向其Web场“发布”所选的动态内容片段(静态版本)。尽管它需要一点编排,但是它可以很便宜地完成,并且可以真正减少数据库服务器、后端网络等的负载。作为一个简单的示例,将其发布到一个文件夹中,动态评估该结构的根。准备好发布更新后,编写一个新文件夹,然后更改根路径。没有停机时间,便宜又容易。在相关的注释中,从后端存储中提取所有这些信息将需要您将这些内容加载到内存中。这最终将转化为垃圾收集中的更多时间,从而意味着应用程序速度较慢,即使您使用的是多处理器/核心园艺。

    • 如果你需要 细粒度控制 对于如何组织/公开图像,文件夹可能不是最合适的。例如,如果您需要组织单个用户的图像,并且需要跟踪图像周围的大量元数据,那么数据库可能是一个很好的适合。有了这一点,您的数据库团队可能会因为它而讨厌您,因为从数据库管理的角度来看,这会带来许多挑战。此外,如果您使用的是ORM,那么您可能会遇到一些问题,并且可能会发现由于隐藏的代理对象、二级缓存等原因,内存占用增长到了不可接受的水平。这一切都可以减轻,因此请注意并确保您对应用程序进行了配置。有鉴于此,结构化存储(如DB)更适合于此用例。

    • 考虑到 安全 …根据这些图像所代表的内容,平面文件不可避免地会引起对规范化攻击、可浏览文件夹结构的强力枚举、重放cookie、URL、视图状态等的关注。如果使用自定义的基于角色或基于声明的安全模型,则可能会发现使用平面文件会变得有些困难,因为将文件系统安全约束映射到逻辑/上下文安全约束。像这样的问题常常让我倾向于结构化商店。

    所提出的缓存概念是一个很好的概念,它可以帮助您在实际访问数据库的频率方面创建一些中间地带,尽管它不会帮助您解决与内存消耗、GC等相关的问题。您可以使用内置的缓存机制,但如果您负担得起(例如ncache、scaleout等),支持后备存储的缓存/网格会更好。它们提供了很好的可伸缩性/缩减性,还可以用来卸载会话状态、视图状态等的存储。

    希望这有帮助。

        2
  •  1
  •   Jamiec    16 年前

    你基本上有两个选择

    1)将二进制文件存储在数据库中。varbinary(max)字段将是一个很好的数据类型选择。 2)将存储在磁盘上的映像的路径存储在数据库中。对于数据类型,nvarchar(max)是一个很好的选择。

    当然,这两种解决方案都有优点和缺点。如果不了解您的需求,就很难建议哪种方法是最好的。

        3
  •  1
  •   Geoff Appleford    16 年前

    我不喜欢将图像存储在数据库中,而是只存储指向正确图像的链接(路径/文件名/id等)。

    然后,如果您实现一个httphandler来提供图像,那么您可以将它们存储在您喜欢的任何位置。下面是一个非常基本的实现:

    public class myPhototHandler: IHttpHandler
    {    
    
        public bool IsReusable {
            get { return true; }
        }
    
        public void ProcessRequest(System.Web.HttpContext context)
        {
    
                if (Context.User.Identity.IsAuthenticated) {
                    var filename = context.Request.QueryString("f") ?? String.Empty;
                    string completePath = context.Server.MapPath(string.Format("~/App_Data/Photos/{0}", filename));
                    context.Response.ContentType = "image/jpeg";
                    context.Response.WriteFile(completePath);             
                }
    
        }
    
    }
    

    有关设置处理程序的重要资源,请签出 this blog post 以及其他相关岗位。

        4
  •  0
  •   Snives    16 年前

    我不会对你的解决方案过于复杂。在数据库中存储图像的缺点是数据库膨胀和备份的存储需求,特别是当图像只适合12小时时。如果有疑问,请保持简单,所以当需求发生变化时,无论如何您都没有投入太多时间。

    这就是我在网站上做的。

    • 将图像存储在文件夹中。
    • 如果要控制用户看到的文件名,或使用条件逻辑,请使用httphandler提供图像,否则只需在img标记中使用其完整路径和文件名。
    • 如果你说的是大容量的大型网站,也许可以考虑使用内容交付网络。
        5
  •  0
  •   Michael Petito    16 年前

    您是否考虑过缓存图像以减少往返于SQL Server的时间?缓存可能适用于浏览器(通过 HTTP Headers )和/或为图像提供服务的HTTP处理程序(通过 System.Web.Caching )

    在SQL Server中存储图像很方便,因为您不必担心维护指向文件系统的指针。但是,数据库的大小显然要大得多,这会使备份和维护更加复杂。您可以考虑在数据库中为图像表使用不同的文件组,或者一起使用单独的数据库,这样就可以维护与图像数据分离的行数据。

    使用SQL Server还意味着您可以轻松地选择并发控制、分区和复制(如果它们适合您的应用程序)。