CREATE TABLE IF NOT EXISTS account
(
id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
username TEXT NOT NULL,
coin NUMERIC NOT NULL DEFAULT 0 CHECK ( coin >= (0)::numeric ),
version BIGINT NOT NULL DEFAULT 0,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE
);
comment on table account is '账户表.';
comment on column account.id is '自增唯一 ID 标示.';
comment on column account.username is '账户名.';
comment on column account.coin is '余额.';
comment on column account.version is '账户余额版本标识(乐观锁).';
CREATE TABLE IF NOT EXISTS transaction
(
id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
account_id INTEGER NOT NULL REFERENCES account (id),
value NUMERIC NOT NULL,
balance NUMERIC NOT NULL DEFAULT 0 CHECK ( balance <> 'NaN'::numeric AND (balance >= (0)::numeric)),
type INTEGER NOT NULL CHECK ( type IN (1, 2, 4, 8, 16) ),
narration TEXT NOT NULL DEFAULT '',
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE,
deleted_at TIMESTAMP WITH TIME ZONE
);
comment on table transaction is '账户余额变动交易表, 此表记录了每笔交易账户余额变动日志.';
comment on column transaction.id is '自增唯一 ID 标示.';
comment on column transaction.account_id is '账户 ID, 关联账户表.';
comment on column transaction.value is '交易代币数额,收入为正, 支出为负.';
comment on column transaction.balance is '交易完成后剩余的账户余额.';
comment on column transaction.narration is '交易描述.';
comment on column transaction.type is '交易类型.';
-- TRIGGER
CREATE OR REPLACE FUNCTION transaction__sync_balance()
RETURNS TRIGGER AS
$$
BEGIN
-- UPDATE
UPDATE account
SET coin = coin + NEW.value,version = version + 1
WHERE id = NEW.user_id
RETURNING coin INTO NEW.balance;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER sync_balance_trigger
BEFORE INSERT
ON transaction
FOR EACH ROW
EXECUTE FUNCTION transaction__sync_balance();
SELECT pg_advisory_xact_lock(1001, account_id)
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.