0

我有开发系统的需求。该系统的一部分是,每天都会计算一个人的付款(根据某些规则,一个人每天得到 $x.xx),并存储在一个交易表中,该表目前包括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 表中找到日期,然后通过外键将与其关联的所有记录获取到事务表。

到目前为止,这似乎还可以(除非有人看到问题?)

但是,现在的问题。

另一个要求是,在白天,可以将临时付款添加到交易表中。所以,额外的一次性付款。但是,它不会被创建为运行。因此,DailyRun 表中没有行。一个想法是 Transaction 表中可以为空的 DailyRun ID,但是......当我需要获取特定日期的所有交易时 - 嗯,没有日期字段......现在 RunID 设置......所以它不会成立。

我能做的是允许 Null RunID,并且还有一个可为空的“AdHocPaymentDate”字段。因此,如果它是 Adhoc 付款,我可以将 RunID 保留为空,并填充 AdHocPaymentDate?

如果它是计划付款运行,我填充 RunID,并将 AdHocPaymentDate 保留为空?

但是,可空字段是不是很慢,或者由于某种原因不推荐?

有没有更好的方法来处理这个?除了保存常规每日付款的表之外,也许还有一个单独的“临时付款”表,它保存临时付款?

4

2 回答 2

1

似乎存在将临时付款与日常付款区分开来的业务需求。我想你可以使用这种解决方案。使用“DailyRun”和“AdHoc”作为事务类型,然后让商业智能从日常运行(服务)和临时(用户交互)中正确插入事务

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
)
于 2013-06-10T12:01:20.187 回答
1

我不确定如何解决您对行中重复值的担忧。我能提供的最好的方法是,没有规范化原则说:“寻找出现在多行中的值。如果找到它们,请将 then 替换为整数和另一个表。” 无论如何,如果你这样做,你将有一行又一行的重复整数。

此外,由于“运行”和临时付款都有一个日期,因此没有逻辑理由从交易表中删除该日期。


我将如何开始。. .

根据您的描述,这不是交易表。这是一张付款表。

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)
);

检查约束和外键约束的组合保证了该表中的行将引用临时付款,而不仅仅是任何付款。“运行”付款的结构类似。

于 2013-06-10T12:47:03.717 回答