php – 具有不同字段集的记录的数据库设计

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

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

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

对于任何提议的解决方案,请您说明为什么您认为这是一个合适的解决方案?

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

我的问题在于,如果我同时拥有产品和服务类型表,我觉得最终可能会出现最多重复的问题.所以为了避免这种重复是我在设计中试图实现的另一个主要问题.

更多细节

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

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

>共享WebHosting计划一
>共享WebHosting计划二
>共享WebHosting计划三
>专用服务器计划
> Virtual Dedicated Server Plan One
>虚拟专用服务器计划二

现在我的问题是,我们有许多字段,这些字段对于任何给定的服务都是通用的,但是我们还有许多字段会根据被跟踪的服务的“类型”而改变.根据服务的类型,我将显示所有服务的基本表单,以及添加/编辑等的相应表单…

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

>共享虚拟主机
>专用主机
>虚拟专用主机
> ADSL
> ……

我的解决方案

当前解决方案 – 多个表

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

ServiceTypes

> ServiceTypeID INT PK
> Type VARCHAR(40)

产品

> ProductID INT PK
>名称VARCHAR(40)
>说明文字
>价格DECIMAL
> BillingDuration INT
> TypeID INT(FK ServiceTypes.ServiceTypeID)

服务

> ServiceID INT PK
> ProductID INT(FK:Product.ProductID)
>名称VARCHAR(40)
>说明文字
>价格DECIMAL
> BillingDuration INT
>活跃的BIT
> StartDate DATETIME
> EndDate DATETIME

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

ServiceADSLInfo

> 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

> ServiceVirtualServerInfo INT PK
> ServiceID INT(FK:Service.ServiceID)
> ServerName 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
> BandwidthQuota INT

其他解决方案 – 单表

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

> ServiceID INT PK
> ProductID INT(FK:Product.ProductID)
>名称VARCHAR(40)
>说明文字
>价格DECIMAL
> BillingDuration INT
>活跃的BIT
> StartDate DATETIME
> EndDate DATETIME
>用户名VARCHAR(20)
>密码VARCHAR(20)
> FNN VARCHAR(10)
> LocationID INT(FK:Locations.LocationID)
> AssetID INT(FK:Assets.AssetID)
> ……

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

我在这里主要关注的是我最终得到一个有30列的表,看起来它可能会变得非常混乱.另一件事是它并没有解决我的问题,因为我仍然需要核心的serviceTypes表来确定我需要为任何给定的搜索使用哪些字段 – 因此仍然与我的产品表有一些重叠.

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

实体 – 属性 – 值模型

我也考虑过这个设计.总的来说,我觉得这对我来说太过分了,因为我不需要那些灵活而有活力的东西.我们将需要一组字段,具体取决于服务类型,但我们需要在每个核心服务类型上收集的数据我看不到很快就会改变,所以这可能是静态的.

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

必须确定要显示的HTML表单字段的类型,具体取决于从数据库查询的字段类型等…听起来很痛苦.

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

谢谢!

最佳答案 我认为这一切都取决于你如何设想前进,特别是新服务进入系统,所有都是有效的方法,但都有利有弊.

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

非规范化表方法更容易查询,但是您可以创建一个包含大量某些类型的有用数据的怪物表.稍微不同的方法可能是添加通用字段,即名为numX的10个字段(其中x为1到10),其中包含数字,10个名为textx,依此类推,我认为salesforce将此aporoach用于客户的自定义字段.

关键值字段方法就像你说的最灵活,但是你丢失了类型识别之类的东西,一切都需要在数据库中至少相同.

这取决于你的应用程序的性质,5个并发用户的性能不应该是关注,所以也许应该是易于实现.通用方法概述(销售人员方法)可能在这里工作,并可能覆盖您前进的其他服务和未来证明您一点,但这取决于您设想的变化多少.

如果变化是一致的,加载如果具有不同字段的服务等等,键/值方法可能是你最好的选择,但在那个阶段你也可以看一些nosql方法,因为它们可能适合这里的账单,但mysql会还在工作,只是打开讨论.

更新

如果您没有设想对服务进行过于频繁的更改,我会跳过noSQL,因为它会增加您的开发的复杂性,这可能不会让您受益.

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

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

>通用字段是您在所有服务中共享的主要字段.

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

点赞