一对多关系的 SQL 视图、性能和计数

发布于 2024-11-18 11:00:04 字数 954 浏览 3 评论 0原文

我需要一些帮助来为我的一堆表形成基本的 SQL-VIEW。这是一个快速概述,

  • 我有一个 ClaimDetail 表,它有一些查找字段,如 StatusID、BrandID、SalespersonID 等。
  • 像往常一样,查找字段映射到主表,如 MasterStatus、MasterBrand、... {Structure: ID, Title}
  • 还有另外两个表“注释”和“文件”。一个声明可以有多个评论和多个文件。
  • 我需要显示一个仪表板,其中包含索赔列表。我需要显示主表中的标题以及评论和评论的数量。文件。

现在,我对该仪表板有两种视图,一种是针对“客户”类型的用户,仅限于某些详细信息,另一种是针对内部用户的详细视图。您可以说客户视图是内部视图的子集。

我看到两个选择 -

  1. 选项#1:创建单个 vw_Internal 视图并 用它来获取数据 用户。
  2. 选项#2:我创建一个 vw_Customer 其中只有那些字段 客户需要并且 然后我创建一个 vw_Internal 将类似于:vw_Customer INNER JOIN 主表。简而言之我会延长 要包含的基本 vw_Customer 更多领域。

从速度和性能的角度来看,选项#2 有意义吗? Opt#1 很简单,但考虑到大量记录,我想确保客户不必为那些不会包含在仪表板中的额外查找等待更长的时间。

最后,我提到的最后一个功能有办法实现吗?即获取与ClaimDetail 表具有一对多关系的评论和文件的计数。我只需要计数或至少一个布尔字段,该字段表示声明是否有任何注释(文件相同) - 如果计数 = 0,则为 false。我还担心此功能对性能的影响。

提前致谢。

I need some help with forming basic SQL-VIEWs for a bunch of my tables. Here's a quick overview

  • I've a ClaimDetail table and it has got some Lookup fields like StatusID, BrandID, SalespersonID, etc..
  • As usual, the lookup fields map to master tables like MasterStatus, MasterBrand, ... {Structure: ID, Title}
  • Also there're two other tables Comments and Files. A Claim can have multiple Comments and multiple Files.
  • I need to display a Dashboard which will be a list of Claims. I need to display titles from the Master tables and count of the comments & files.

Now, I've two views of this Dashboard one is for users of type Customer which is limited to certain details and another one is a detailed view which is meant for Internal users. You can say that the Customer view is a sub-set of the Internal view.

I see two options -

  1. Opt#1: Create a single vw_Internal view and
    use it to fetch data for both the
    Users.
  2. Opt#2: I create a vw_Customer
    which has onlt those fields which
    are required for the Customer and
    then I create a vw_Internal which
    will be like: vw_Customer INNER JOIN
    Master tables. In short I'll extend
    the basic vw_Customer to include
    more fields.

Does option#2 make sense from speed and performance point of view? Opt#1 is simple but considering the huge number of records I want to make sure that the Customers don't have to wait a bit longer for those extra lookups which not are going to be included in their Dashboard.

Finally, is there a way for the last feature I mentioned? That is getting the count of Comments and Files which has a one-to-many relationship with the ClaimDetail table. I just need the count or atleast a boolean field which says whether a claim has any Comments or not (Same for Files) - if'll be false if the count = 0. I'm also concerned about the performane impact due to this feature.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

茶色山野 2024-11-25 11:00:04

关于视图定义,我将构建两个视图,并将它们分开——两个视图都不会引用另一个视图。这将允许您独立地优化查询,并且避免您在视图之上分层视图时遇到的任何问题;太多的层会使数据库管理、维护和重构变得特别具有挑战性。

对于数据聚合,常见的策略包括以下几种。比较、对比、测试和推断,看看什么最适合您的环境:

子查询

SELECT mt.Id, st1.HowMany, st2.HowManyOther, <etc>
 from MainTable mt
  inner join (select Id, count(*) HowMany
               from SubTable1
               group by Id) st1
   on st1.Id = mt.Id
  inner join (select Id, count(*) HowMany
               from SubTable2
               group by Id) st2
   on st2.Id = mt.Id

相当简单,尽管子查询可能会变得有点昂贵,即使有适当的索引。

count(distinct xx)

SELECT mt.Id, count(distinct st1.UniqueKey) HowMany, count(distinct st2.UniqueKey) HowManyOther, <etc>
 from MainTable mt
  inner join SubTable1 st1
   on st1.Id = mt.Id
  inner join SubTable2
   on st2.Id = mt.Id

这需要“子表”中有一个唯一的列,如果必须处理外连接或 NULL,就会变得混乱。


添加


首先,在上述任一查询中用(左)外连接替换内连接将从子表中产生 0+ 计数,只要您确保计数是在“右”表上完成的(因为 NULL 不会)没有得到统计)。要确定哪一个最适合您的环境,您必须编写并测试这两个查询。我猜第二个,因为第一个需要对子查询的表进行表扫描,而第二个执行连接,因此可能优化得更好,但 SQL 查询优化器比我更聪明(因为它知道你的索引并具有分布直方图你的数据)所以你想看看它会产生什么结果。

关于“分层视图”,如果我遵循正确的逻辑,我建议将内部视图构建为复杂/综合查询(所有联接、所有相关列),然后构建希望的客户视图就像

SELECT <customerOnlyColumns>
 from vw_Internal

With regards to the view definitions, I'd build two views, and I'd make them separate--neither view would reference the other. This would allow you to optimize the queries independantly, and it avoids any problems you'd get with views layered on top of views; too many layers can make databases management, maintenance, and refactoring particularly challenging.

As for the data aggregation, common tactics include the following. Compare, contrast, test, and extrapolate to see what fits best in your environment:

Subqueries

SELECT mt.Id, st1.HowMany, st2.HowManyOther, <etc>
 from MainTable mt
  inner join (select Id, count(*) HowMany
               from SubTable1
               group by Id) st1
   on st1.Id = mt.Id
  inner join (select Id, count(*) HowMany
               from SubTable2
               group by Id) st2
   on st2.Id = mt.Id

Fairly straightforward, though the subqueries might get kind of costly, even with proper indexing.

count(distinct xx)

SELECT mt.Id, count(distinct st1.UniqueKey) HowMany, count(distinct st2.UniqueKey) HowManyOther, <etc>
 from MainTable mt
  inner join SubTable1 st1
   on st1.Id = mt.Id
  inner join SubTable2
   on st2.Id = mt.Id

This requires a single unique column in the "subtables", and gets messy if you have to deal with outer joins or NULLs.


Added


First, replacing the inner joins with (left) outer joins in either of the above queries will produce 0+ counts from the subtables, so long as you make sure the count is being done on the “right” table (because NULLs don’t get tallied). To figure out which performs best on your environment, you’d have to write and test both queries. I’d guess the second, since the first requires table scans on the tables of the subqueries while the second performs joins and so may optimize better, but the SQL query optimizer is smarter than me (because it knows your indexes and has distribution histograms of your data) so you want to see what it comes up with.

With regards to “layered views”, if I’m following the logic right, I’d recommend building the Internal view as the complex/comprehensive query (all the joins, all the relevant columns), and then build the Customer view that’s hopefully as simple as

SELECT <customerOnlyColumns>
 from vw_Internal
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文