1

私は偽の株式市場タイプのデータベースを作成していますが、Transactionテーブルには特定のルールを適用するための何らかのロジックが必要です。Transactionこれが私が使用しているテーブルです:

Id  AccountId   Action  Qty Price   Amount
1   1           SELL    30  $1.00   $30.00
2   2           BUY     30  $1.00   -$30.00
3   1           SELL    20  $2.00   $40.00
4   3           BUY     20  $2.00   -$40.00
5   3           DEPOSIT            $100.00

ここでわかるBUY/SELLように、アクションには計算する必要のあるとが必要ですQty。DEPOSITアクションは必要ありません、またはそれはユーザーがテーブルにお金を入れるだけだからですPriceAmountQtyPriceAccount

これを行うために、ある種のトリガーを使用することを考えていました。より良い方法はありますか?

4

1 に答える 1

1

SQL Server 2012でテスト済み。(銘柄記号は省略されています。)

create table stock_transactions (
  trans_id integer primary key,
  trans_ts datetime not null default current_timestamp,
  account_id integer not null, -- references accounts, not shown

  -- char(1) keeps the table narrow, while avoiding a needless
  -- join on an integer. 
  -- (b)uy, (s)ell, (d)eposit
  action char(1) not null check (action in ('b', 's', 'd')),

  qty integer not null check (qty > 0),

  -- If your platform offers a special data type for money, you
  -- should probably use it. 
  price money not null check (price > cast(0.00 as money)),

  -- Assumes it's not practical to calculate amounts on the fly
  -- for many millions of rows. If you store it, use a constraint
  -- to make sure it's right. But you're better off starting
  -- with a view that does the calculation. If that doesn't perform
  -- well, try an indexed view, or (as I did below) add the 
  -- "trans_amount" column and check constraint, and fix up
  -- the view. (Which might mean just including the new "trans_amount"
  -- column, or might mean dropping the view altogether.)
  trans_amount money not null,

  -- Only (b)uys always result in a negative amount.
  check ( 
    trans_amount = (case when action = 'b' then qty * price * (-1)
                         else                   qty * price
                    end )
  ),

  -- (d)eposits always have a quantity of 1. Simple, makes logical 
  -- sense, avoids NULL and avoids additional tables.
  check ( 
    qty = (case when action = 'd' then 1 end)
  )
);

insert into stock_transactions values
(1, current_timestamp, 1, 's', 30,   1.00,   30.00),
(2, current_timestamp, 2, 'b', 30,   1.00,  -30.00),
(3, current_timestamp, 1, 's', 20,   2.00,   40.00),
(4, current_timestamp, 3, 'b', 20,   2.00,  -40.00),
(5, current_timestamp, 3, 'd',  1, 100.00,  100.00);

しかし、何が起こったのか見てください。トランザクションのタイプとして預金を追加したので、これは株式トランザクションのテーブルではなくなりました。今では、当座預金のテーブルのようなものになっています。

アカウント所有者が購入したいものを購入するのに十分なアカウントがアカウントにあることを確認するには、CHECK制約以上のものが必要になります。

SQL Serverでは、クラスター化インデックスに関する決定が重要です。少し考えてテストしてください。アカウントID番号について頻繁に問い合わせることを期待しています。

于 2012-09-09T00:34:49.573 に答える