測試在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號碼。
Imo a [check constraint](http://msdn.microsoft.com/zh-cn/library/ms188258(v = sql.105).aspx)將會更好。 – StuartLC
由於購買,銷售和存款有不同的要求,人們可能會爭辯說,您應該使用適合每個要求的獨立表格。這會[規範化](http://en.wikipedia.org/wiki/Database_normalization)設計,並允許列的簡單約束。如果你想要防止賣空股票,即賣出你沒有持有的股票,那麼觸發器是合適的。 – HABO
@HABO - 這種類型的東西有特定的模式嗎?我感覺好像所有事務的單個表是最有意義的,因爲我有其他表引用它。我還爲賬戶表設置了一個觸發器設置,用於更新餘額 – Ryan