每次采取某项行动时,我都需要更新一个表格。
MemberTable
Name varchar 60
Phone varchar 20
Title varchar 20
Credits int
< - 需要不断更新的 我应该用以下内容更新此表:
UPDATE Members
SET Credits = Credits - 1
WHERE Id = 1
或者我应该创建另一个名为account的表,只有两列,如:
帐户表
Id int
MemberId int
< - 成员表的外键Credits int
并使用以下内容进行更新:
UPDATE Accounts
SET Credits = Credits - 1
WHERE MemberId = 1
哪一个更快更有效?
我已经读过SQL Server必须读取整行才能更新它。我不确定这是不是真的。任何帮助将不胜感激
答案 0 :(得分:1)
实际上后面的方式会更快。
如果您的数字交易非常庞大,那么毫秒精度非常重要,这样做会更好。
或者也许有些成员没有学分,你也可以节省一些空间。
但是,如果不是,那么保持表结构规范化是件好事。如果每个帐户始终都有credit
,最好将其作为表Member
中的列添加。
尽量不要使用不必要的中间表,这会占用更多空间(包括所有这些外键和附加ID)。此外,它还使您的架构更复杂。
最后,这取决于您的要求。
答案 1 :(得分:1)
我知道这并没有直接回答这个问题,但我会把它作为替代解决方案。
您是否对历史交易感到困扰?不是每个人都会,但如果你或其他未来的读者,这就是我将如何处理这个问题:
CREATE TABLE credit_transactions (
member_id int NOT NULL
, transaction_date datetime NOT NULL
CONSTRAINT df_credit_transactions_date DEFAULT Current_Timestamp
, credit_amount int NOT NULL
, CONSTRAINT pk_credit_transactions PRIMARY KEY (member_id, transaction_date)
, CONSTRAINT fk_credit_transactions_member_id FOREIGN KEY (member_id)
REFERENCES member (id)
, CONSTRAINT ck_credit_transaction_amount_not_zero CHECK (credit_amount <> 0)
);
就写作表现而言......
INSERT INTO credit_transactions (member_id, credit_amount)
VALUES (937, -1)
;
很简单,呃!不需要行锁。
这种方法的缺点是,要计算成员“余额”,你必须进行一些计算。
CREATE VIEW member_credit
AS
SELECT member_id
, Sum(credit) As credit_balance
, Max(transaction_date) As latest_transaction
FROM credit_transactions
GROUP
BY member_id
;
然而,使用视图可以使事情变得美观和简单,并且可以进行适当的优化。
哎呀,您可能想在该视图上输入NOLOCK(在做出决定之前阅读此内容)以减少锁定影响。
优点:快速写入速度,可用的交易记录
缺点:读取速度较慢
答案 2 :(得分:0)
由于ID是主键,所有dbms必须做的是查找索引中的键,获取记录并进行更新。应该没有太大的性能问题。
使用帐户表可以获得完全相同的访问方法。但你是对的;由于每条记录的数据较少,您可能更经常在内存缓存中拥有该记录,从而节省了物理读取。但是,我不希望这种情况经常发生。好吧,您可能更多地使用您的成员表而不是帐户表。这使得成员记录更有可能已经存在于缓存中,因此反之亦然,因此您的帐户表访问速度较慢。
缓存访问与物理读取是唯一的区别,因为使用主键,您将以与ID索引相同的方式行走,而不是直接访问一个特定记录。
我不建议使用帐户表。它有点模糊了数据结构,两个表之间的关系为1:1,可能无法被其他用户识别。你不可能从中获得太多收益。 (如上所述,你甚至可能会失去表现。)