我需要开发一个系统。该系统的一部分是,每天计算一个人的付款(一个人每天得到$ x.xx,基于某些规则),并存储在一个Transaction表中,该表目前由personId,金额和日期。
CREATE TABLE DailyTransaction
(
DailyTransaction INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
PersonId INT NOT NULL,
TransactionDate DATE NOT NULL
)
现在系统中有8,000人,所以每天有8,000行通过流程写入表中。
我认为,存储日期,重复得太多了。之后可能会在该日期进行查询。所以,我想创建一个'DailyRun'表,其中包含日期和id(如果需要,稍后会有更多列)。因此,当我执行每日付款插入运行以填充8,000行时,我首先使用日期创建DailyRun记录,然后将该行的ID分配给Transaction表。
CREATE TABLE DailyRun
(
DailyRunId INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
RunDate DATE NOT NULL
)
CREATE TABLE DailyTransaction
(
DailyTransaction INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
PersonId INT NOT NULL,
DailyRunId INT NOT NULL
)
因此,如果我想要特定日期的所有行,我会在DailyRun表中找到日期,然后通过外键获取与其关联的所有记录到事务表。
到目前为止似乎没问题(除非有人发现问题?)
但是,现在问题。
另一个要求是,在白天,可以将特别付款添加到交易表中。所以,额外的一次性付款。但是,它不会被创建为Run。所以,DailyRun表中没有行。一个想法是在Transaction表中可以为空的DailyRun ID,但是...当我需要获取特定日期的所有事务时 - 好吧,没有日期字段......现在RunID设置..所以它不会是找到。
我能做的是允许Null RunID,并且还有一个可以为空的'AdHocPaymentDate'字段。那么,如果是特别付款,我可以将RunID留空,并填充AdHocPaymentDate吗?
如果是预定的付款运行,我会填充RunID,并将AdHocPaymentDate保留为空?
但是,不是可空的字段慢,或者由于某种原因不推荐?
有没有更好的方法来解决这个问题?除了持有定期每日付款的表格之外,可能还有一个单独的“Ad Hock Payment”表,其中包含临时付款?
答案 0 :(得分:1)
似乎有业务要求将临时付款与每日运行区分开来。我想你可以使用这种解决方案。使用“DailyRun”和“AdHoc”作为事务类型,然后使商业智能从日常运行(服务)和adhocs(用户交互)中正确插入事务
CREATE TABLE [TransactionType]
(
[Id] INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
[Name] NVARCHAR(40)
)
CREATE TABLE [Transaction]
(
[Id] INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
[TransactionTypeId] INT NOT NULL REFERENCES TransationType
[PersonId] INT NOT NULL REFERENCES person
[Date] DATE NOT NULL
)
答案 1 :(得分:1)
我不确定如何处理您在行中重复值的问题。我能提供的最好的是没有规范化的原则,即“寻找出现在多行中的值。如果找到它们,则用整数和另一个表替换。”无论如何,如果你这样做,你将有一排又一排的重复整数。
此外,由于“运行”和临时付款都有日期,因此没有合理的理由从交易表中删除日期。
我如何开始。 。 强>
根据您的描述,这不是交易表。这是一张付款表。
create table payments (
payment_id integer not null,
payment_date date not null,
payment_amount decimal(12, 2) not null
check (payment_amount > 0),
-- For identifying a(d hoc) and r(un) payments
payment_type char(1) not null
check (payment_type in ('a', 'r')),
person_id integer not null, -- references a table not shown
primary key (payment_id),
unique (payment_id, payment_type),
unique (payment_date, payment_type, person_id)
);
{payment_date,payment_type,person_id}的唯一约束非常重要。您的描述似乎要求每人每个日期不超过一次“运行”付款,每人每个日期不得超过一次临时付款。在任何情况下,除了对代理ID号的主键约束外,还需要对实际数据有唯一约束。
{payment_id,payment_type}的唯一约束也很重要。如果您需要存储有关运行付款或临时付款的更多详细信息,您可以构建一个这样的表。
create table payments_ad_hoc (
payment_id integer not null,
payment_type char(1) not null
default 'a'
check (payment_type = 'a'),
other_columns_go_here char(1) not null
default 'x',
primary key (payment_id),
foreign key (payment_id, payment_type)
references payments (payment_id, payment_type)
);
检查约束和外键约束的组合可确保此表中的行将引用临时付款,而不仅仅是任何付款。 “运行”付款的结构类似。