在数据库上存储媒体文件的最佳方法是什么?
我想在数据库中存储大量声音文件,但是我不知道这是一个好习惯。我想知道这样做的利弊。
我还考虑了与这些文件建立"链接"的可能性,但是也许这将带来比解决方案更多的问题。对此方向的任何经验都将受到欢迎:)
注意:数据库将是MySQL。
解决方案
一个简单的解决方案是仅将文件的相对位置存储为字符串,然后由文件系统处理。我已经在一个项目中尝试过(我们正在将Office文件附件存储到调查中),并且效果很好。
我们可以将它们存储为BLOB(或者LONGBLOB),然后在要实际访问媒体文件时检索数据。
或者
我们可以简单地将媒体文件存储在驱动器上,然后将元数据存储在数据库中。
我倾向于后一种方法。我不知道这在整个世界上是如何完成的,但是我怀疑很多其他公司也会这样做。
我们可以存储链接(数据的部分路径),然后检索此信息。轻松移动驱动器上的内容并仍然可以访问它。
我将每个文件的相对路径以及有关文件的其他元数据存储在数据库中。如果我需要将实际数据重新定位到另一个驱动器(本地或者通过UNC路径),则可以即时更改基本路径。
这就是我的方法。我相信其他人也会有想法。
使用数据库的优点:
- 易于将声音文件与其他数据位合并。
- 避免绕过数据库安全性的文件I / O操作。
- 删除数据库记录时,无需执行分离操作即可删除声音文件。
使用数据库的缺点:
- 数据库膨胀
- 数据库可能比文件系统更昂贵
我认为,只要我们使用良好的实现,就可以将它们存储在数据库中。我们可以阅读这篇较旧但不错的文章,以获取有关如何防止数据库中的大量数据影响性能的想法。
http://www.dreamwerx.net/phpforum/?id=1
我已经在mysql数据库中加载了100个演出,没有任何问题。设计和实现是关键,如果做错了,我们将蒙受痛苦。
更多数据库优势(尚未提及):
在负载平衡的环境中效果更好
我们可以建立更多的后端存储可扩展性
我所知道的每个存储大量大文件的系统都将它们存储在数据库的外部。我们将文件的所有可查询数据(标题,艺术家,长度等)以及文件的部分路径存储在数据库中。当需要检索文件时,我们可以提取文件的路径,在其前面添加一些文件根(或者URL),然后将其返回。
因此,我们将有一个"位置"列,其中包含部分路径,例如" a / b / c / 1000",然后将其映射到:
" http://myserver/files/a/b/c/1000.mp3"
确保我们有一种简便的方法将媒体数据库指向其他服务器/目录,以防万一需要进行数据恢复。另外,我们可能需要一个例程,该例程将数据库与文件归档的内容重新同步。
另外,如果我们要拥有成千上万个媒体文件,请不要将它们全部存储在一个巨大的目录中,这是某些文件系统上的性能瓶颈。而是将它们分解为多个平衡的子树。
我已经在不同的项目中尝试了两种方法,最后我们决定使用文件系统也更容易。毕竟,文件系统已经针对存储,检索和索引文件进行了优化。
我要解决的一个技巧是仅在数据库中存储文件的"相对根"路径,然后让程序或者查询/存储过程/中间件使用特定于安装的根参数来检索文件。
例如,如果将XYZ.Wav存储在C:\ MyProgram \ Data \ Sounds \ X \中,则完整路径为
C:\MyProgram\Data\Sounds\X\XYZ.Wav
但是我们会将路径和/或者文件名存储在数据库中为:
X\XYZ.Wav
在其他地方,在数据库或者程序的配置文件中,存储根路径,如SoundFilePath等于
C:\ MyProgram \ Data \ Sounds \
当然,从数据库路径分割根的位置由我们决定。这样,如果我们移动程序安装,则不必更新数据库。
另外,如果要存储大量文件,请找到某种对路径进行哈希处理的方法,以免出现一个包含数百或者数千个文件的目录(在我的小示例中,有一些子目录基于第一个字符)文件名,但我们可以更深入或者使用随机散列)。这也使搜索索引器感到满意。
使用Blob存储文件的一些优点
- 降低管理开销-使用单个工具进行备份/还原等
- 数据库和文件系统不同步的可能性
- 交易能力(如果需要)
一些缺点
- 用无用的垃圾炸毁数据库服务器的RAM,它可能会用来存储行,索引等
- 使数据库备份非常大,因此难于管理
- 不能像文件系统那样方便地服务于客户端(例如,通过Web服务器)
性能如何?你的旅费可能会改变。文件系统千差万别,数据库的性能也是如此。在某些情况下,文件系统将获胜(可能使用较小的较大文件)。在某些情况下,数据库可能会更好(也许带有大量小文件)。
无论如何,请不要担心,尽一切所能。
某些数据库提供了内置的Web服务器来服务Blob。在撰写本文时,MySQL没有。