4

问题

1) 我正在寻找一种合适的方式来设计 Web 应用程序,特别是数据库模式,这样我就可以拥有一个包含给定服务的所有核心字段的基表,然后根据服务的类型,我将需要一组额外的字段与服务相关联。

我需要以这样一种方式执行此操作,即执行搜索将是直截了当的并提供合理的性能。我可能正在查看某种类型的全文搜索,但最多只有 5 个应用程序并发用户。

我对该应用程序的最终目标是能够在整个数据库中搜索任何给定的关键字并返回所有相关记录。我最初希望将每种服务类型的设置字段拆分为具有自己列的单独表,但我认为这样做可能会导致更复杂的搜索查询(许多 JOIN)或更多查询要运行每次搜索。

对于提出的任何解决方案,您能否具体说明您认为这很合适的原因?

2) 我的另一个问题(希望在下面变得清楚)是我的设计目前包含一个“服务类型”表,我将在其中定义每个产品的核心类型,然后每个服务都是给定产品的“实例” .

我的问题是,如果我同时拥有产品和服务类型表,我感觉可能最终会重复大多数事情。因此,避免这种重复是我在设计中试图实现的另一个主要目标。

更多细节

我目前正在编写一个自定义 Web 应用程序,用于跟踪基于每个客户提供的服务,不仅用于开票(计费周期、开始/结束日期、价格),还用于记录这些服务(关联的用户帐户、IP地址、实物资产等)。

每项服务都基于一个“产品”表,该表定义了基本产品的名称、价格、计费期限、描述等……我们可以有多个相同类型的产品(例如,对于给定产品的不同计划类型)。例如,我们有以下产品:

  • 共享虚拟主机计划一
  • 共享虚拟主机计划二
  • 共享虚拟主机计划三
  • 专用服务器计划
  • 虚拟专用服务器方案一
  • 虚拟专用服务器计划二

现在我遇到的问题是,我们有许多对任何给定服务都通用的字段,但我们也有许多字段会发生变化,具体取决于被跟踪的服务的“类型”。根据服务的类型,我将显示所有服务的基本表单,以及用于添加/编辑等的适当表单......

例如,我们有以下服务类型,每个产品(如上所示)都与这些核心服务类型之一相关:

  • 共享虚拟主机
  • 专用主机
  • 虚拟专用主机
  • ADSL
  • ...

我可能的解决方案

当前解决方案 - 多个表

目前,在我的数据库中,我有:

服务类型

  • ServiceTypeID INT PK
  • 类型 VARCHAR(40)

产品

  • 产品ID INT PK
  • 名称 VARCHAR(40)
  • 说明文字
  • 价格小数
  • BillingDuration INT
  • TypeID INT (FK ServiceTypes.ServiceTypeID)

服务

  • 服务ID INT PK
  • ProductID INT (FK: Product.ProductID)
  • 名称 VARCHAR(40)
  • 说明文字
  • 价格小数
  • BillingDuration INT
  • 主动位
  • 开始日期日期时间
  • 结束日期 DATETIME

这些是任何服务的主表,然后我有扩展属性的附加表:

服务ADSLInfo

  • ServiceADSLInfoID INT PK
  • ServiceID INT (FK: Service.ServiceID)
  • FNN VARCHAR(10)
  • 用户名 VARCHAR(20)
  • 密码 VARCHAR(20)
  • LocationID INT (FK: Locations.LocationID)
  • ModemAssetID INT (FK: Assets.AssetID)

服务虚拟服务器信息

  • ServiceVirtualServerInfo INT PK
  • ServiceID INT (FK: Service.ServiceID)
  • 服务器名称 VARCHAR(20)
  • IPAddress INT (FK: IPAddresses.AddressID)
  • HostServer INT (FK: Assets.AssetID)
  • 用户名 VARCHAR(20)
  • 密码 VARCHAR(20)

ServiceSharedHostingInfo

  • ServiceSharedHostingInfoID INT PK
  • ServiceID INT (FK: Service.ServiceID)
  • 主机名 VARCHAR(50)
  • HostServer INT (FK: Assets.AssetID)
  • DiskSpaceQuota INT
  • 带宽配额 INT

其他解决方案 - 单表

