Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Базы данных под .NET > БД - состояние "Счета"


Автор: Pankon 13.10.2006, 11:40
Есть Юзеры на счет которых приходят условные пункты, после определенных действий юзера;
Юзеры могут свои пункты тратить, на определенные вещи;
Каждый Юзер может смотреть свое состояние "Счета" и свои приходы(и по какому поводу), расходы(и по какому поводу)...
"Хозяин базы" может смотреть всевозможные отчеты и статистики...

Порассуждав немного и прикинув - сколько будет записей, можно сделать вывод, что состояние счета Юзера простым суммированием в таблице приходы и отниманием суммы из таблицы расходы, будет очень "накладно(время)" для БД...


Kак это делается в подобных случаях(например банковские счета, кредитные карточки и. т.д.)?

Автор: mr.DUDA 13.10.2006, 13:27
Проще всего поставить триггер на insert, update и delete для таблицы с приходами-расходами; этот триггер выполнит суммирование денег на счёту и обновит таблицу с суммами (это отдельная таблица). Так мы добъёмся того, что вычисления будут выполняться только тогда, когда что-то действительно меняется, и автоматически.

Автор: Pankon 17.10.2006, 11:52
Цитата(mr.DUDA @  13.10.2006,  13:27 Найти цитируемый пост)
для таблицы с приходами-расходами
 это одна таблица? Я хотел две сделать: одна для приходов, другая для расходов...

Автор: mr.DUDA 17.10.2006, 12:56
Pankon, количество таблиц принципиального значения не играет. Если таблиц две, просто будет два одинаковых триггера. Например, имеем структуру БД как на приаттаченном скриншоте. Тогда для создания триггера для таблицы Prihods надо выполнить такой SQL:

Код
CREATE TRIGGER [Prihods_Changed]
   ON  [dbo].[Prihods]
   AFTER INSERT, UPDATE, DELETE
AS 
BEGIN
    DECLARE @prihodSum real
    DECLARE @rashodSum real
    DECLARE @accountId int

    SELECT @accountId = (SELECT TOP 1 AccountID from Inserted)
    IF @accountId IS null
        SELECT @accountId = (SELECT TOP 1 AccountID from Deleted)

    SELECT @prihodSum = (
        SELECT SUM([Prihods].[Value]) FROM [Prihods]
        WHERE [Prihods].[AccountID] = @accountId)
    
    SELECT @rashodSum = (
        SELECT SUM([Rashods].[Value]) FROM [Rashods]
        WHERE [Rashods].[AccountID] = @accountId)

    UPDATE [Accounts] 
    SET [Value] = @prihodSum - @rashodSum
    WHERE [AccountID] = @accountId
    
END


Для таблицы Rashods всё будет то же самое, кроме первых двух строчек:
Код
CREATE TRIGGER [Rashods_Changed]
   ON  [dbo].[Rashods]


Добавлено @ 12:58 
З.Ы. ещё есть такая штука как Computed columns (по крайней мере в 2005-м точно есть, в 2000-м не помню), вроде можно сделать вычисляемую колонку обновляемую автоматически.

Автор: Pankon 19.10.2006, 11:29
mr.DUDA, спасибо за помощь


Цитата(mr.DUDA @  17.10.2006,  12:56 Найти цитируемый пост)
Computed columns (по крайней мере в 2005-м точно есть,
 база как раз на 2005... Computed columns - с чем это едят? (т.е. где это искать, и как с этим работать, в двух словах, если можно)(2005 еще в глаза не видел smile)

Автор: mr.DUDA 19.10.2006, 14:30
Цитата(Pankon @  19.10.2006,  11:29 Найти цитируемый пост)
 база как раз на 2005... Computed columns - с чем это едят? (т.е. где это искать, и как с этим работать, в двух словах, если можно)(2005 еще в глаза не видел )

Это есть в SQL Server books online, я с этим не работал но пару раз натыкался - это что-то вроде полей, которые хранятся в БД, но автовычисляются. По ним индексы строить можно и т.п.

ИМХО, для твоей задачи моих триггеров достаточно smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)