存储文件的数据库设计决策

时间:2013-09-12 18:14:02

标签: sql-server database-design

您好我正在处理个人应用程序并面临数据库设计决策,我不知道采取哪种行动。这就是我想要实现的目标。

在我的应用程序中,我将使用WYSIWYG编辑器存储大量图像,视频和一些html文件。我已经决定不在我的数据库中存储文件但是我只会存储原始文件名和存储文件名(唯一标识符)。

为此,我决定为每种类型的文件分别设置3个表。

这是我开始遇到一些问题的地方。

目前,在我分析了我想要构建的内容之后,我意识到到目前为止我有4种类型的图像:头像,缩略图,描述,标题。这个列表可能会增长,直到我完成应用程序。对于视频和html文件也是如此,我还不确定。

截至目前,我在设计数据库时看到了2个行动方案。

第一个是我有一个Images表,我将拥有这些属性:

OriginalFileName,StorageFileName,IsAvatar,IsThumbnail,IsDescription,IsHeader

在这种情况下,每当我在我的应用程序中识别出一种新类型的图像时,我将不得不修改数据库表,这对我来说听起来并不合适。

第二个是我为每种类型的图像创建表格。

在这种情况下,我会有4个表,它们有一个Primary列,一个OriginalFileName列和一个StorageFileName列。

同样,每种类型我都会识别一种新类型的Image,必须创建一个新表。

这种解决方案听起来不错,但我可以通过做这样的事情进入过度工程的领域。

那么对我目前的问题最好的解决方案是什么?

如果有人有话,我会听取其他选择。

3 个答案:

答案 0 :(得分:5)

你所建议的(两个建议)被称为非正规化;在关系数据库中,这可能是一件坏事。如果头像,缩略图,描述和标题具有相同的属性,即只有原始文件名和存储文件名,它们都应该放在一个表中,当然,但是您只需要一个列来标识哪个是哪个。然后你有第二个表来解码它。

例如:

你有一个表,列

Files
    OriginalFileName, StorageFileName, FileTypeID

然后,FileTypeID将成为第二个表中的外键:

FileTypes
    ID, Description
    1   Avatar
    2   Thumbnail
    3   Description
    4   Header

如果您想添加另一种类型的文件,则在FileTypes中添加另一行并开始填充表文件。

如果您的文件具有不同的属性,那么您可能需要考虑4个单独的表,但直到那时为止。

答案 1 :(得分:3)

您可以对表格进行子类型化。有一个存储图像本身:

Images
----------------
ID
OriginalFileName
StorageFileName

然后对于子类型,它们的主键将是返回超类型表的外键:

Avatars
---------------
ID (FK to Images.ID)

Thumbnails
---------------
ID (FK to Images.ID)

etc.

这将允许您轻松添加/删除类型以及添加/删除与特定类型相关联的数据,而无需修改与这些特定更改无关的结构。

答案 2 :(得分:2)

我已根据我的应用要求以不同方式完成此操作。例如,我根据长期存储与短期存储分割文件,因为这是文件中的一个重要区别。但除非我有一个非常具体的理由将文件拆分成子类型,我只是将文件视为无类型数据(就数据库而言),因为文件引用表具有我想要捕获的所有元数据,查找表以解释元数据。忽略指数等。

create table FileRef
(
  FileName varhchar(80) not null
, FileExt varchar(30) null
, FileClass smallint not null
, CreateUTC datatime not null
, Modified datetime not null
, Description varchar(250) null
)
GO

/*
You might want a computed column for the filename+Extentsion. I have have that splitting out the extension is often useful in the database so I don't have to parse it out whenever I want it.
*/

create table FileClass
(
  smallint id not null
, Description varchar(80) not null
, Location varchar(80) not null
)
GO

当然,改变以前的表格以满足您的需求。

我还建议不要在FileRef中存储磁盘文件的路径(如上所示,我将其存储在FileClass中),因为当由于服务器更改而必须移动文件时,更容易移动文件,等

如果文件量很大,您不希望将所有文件放在一个文件夹中。虽然现代版本的Windows在btree中维护磁盘目录,但是你会遇到一些问题,例如在一个大型目录中意外打开资源管理器,这使得它对一百万个文件非常不愉快。每个目录可能只有4K文件的文件的简单拆分 - 可能基于TSQL CHECKSUM()将防止这是一个问题。

OOPS,忘了重要字段,你还需要FileRef中某种形式的FileID。