在关系数据库中建模单例的最佳方法


12

在为Web应用程序设计关系数据库架构时,经常会遇到一种情况,最终我创建了一个表,仅包含一行和一行。感觉那是设计它的错误方法,但是我无法提出任何明显更好的方法,或者那显然是“正确的方法”。

最近的示例是一个站点,该站点使用户可以手动控制主页上的内容。好吧,只有一个主页。我创建了一个表,其中包含构建主页的所有必要字段,例如包含描述性文本的区域的文本字段。一个用于存储大图像文件名称的字段。一些外键指向将在首页上显示的文章,等等。它虽然有效,但是只有一行的表感觉不对。

过去,我尝试了许多其他设计,例如允许主页表中包含多行并随机选择一个。我尝试添加一个名为“ active”的布尔字段,并随机选择一个活动主页。在应用程序逻辑中,我尝试在任何给定时间仅强制一行处于活动状态。我什至尝试不制作主页表,也不让所有其他项(例如文章)具有名称为featured_on_homepage之类的布尔字段。

在大多数情况下,我可以在设置文件中使用一堆常量来构建主页。设置文件的主要问题在于它在开发人员的控制之下。因为像主页内容这样的东西是用户要编辑的东西,所以它必须进入数据库。

在许多站点上,我没有这个问题,因为我可以通过查询来构建诸如首页之类的内容,例如选择五篇最新文章。但是,当我有严格要求的手动页面时,在数据库中对其建模就变得很棘手。但是想象一下,您有一张照片桌子和一张物品桌子。要求是首页要显示精确的五张照片,精确的三篇文章和两块由用户手动控制的任意文本。您如何在数据库中正确建模呢?

另外,除了首页以外,我在许多其他情况下都遇到了建模问题。这只是我能想到的最简单,最适用的示例。


除了单行表在某种程度上代表浪费表之外,还不清楚单行表会给您带来什么问题。您确定要解决实际遇到的问题吗?
David Aldridge

Answers:


10

一种简单的方法是将“主页”属性保存在“名称”和“值”列组成的“属性”表中(或称为其他名称)。

HomePageProperty1-UserValue1

HomePageProperty2-UserValue2

它可能不是理想的解决方案,但它简单而灵活。它还消除了具有单行方案的表。


1
这种方法可用于多种目的。例如,我将存储模式版本信息,需要每天循环的事物的旋转指针等。在诊断出问题时,模式版本信息非常重要。这是确保补丁程序适用于仅数据库修复程序的合理方法。
Berin Loritsch 2010年

2
+1-这是我们的数据架构师出于类似目的而给我的确切表格布局。
阿里2010年

3
这种方法的问题在于,您需要将不同的变量类型表示为不同的列,并具有逻辑来告诉您要使用哪个列以及哪些是强制性的。您无法定义布尔值是布尔值,还是日期是日期,或者特定属性不能为null,或者必须在特定范围内或满足条件-所有这些都很简单与一个单行表。
David Aldridge

3

对我来说尚不清楚您是否有需要解决的问题。

单行表对数据库本身绝对不是问题,它允许您将数据类型和约束应用于数据。

老实说,我不确定您是否要解决一个真正的问题。


2

在我看来,您正在使用数据库来存储实际上应存储为文件的内容。

您的描述使我想起了很多Wiki页面,用户可以在其中编辑内容。在Wiki中,或者至少在我所看到的实现中,页面以文件的形式持久保存。

这可以帮助您了解其他网络详细信息,例如允许用户缓存您的主页,如果您将页面存储为文件,则实际上是免费的,但是如果您要构建主页,则必须手动实现缓存无效的逻辑根据存储在数据库中的内容在每个请求上显示页面。

无论如何,我只想澄清一下,即使大多数应用程序的持久数据存储在数据库中,也不意味着我们必须将所有内容都存储在数据库中。数据库只是我们交易的工具之一。我们必须学习尽可能多地利用各种不同的工具。


2

一行表绝对没有错。

如果这是设计的一部分,则应强制执行。给表一个标识列,给它一个唯一性约束,然后添加一个列约束以仅允许一个值。这将确保没有人能够添加第二行,如果读取表的SQL语句(可以理解)缺少where子句,那将是灾难性的。

如果您开始获得大量列,则可能会尝试缩小表的范围,而每个配置项只有一行。这不是最好的主意,因为您会丢失类型安全性和验证。同样,您将失去与多租户的前向兼容性,这可能对您很重要。更好的解决方案是重新考虑您的实体的真正含义,并为不同的实体提供单独的单行表。

是的,我不仅在说单行表还可以,而且我建议您可能需要多个表。


1

您可以创建一个名为STATIC_CONTENT的表,并具有一个键列以及内容,活动/非活动跟踪器等。然后,创建一个键为“ HomePage”的行,并在您的首页中加载该键的静态内容并显示它。这样,当您拥有其他静态内容(关于页面,联系页面等)时,可以向该表添加行。


1

一个只有一行的表本身没有什么错。如果您只有某个实体的一个实例,那么这很可能是最自然的表示方式。

但是,随机选择一行是错误的也是坏的。如果您的域逻辑仅期望一行,那么如果实际上有更多行,则显然是数据错误。因此,您应该弄清楚谁或什么人正在将无效数据写入数据库,并防止它们这样做!根据数据库的不同,您可能会向表中添加一个约束,以防止这种情况首先发生,例如,仅允许特定值作为主键。


0

只是为了添加到Walter ..

属性表结构应允许多种数据类型。

Fileds:
PropertyName
PropertyTextValue
PropertyDateValue
PropertyNumericValue
PropertyBoolValue

这样,如何保证每行只设置一个属性值?在应用程序中强制实施它很容易,但是如果有人随后手动更新数据库并将某些数据粘贴在其中怎么办?
Apreche 2010年

0

在我看来,您可以再抽象一个级别。最后,“主页”是“页面”。您可以具有所需属性的不同类型的页面。如果您的站点中有部分,则可能需要“ SectionHomePage”,该部分可以很好地与“主页”相同。

要求是首页要显示精确的五张照片,精确的三篇文章和两块由用户手动控制的任意文本。您如何在数据库中正确建模呢?

让我们这样尝试。我正在添加ArticlePage表,以便您了解如何相应地分隔属性。

PAGES
Id
Title
Description

HOMEPAGES
PageId (FK)
PhotoListLimit
ArticleListLimit
TextBlockListLimit

ARTICLEPAGE
PageId (FK)
ArticleMainQuote
ArticleMainBody
ArticlePhoto1
ArticlePhoto2

这对我来说很好,甚至对大型网站也很好。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.