首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >避免可空的FK -数据库设计

避免可空的FK -数据库设计
EN

Stack Overflow用户
提问于 2018-05-25 16:57:00
回答 2查看 53关注 0票数 0

我正试图找出如何最好地用无空FK(sql server)来表示我的数据库中的数据。

我有一个网站,用户必须购买一个成员资格(每月订阅),可以购买广告,购买学分做更多的东西在网站上。

所以我想把这些桌子

代码语言:javascript
复制
Company
 -normal company columns
Plan 
  - Limitations (json, that contains all the limitations of what membership allows, ie can do x amount of seraches)
   - Name (ie Membership lv 1)
   - Price
   - Qty 
   - Unit (Monthly, Credit, etc)
PlanTypes
    - Type (membership, addon, ad)
CompanyPlans (junction table)
    - PlanId
    - CompanyId
    - Limitations (Json) - this would store like when their membership expires or how many credits they have left. If they would extend membership or buy credits the rows would be updated, so there would be business rules to basically make sure 1 row per plan per company, though this would not work really for ads as they can buy more than 1 ad.
Ads
 - normal add columns
 - Start
 - End

因此,我遇到的问题是,Plan table是一个表,用来跟踪他们是否订阅了会员,我认为这是可以的。

然而,当它到达广告,它变得奇怪,因为现在,我正计划把关系与Company。所以现在,对于ads来说,在ads表中检查它们是否仍然是活动的,这是突然之间的事,而其他的东西都在CompanyPlan表中。

更糟糕的是,广告的开始日期和结束日期是否仍然被复制在CompanyPlan表中以保持一致性?

我真的不想尝试将Plan表分解成像订阅表、Addon表和Addon这样的东西,因为我正计划连接到所购买的产品的order history & order history line table,我不希望有3种不同的关系到订单历史行表,并且始终有2种FK关系null,因为我认为这也很糟糕。

另一种选择,我在想,但我不确定这是不是不好的做法是把广告关系的CompanyPlan Junction Table,并保持开始/结束日期在Company Table和其他信息在Ad table.中。

示例数据

代码语言:javascript
复制
Company

Id Name
1  My Compnay

PlanTypes
Id  Type
1  Membership
2  Addon
3  Ad


Plans

Id PlanTypeId Limitations Name Price Value Unit
1   1         {Searches: 100} Plan 1 $30  1  Month
2   2         {}              Extra Searches $10  100 Credits
3   3         {}              Ad1    $100  1   Month

CompanyPlan
Id  PlanId   Limitations CompnyId
1   1        {Start: "2018-01-01", End: {2018-02-01}, 1
2   2        {ExtraSearches: 100}, 1
3   3        {AdStart: "2018-01-01", AdEnd: {2018-02-01}, 1

Ads
Id CompanyId Start End
1  1         2018-01-01  2018-02-01

Order History
Id  CompanyId
1    1

Order Lines
Id   OrderHistoryId  PlanId
1      1              1
2      1              2
3      1              3
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-25 19:13:42

从一开始,就像他在评论中提到的那样,如果正确使用,可空的FK并不是一件坏事。我会把你们的桌子设计如下:

代码语言:javascript
复制
Company
-Id
-Name

Plan
-Id
-Name
-Details

Addon
-Id
-Value

DefaultPlanAddon
-Id
-Plan_Id
-Addon_Id

Subscription
-Id
-Company_Id
-Plan_Id
-Start
-End

SubscriptionAddons
-Id
-Subscription_Id
-Addon_Id

Advertisement
-Id
-Subscription_Id
-Content
-Start
-End

我想大部分的桌子都是笔直的。

公司

确认公司/客户身份的所有数据。

计划

计划的基本细节。

Addon

这里变得更有趣了。这个表中所有的加载项都保存了下来。根据我的理解,加载项可以用于所有不同的计划。如果不是这样的话,您可以添加类似于PlanAddons表的内容,该表包含计划可以有哪些加载项的信息。值包含了这句话的意思。也许是大约100个额外的添加或其他什么的。至于我所知道的,您可以使用一个简单的字符串作为类型,因为一个副词基本上是一个Id,并且是对这个副词的描述。

订阅

我会分开做一个订阅表。您还可以保存每个订阅的开始日期和结束日期。有了这一点,您也有一个pruchase历史,而不需要一个OrderHistory表。如果开始日期不等于购买日期,则可以轻松添加PurchaseDate列。

SubscriptionAddon

此表包括特定订阅的所有加载项,因为一个子描述可以有多个加载项。

DefaultPlanAddon此表存储每个计划的默认加载项。这些信息只有在公司购买订阅时才会使用。您的逻辑查找了一个计划有哪些默认的加载项,并将int和其他想要的加载项放在SubscriptionAddon表中。

Advertisement

以下是存储的所有添加。还有开始和结束。与订阅一样,您也可以将此表用于OrderHistrory。

票数 2
EN

Stack Overflow用户

发布于 2018-05-25 17:43:28

在阅读了你的案例之后,我就这样想:

  • 我认为广告表应该存储广告的开始/结束日期。
  • companyads之间的关系是1:n,因此ads有一个指向company的外键。
  • 公司表不应该存储广告的开始/结束日期,因为同一家公司将来可以购买更多的广告。这样做的话,新的广告就会有一个开始/结束的日期,而不会影响到旧的广告,这个日期可能会被淘汰。

这应该使你的模型保持干净,没有(危险的)冗余。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50533818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档