【问题标题】:Database Table Schema and Aggregate Roots数据库表架构和聚合根
【发布时间】:2011-06-09 16:20:02
【问题描述】:

应用程序是单用户、1 层(1 pc)、数据库 SqlCE。 DataService 层将是(我认为):Repository 返回域对象并使用 LinqToSql(dbml)查询数据库。显然还有很多列,这是简化视图。

单独表中的日志时间:http://i53.tinypic.com/9h8cb4.png

ItemTimeLog 表中的LogTime(作为时间):http://i51.tinypic.com/4dvv4.png

alt text http://i53.tinypic.com/9h8cb4.png

这是我第一次尝试创建 >2 个表的数据库。我认为表模式是有道理的,但我需要一些保证或批评。因为说实话,表关系看起来很可怕。我希望你能做到;

  • 查看表架构,如果有明显的问题或错误迹象立即发现并做出响应。如果您有时间,

  • 查看计划摘要/问题,看看表格布局是否对这些要点有意义。

请野蛮,我会尽力捍卫:)

计划摘要:

a) 一组类别,每个类别都有一组策略 (1:m)

b) 每天都会生产一些物品。每个策略都可以引用它。 (所以可以有50个item,一个策略可以引用其中的23个)

c) 一个项目可以被多个策略引用。所以我认为这是一个 m:m 关系。

d) 状态值将在一天中的固定时间部分记录,用于: - ....每个策略.....每个策略项....每个项目

e) 对某个项目的操作可能由引用它的策略执行。 - 这被记录为 ItemAction(可以称之为 StrategyItemAction)

用户要求

b) -> e) 描述了程序的主要活动模式。对于每个类别,仅使用 today's DayLog第二优先活动是历史检索,通常是来自所有类别,从第 x 天到第 y 天;获取所有 StrategyDailyLog。

问题

  1. 首先,整体布局看起来是否合理?我担心看到有这么多的关系,四面八方,连接着一切。这是正常的,还是看起来很麻烦?

  2. StrategyItem 用于表示 m:m 关系。正如我所说的那样正确吗 1:m / 1:1(标记为红色)?

  3. 策略项目时间日志和项目时间日志;在检索 StrategyItem 时记录需要一起检索的值。我分开的原因是第一个是特定于策略的,并且多个策略可以引用同一个项目。所以我想不要复制那些不依赖于任何策略而只依赖于项目的值。因此,我还拖出了 LogTime,因为它似乎是统一日志的唯一参数。但这三张桌子看起来很令人不安。这有意义吗?或者你有什么建议?

  4. 粉色圆圈显示了我对聚合根路径的模糊尝试。我一直在考虑“哪个实体负责删除”。虽然我不确定实际的根。我认为是类别。与上述用户请求相关是否有意义?


EDIT1: (更新的架构,显示前几个关系的典型层次结构项目数,365 天,以及其他说明)

1:1 关系:抱歉。我犯了一个错误。 StrategyDailyLog 应该是 1:m。请参阅更新的架构。每天每个策略一个。

DayLog / StrategyDailyLog:我一直在思考 DayLog 是否应该像这样成为层次结构的一部分。 DayLog 表的目的是保存从同一天的所有 StrategyDailyLog 表派生的“总和值”。就像今天的性能值一样。它还保存日期值。这允许我在 StrategyDailyLog 中省略一个日期值(我觉得这有点像日期字段的重复建模),而是存在对 DayLog 的引用以“查找”日期。我不确定这是否是对规范化的滥用/误解。

空值:我没有想过这个。我相信我找到了 2,就像现在在 StrategyDailyLog 和 ItemAction 中标记的那样。它们在创建时不能为 null,但如果需要删除 Strategy 或 StrategyItem,则可以将它们设置为 null。这不需要删除 StrategyDailyLog 和 ItemAction。因此可以将它们设置为 null。

