带有图像字段的图片项目的单独表格

Posted

技术标签:

【中文标题】带有图像字段的图片项目的单独表格【英文标题】:separate table for picture items with image field 【发布时间】:2010-09-24 21:47:25 【问题描述】:

我将不同的项目(笔记、文章、图片、文件)存储在一个表中(所有项目类型都有许多共同的元数据 - 例如,类别、标签、评级、统计信息等)。

我的第一个设计是这样的:Items 表,以及每个项目类型的另一个“详细”表(NoteItemsArticleItems图片项等)。要检索单个项目,表必须一对一连接(SELECT * FROM Items INNER JOIN PictureItems ON Items.Id = PictureItems.Id WHERE Items.Id = N)。

我很确定这种“按部就班”的设计会很好地工作(多次这样做),但是,我开始怀疑这种设计是否过于矫枉过正。有一个表(Items)会简单得多。

假设有大约 5% 的图片或文件类型的项目。

现在的问题是:如果我选择(几乎)单表设计,是否最好为图像字段提供详细表(当然是图片和文件项)?

场景一:只有一张表:Items(用于存放笔记、文章、图片、文件...)

场景2:两张表:Items(用于存放笔记、文章、图片文件)、ImageItems(仅用于存放item类型图片、文件的图片字段);一对一的关系

(场景 3 是场景 2 的一个小变化;有 3 个表(项目、图片项目、文件项目))

方案一的优点是:

更简单的选择查询(无连接) 无事务更新(在 INSERT/UPDATE 时仅更新一个表) 无事务更新带来的性能和可扩展性?

方案 2 的优点是:

更简洁的设计 降低数据消耗(在场景 1 中,大约 95% 的非图片或文件类型的项目在图像字段中具有 NULL 值,即浪费了大约 16 个字节用于指针)

您会选择哪种方案:1(无事务更新)或 2(更低的数据消耗)?感谢您的意见。

【问题讨论】:

我们正在处理一个文件内容存储在数据库字段中的案例,不是吗?你有没有想过在你的数据库中存储文件名(以及最终的路径)? 我通常避免将二进制数据放入数据库。路径效果很好。 【参考方案1】:

如果数据库不需要知道这些项目中的内容(不会对它们进行索引或搜索),那么选项 1 似乎是最好的选择(假设您只有一个“项目”列作为 BLOB)-您可以将项目读出为二进制数据并自行处理 - 从而避免内部连接。

我不相信方案 2 会降低数据消耗 - 您可以只使用 BLOB 字段(无论如何,额外的 ImageItems 表的开销可能相当于每行 16 个字节)

所以我个人会选择选项 1,但当然这取决于您在项目从数据库中出来时如何处理它们。

【讨论】:

【参考方案2】:

如果程序员足够明智地只从表中查询所需的列而不是“SELECT *”,那么第一种设计方法看起来还可以。

需要注意第二个设计的索引、引用约束等。

【讨论】:

不幸的是,“SELECT *”正是将要发生的事情。任务涉及该表中其他列的程序员可能甚至不知道应该避免它。【参考方案3】:

如果您使用某种 ORM 或自动生成 DAL(SubSonic?),第一种方法通常会受到惩罚。每次传递 DAL 对象(或集合)时,您都会检索 Image 列(及其数据),所以通常我会使用场景2(或3)

从 SQL 的角度来看,根据您的存储引擎(ISAM、InnoDB 等),两种方案的工作方式大致相同,但即便如此,方案之间的优势和差异也很小。

【讨论】:

【参考方案4】:

如果你是正确的,只有大约 5% 的行实际上有额外的图像/二进制数据,那么我肯定会说使用单表方法,并结合 Murthy 给出的提示 - 确保不要执行 SELECT *在此表上,但只请求您真正需要的那些列 - 尽可能多地省略 BLOB 列。

如果您的数据库增长,您可能还想为 BLOB 数据检出一个单独的文件组,以保持分离和清洁(但这实际上只在您处理数十万行或更多行时,如果您可以将文件组拆分到几个单独的磁盘上)。

KISS - 尽可能保持智能和简单! :-)

马克

【讨论】:

以上是关于带有图像字段的图片项目的单独表格的主要内容,如果未能解决你的问题,请参考以下文章

打印带有图像的 html(每个图像在单独的页面上)

带有图像和文本字段的自动布局表格单元格?

cms项目技术心得!

带有额外视图的表视图。查看保持调整到最大

如何在访问表单和报告标题中使用表格中的附件图像?

提交带有表格的图像时需要Django Pillow或Pil吗?