我是否应该将所有MySQL表相互关联?
我正在做一个个人项目,负责各种项目的计时,但我不确定构建数据库的最佳方式 结构的简化分解如下所示:我是否应该将所有MySQL表相互关联?,mysql,sql,database-design,Mysql,Sql,Database Design,我正在做一个个人项目,负责各种项目的计时,但我不确定构建数据库的最佳方式 结构的简化分解如下所示: 每个客户端可以有多个报告 每个报表可以有多个行项目 每个行项目可以有多个时间记录 最终会有更多的关系,但这是应用程序的基础。如您所见,每个项目都以一对多的关系与其下的项目相关 我的问题是,我应该将每个表与上面的每个“父”表关联起来吗?大概是这样的: clients id reports id client_id line_items id repor
- 每个客户端可以有多个报告李>
- 每个报表可以有多个行项目李>
- 每个行项目可以有多个时间记录
clients
id
reports
id
client_id
line_items
id
report_id
client_id
time_records
id
report_id
line_item_id
client_id
Client
ClientId
Report
ReportId
ClientId
LineItem
LineItemId
ReportId
TimeRecord
TimeRecordId
LineItemId
随着它的级联,将有越来越多的外键添加到每个新表中
我最初的反应是,这不是正确的方法,但我希望得到一些第二(和第三)种意见。作为个人意见,我会:
clients
id
time_records
id
client_id
report
line_item
report_id
这样,您的所有字段都在时间记录表中。然后,您可以执行以下操作:
SELECT *
FROM 'time_records'
WHERE 'time_records'.'client_id' = 16542
AND 'time_records'.'report' = 164652
ORDER BY 'time_records'.'id' ASC
不,如果模型的元素中没有直接关系,那么相应的表中就不应该有直接关系。否则,您的数据将有冗余,并且您将在更新时遇到问题
这是正确的方法:
clients
id
reports
id
client_id
line_items
id
report_id
time_records
id
line_id
如果从不直接连接行项目客户端,则不需要在行项目
表上创建客户端id
,因为您可以通过报告
表获得该id。其他FK也是如此
我建议您在创建可能使开发复杂化的冗余外键之前,在报告中考虑对该数据集合的需求/查询
如果将来需要,创建冗余FK并不困难,一些更改和更新选择可以解决您的问题
如果您在行\u项中没有那么多信息
,您可以在时间\u记录中取消规范化并添加此信息
这样做的好处是,您可以检查所有时间记录,例如,特定的客户端id,而无需加入。但事实上,这是没有必要的。您只需将引用存储到一个“级别”即可。以下是“客户”视角下的一些示例:
获取特定客户的报告:(简单;与您建议的当前模式相同)
获取特定客户端的行项目:(新架构;不需要表中的“客户端id”)
获取特定客户端的时间项:(新架构;不需要表中的“客户端id”或“报告id”)
因此,修改后的模式为:
clients
id
reports
id
client_id
line_items
id
report_id
time_records
id
line_item_id
编辑:
clients
id
reports
id
client_id
line_items
id
report_id
time_records
id
line_item_id
另外,我会考虑使用视图来简化查询(我假设您经常使用它们),明确地在连接列上创建索引,并使用外键引用进行归一化(UnDB只)。
< P>在两个表之间有直接关系,应该使用外键来保持数据完整性。就我个人而言,我会考虑这样的结构:
clients
id
reports
id
client_id
line_items
id
report_id
client_id
time_records
id
report_id
line_item_id
client_id
Client
ClientId
Report
ReportId
ClientId
LineItem
LineItemId
ReportId
TimeRecord
TimeRecordId
LineItemId
在本例中,您不需要LineItem
中的ClientId
,因为您通过Report
表具有这种关系。在所有表中使用ClientId
的主要缺点是,如果业务逻辑没有强制这些值的一致性(代码中有一个bug),那么如果基于
Report:
ReportId = 3
ClientId = 2
LineItem:
LineItemId = 1
ReportId = 3
ClientId = 3
在上述情况下,如果您的查询通过Report
,您将看到ClientId=2
;如果您的查询通过LineItem
,则很难确定哪个关系是正确的,以及错误在哪里
此外,我主张不要使用id
列,而是使用更明确的名称来描述id
的用途。(ReportId
或ClientId
)在我看来,这使得连接更容易阅读。例如:
SELECT COUNT(1) AS NumberOfLineItems
FROM Client AS c
INNER JOIN Report AS r ON c.ClientId = r.ClientId
INNER JOIN LineItem AS li ON r.ReportId = li.ReportId
WHERE c.ClientId = 12
在格式化查询时,我还将=
更改为=
。我希望这个改变是你想要的;如果不是,很抱歉。谢谢!它是。尝试的速度比我想象的要快。你(概念上)如何区分行项目和时间记录?行项目是某种任务吗?是的,行项目将是一项任务。例如,一个行项目可能会读为“Build Timekeing application”,它会有多个时间记录(这里30分钟,那里12分钟,等等),这些时间记录加起来等于在一个行项目上花费的总时间。鉴于此,我认为您当前的设计是完全可以接受的(减去子表中的额外ID)我希望我能接受所有的答案,但我觉得你的答案解释得非常透彻。非常感谢。