All Id –columns: 我的想法是将 ID(自动生成的整数)作为我所有表的 PK。我相信这也足以作为候选键。这不是进行PK的正确方法吗?这是唯一可以识别我的任何桌子的方法。我之前问过一个问题是否可以,也许我误解了,但认为这是一个好方法。

m:m 关系: 这是我尝试做的:StrategyItem 是 StrategyDailyLog / DailyItem 的 m:m 表。

【问题讨论】:

  • 为什么是DailyItem——而不是Item
  • 这只是为了表明该项目在每一天都是唯一的。其他日子的类似项目将是一个独特的行。也许不是一个好的命名,但这是我的理由。
  • 无论策略如何,DailyItems 都存在。然而,每个策略都可以通过 m:m 表 StrategyItem 选择“插入”一个项目。这有意义吗?
  • 我将其重命名为“项目”。我同意这令人困惑。

标签: c# sql sql-server database database-design


【解决方案1】:

好的。这是我的残酷。我不明白模型。 因此,与其试图对此发表太多评论,不如说是我看到它时想到的一些想法。

我认为你应该看看你的 1:1 关系(所有这些)。为什么 DayLog 和 StrategyDailyLog 在两个表中分开?可能是因为您将始终拥有至少一个 DayLog 项目,但并非所有 DayLog 项目都有一个 StrategyDailyLog 项目。如果是这种情况,您可以在 DayLog 表中使用允许空值选项的 StrategyID FK。

如果您可以显示哪些字段是必需的以及哪些字段接受 null 作为值,这将有助于理解模型。

您的所有表格都有自己的 id 列。在进行 1:1 关系和 m:m 关系时,这可能会非常令人困惑。对于 1:1 关系,通常两个表之间的关系是在两个表中的主键上建立的。如果你不这样做,你必须在外键列上创建一个候选键。在您的情况下,这意味着 StrategyDailyLog 应该在 DayLogID 上有一个候选键。

两个表之间的 m:m 关系通常通过在两个表之间添加一个新表来解决,主键来自两个表。这些字段一起是中间表的主键。 例如,您应该在类别和策略之间建立 m:m 关系。然后,您应该创建一个名为 CategoryStrategy 的表,其中包含两个字段 CategoryID 和 StrategyID,它们一起是表 CategoryStrategy 的主键。

我希望我的 cmets 有意义并且对你有用。

编辑 2011-01-17

我认为您不应该将 IDENTITY 列用作所有表中的主键作为原则。 m:m 关系不需要它,所以你不应该这样做。我还认为您误解了我对候选键的含义。候选键是可以用作主键的键。在 MS SQL Server 中,您为候选键定义一个唯一约束。 例如:表 StrategyItem 的 id 为 PK,但 StrategyID 和 DailyItemID 的组合是候选键。最好去掉 id 并使用 StrategyID+DailyItemID 作为 PK。

以下是我根据您的描述构建的架构。我可能错过了一些重要的事情,因为我不知道你想做什么。 在设计模式时,您不应该过多考虑查询性能和构建聚合。这可以通过在列上创建索引并在查询中使用 sum、count 和 group by 来处理。在下面的模型中创建的列上的索引对于您在日期或日期间隔上的查询是必要的。在 MS SQL Server 中有一种叫做聚集索引的东西。默认情况下,表的 PK 是聚集索引,但在这种情况下,我会将 Created 列上的索引设为聚集索引。

一个类别有 0,1 个或更多策略。 LogItem 具有类别和可选的一个策略 LogItem.Created 保存日期和时间。

【讨论】:

  • :) 谢谢!您可能已经指出了我理解中的一些误解。但我不是 100% 确定。请参阅上面的 EDIT1,我对您的观点作出回应。干杯
  • @bretddog 添加了更多内容来回答
猜你喜欢
  • 1970-01-01
  • 2010-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-24
  • 2014-06-27
  • 2012-08-04
  • 2014-10-26
相关资源
最近更新 更多