我正在考虑将所有与服务相关的信息存储在一个表中,而不管服务的类型如何,并且如果该特定服务不需要它们,则只需将这些值设置为 NULL。

  • 服务ID INT PK
  • ProductID INT (FK: Product.ProductID)
  • 名称 VARCHAR(40)
  • 说明文字
  • 价格小数
  • BillingDuration INT
  • 主动位
  • 开始日期日期时间
  • 结束日期 DATETIME
  • 用户名 VARCHAR(20)
  • 密码 VARCHAR(20)
  • FNN VARCHAR(10)
  • LocationID INT (FK: Locations.LocationID)
  • AssetID INT (FK: Assets.AssetID)
  • ...

我觉得这在搜索方面也可能是一个更容易使用的解决方案,因为为了服务任何与服务相关的数据,我可以在单个表上使用全文搜索,而不用担心将记录连接在一起。

我在这里主要担心的是我最终会得到一个包含 30 多列的表,这似乎会变得非常混乱。另一件事是它并没有解决我的两个问题,因为我仍然需要核心 serviceTypes 表来确定我需要为任何给定搜索使用哪些字段 - 因此仍然与我的产品表有一些重叠。

我想知道是否无法避免与产品表的某种程度的重叠?

实体-属性-值模型

我也考虑过这个设计。总的来说,我觉得这对我来说太过分了,因为我不需要事情变得那么灵活和动态。根据服务类型,我们将需要一组字段,但是我们需要收集的每种核心服务类型的数据我看不到很快会发生变化,所以这可以是静态的。

在我看来,实现这种级别的灵活性所需的应用程序逻辑对于它带来的好处来说太复杂了。

必须根据从数据库中查询的字段类型等来确定要显示的 HTML 表单字段的类型……听起来很痛苦。

如果我可以提供任何进一步的细节,请告诉我!我希望一切都清楚。

谢谢!

4

1 回答 1

2

我认为这一切都取决于您对前进的设想,尤其是在新服务进入系统的情况下,所有这些都是有效的方法,但都有利有弊。

使用第一种方法,您可以获得更干净的主表,但是对于每个服务,您必须创建一个单独的表,对于新服务,您必须继续这样做,对于您的应用程序,这可能会增加一些复杂性,因为每个服务都需要自己的一组用于提取数据的查询(不确定您的架构是什么,所以是在黑暗中刺伤。我个人觉得这最终会受到伤害。

非规范化表方法更容易查询,但是您可能会创建一个怪物表,其中包含针对某些类型的大量不必要的数据。稍微不同的方法可能是添加通用字段,即 10 个称为 numX 的字段(其中 x 是 1 到 10),其中包含数字,10 个称为 textx 等等,我认为销售人员使用这种方法为客户定制字段。

键值字段方法就像你说的最灵活,但是你失去了类型识别之类的东西,至少数据库中的所有内容都需要是相同的类型。

这取决于您的应用程序的性质,5 个并发用户的性能不应该是问题,所以也许应该易于实施。通用方法大纲(销售人员方法)可能适用于此,并可能涵盖您的其他服务向前发展并为您提供一点未来证明,但这取决于您设想的变化量。

如果更改要保持一致,则加载具有不同字段的服务等,键/值方法可能是您最好的选择,但在那个阶段您也可以查看一些 nosql 方法,因为它们可能适合这里的账单,但 mysql 会仍然有效,只是开始讨论。

更新

同意评论,如果您不打算对服务进行过于频繁的更改,我会跳过 noSQL,因为它会增加您的开发的复杂性,这可能不会使您受益。

如前所述,服务类型可能不会发生太大变化,那么我认为非规范化的通用方法可能对您有用。这样,您的应用程序可以有一个服务区域,并且您可以将其他属性视为“自定义字段”并根据需要添加。这样你的应用程序是通用的。一个不幸的副作用是,您将不得不通过某种逻辑在您的应用程序中以某种方式对其进行管理,以测试它是否存在,并且您必须提取所有字段,无论它们是否已填充,对于您目前的需求,可能不是一个巨大的权衡。

通用方法的示例(非常非常简单)示例。

在此处输入图像描述

  • 通用字段是所有服务共享的主要字段。

这可能会使搜索变得有点痛苦,因为您可能(取决于机制)必须在搜索中包含所有字段

于 2012-11-02T08:44:12.397 回答