3

嗨,我正在开发一个个人应用程序,并且正面临一个数据库设计决策,我不知道要采取哪种行动。这就是我想要完成的事情。

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

为此,我决定为每种类型的文件设置 3 个单独的表是个好主意。

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

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

到目前为止,我在设计我的数据库时看到了 2 个操作过程。

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

OriginalFileName ,StorageFileName , IsAvatar , IsThumbnail , IsDescription , IsHeader

在这种情况下,每次我在我的应用程序中识别一种新类型的图像时,我都必须修改数据库表,这对我来说听起来不对。

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

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

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

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

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

如果有人有其他选择,我愿意听取其他选择。

4

3 回答 3

5

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

例如:

你有一张桌子,有列

Files
    OriginalFileName, StorageFileName, FileTypeID

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

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

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

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

于 2013-09-12T18:20:49.040 回答
3

You could sub-type your tables. Have one which stores the images themselves:

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

Then for the subtypes their primary keys would be foreign keys back to the supertype table:

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

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

etc.

This would allow you to easily add/remove types as well as add/remove data associated with specific types without having to modify structures unrelated to those particular changes.

于 2013-09-12T18:20:36.053 回答
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() 将防止这成为问题。

糟糕,忘记了重要字段,您还需要 FileRef 中某种形式的 FileID。

于 2013-09-12T21:59:42.303 回答