是否有任何指导方针或经验法则来确定何时存储聚合值以及何时动态计算它们?
例如,假设我有用户可以评分的小部件(请参阅下面的架构)。每次我显示一个小部件时,我都可以从Ratings表格中计算出平均用户评分。或者,我可以将平均评分存储在Widget表格中。这将使我不必在每次显示小部件时计算评分,但是每次用户对小部件进行评分时我都必须重新计算平均评分。
Ratings Widgets
--------- -------
widget_id widget_id
user_id name
rating avg_rating <--- The column in question
Run Code Online (Sandbox Code Playgroud) 我们正在开发一个预付卡平台,该平台主要保存有关卡及其余额、付款等的数据。
到目前为止,我们有一个 Card 实体,它有一个 Account 实体的集合,每个 Account 都有一个 Amount,它在每次存款/取款时更新。
现在团队中有一场辩论;有人告诉我们,这违反了Codd 的 12 条规则,并且在每次付款时更新其价值很麻烦。
这真的有问题吗?
如果是,我们如何解决这个问题?
在 SQL Server 中,我总是发现获取数据集的最大行数很痛苦,我正在寻找一个方法列表来检索最大行数,并提供一些有关性能和可维护性的指导。
示例表:
DECLARE @Test TABLE (ID INT IDENTITY(1,1), name VARCHAR(50),
dateOfBirth DATETIME, TaxNumber varchar(10))
INSERT INTO @Test (name, dateOfBirth, TaxNumber)
SELECT 'Fred', convert(datetime, '25/01/1976', 103), '123' UNION ALL
SELECT 'Bob', convert(datetime, '03/03/1976', 103), '234' UNION ALL
SELECT 'Jane', convert(datetime, '13/06/1996', 103), '345' UNION ALL
SELECT 'Fred', convert(datetime, '14/02/1982', 103), '456' UNION ALL
SELECT 'Bob', convert(datetime, '25/10/1983', 103), '567' UNION ALL
SELECT 'Jane', convert(datetime, '12/04/1995', 103), '678' UNION ALL
SELECT 'Fred', convert(datetime, '03/03/1976', 103), '789'
select * from …Run Code Online (Sandbox Code Playgroud) 设置复式记账系统供个人使用并帮助管理真正的小型企业。尝试添加一些现在看起来相关的功能。
对于不熟悉会计的人来说,其逻辑是:货币不会被创造也不会被销毁,它只是从一个账户转移到另一个账户。每笔交易都有借方和贷方。几个例子:
雇主的薪水:贷记Salary、借记Bank Account- 钱来自您的薪水,并存入您的银行帐户。
支付租金:贷记Bank Account、借记Rent- 钱来自您的银行帐户并转到您的租金帐户。
账户可以是“股票”账户,即账户余额是累计的(银行账户就是一个很好的例子),也可以是流量/流量账户,即账户余额是非累计的(租金是一个很好的例子)。
这个想法是有一个JournalDB存储主要条目的主表。该表JournalTx存储了交易中涉及的每个帐户。每个条目 (from JournalDB) 都有一个 ID,并且每个事务 (from JournalTx) 都链接到一个日记帐条目。基本情况是 中有 1 个条目JournalDB和两个(或更多)事务JournalTx。每个条目都可以有 a cost_center、 aproject和一些其他属性。
基本上有两种设计方式(根据这个问题) - 每个事务样式一行,每个事务两行。在第一个中,我将有一个信用帐户和借记帐户的行,在第二个(这个)中有 n 行,每个受影响的帐户一个。
Accounts 表是会计科目表(用会计术语)。它具有层次结构 - 我使用了邻接列表样式。虽然不是很频繁,但账户会有 CRUD 操作。我补充说parent_imediate,parent_second作为一个非常丑陋的聚合解决方案(例如,计算资产账户的总数),但考虑到挑战(经过长时间的研究,不知道如何做到这一点),这似乎是一个简单的出路 -也欢迎就此事项提出任何意见或建议。
获取报告,通常是 montlhy:基本上所有帐户都包含影响每个事件的聚合交易。最好的情况是数据透视表(列作为日期),每一行都是一个帐户。我想这个的“堆叠”版本也可以正常工作。
帐户只是一个维度 - 例如,我可能想要查询 bycost_center或 by project。
我想有能力预算帐户(因此预算表),以及有“目标”(我想休假,这将花费我 1.000 …
我有一个类似于之前讨论的要求:
我有两张桌子,[Account].[Balance]并且[Transaction].[Amount]:
CREATE TABLE Account (
AccountID INT
, Balance MONEY
);
CREATE TABLE Transaction (
TransactionID INT
, AccountID INT
, Amount MONEY
);
Run Code Online (Sandbox Code Playgroud)
当对[Transaction]表进行插入、更新或删除操作时,[Account].[Balance]应根据[Amount].
目前我有一个触发器来完成这项工作:
ALTER TRIGGER [dbo].[TransactionChanged]
ON [dbo].[Transaction]
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
IF EXISTS (select 1 from [Deleted]) OR EXISTS (select 1 from [Inserted])
UPDATE [dbo].[Account]
SET
[Account].[Balance] = [Account].[Balance] +
(
Select ISNULL(Sum([Inserted].[Amount]),0)
From [Inserted]
Where [Account].[AccountID] = [Inserted].[AccountID]
)
- …Run Code Online (Sandbox Code Playgroud) 我目前正在设计一个事务表。我意识到需要计算每一行的运行总数,这可能会降低性能。所以我创建了一个包含 100 万行的表用于测试。
CREATE TABLE [dbo].[Table_1](
[seq] [int] IDENTITY(1,1) NOT NULL,
[value] [bigint] NOT NULL,
CONSTRAINT [PK_Table_1] PRIMARY KEY CLUSTERED
(
[seq] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)
我试图获取最近的 10 行及其运行总数,但花了大约 10 秒。
--1st attempt
SELECT TOP 10 seq
,value
,sum(value) OVER (ORDER BY seq) total
FROM Table_1
ORDER BY seq DESC
--(10 rows affected)
--Table 'Worktable'. Scan count 1000001, logical reads 8461526, …Run Code Online (Sandbox Code Playgroud) performance database-design sql-server t-sql execution-plan query-performance
我有两个表:详细信息和这些详细信息的总计。
详细信息(缓慢的解决方案):
select
OrderId = r.OrderId
, TotalQty = SUM(r.Quantity)
, TotalGrossConsid = SUM(r.Price * r.Quantity)
from dbo.Order r
group by r.OrderId
Run Code Online (Sandbox Code Playgroud)
总计(快速解决方案):
select
t.OrderId
, t.TotalQty
, t.TotalGrossConsid
, t.IsValid
from dbo.OrderTotal t
Run Code Online (Sandbox Code Playgroud)
有时总数变得无效(某些作业必须重新计算更改的总数,但会延迟)。如您所知,第二个查询更快,有效总数的数量多于无效总数。因此,我正在寻找一个组合查询,该查询从第二个表 (totals) 返回有效总数,并使用第一个慢查询返回动态重新计算的总数。所以我的目标将实现:所有总数都是有效的,响应时间比完全重新计算要快。
这是我的尝试(混合解决方案):
with fast_static(OrderId, TotalQty, TotalGrossConsid, IsValid)
as
(
select
t.OrderId
, t.TotalQty
, t.TotalGrossConsid
, t.IsValid
from dbo.OrderTotal t
)
, slow_dynamic(OrderId, TotalQty, TotalGrossConsid)
(
select
OrderId = r.OrderId
, TotalQty = SUM(r.Quantity)
, TotalGrossConsid = SUM(r.Price …Run Code Online (Sandbox Code Playgroud) performance sql-server-2008 query aggregate materialized-view
我的表结构如下:
TbDoc (ID int , ...)
TbDocActions( ID Int, DocID Int, Date DateTime, col1 int, col2 int, ...)
Run Code Online (Sandbox Code Playgroud)
我想要索引视图来获取每条TbDoc记录的最后一个 TbDocActions 列。此视图的结果必须如下所示:
DocID , col1, col2, ...
Run Code Online (Sandbox Code Playgroud)
为了通过视图获得此结果,我可以使用以下查询:
Select Z.DocID, X.*
From (Select DocID, Max(ID) as MaxActionID
From TbDocActions
Group By DocID
)Z
inner join TbDocActions X ON X.ID = Z.MaxActionID
Run Code Online (Sandbox Code Playgroud)
但我希望索引视图具有更好的性能。在索引视图中我不能使用Max()聚合函数。
sql-server ×4
aggregate ×2
mysql ×2
performance ×2
t-sql ×2
acid ×1
query ×1
rdbms ×1
transaction ×1
trigger ×1