这是在SQL Server中为每位客户存储日期资格的好方法吗?

时间:2015-08-13 15:49:07

标签: sql-server

我需要计算客户的折扣并按月将其应用到他们的帐户。规则只是客户必须有两个或更多的供应品才有资格获得折扣。

有些客户有简单的历史记录,他们在同一天开始使用两个耗材,并在同一天结束两个耗材。

许多客户的历史更加复杂,他们可以从单一供应开始,在短时间内将其更改为两个供应,然后再次回到单一供应,具有此主题的任何变化。

我目前的解决方案非常非常简单。我有一个名为[DiscountDays]的表,如下所示:

CREATE TABLE [DiscountDays] (
    AccountNumber NVARCHAR(20) NOT NULL,    
    DiscountDate DATE NOT NULL,
    PRIMARY KEY (AccountNumber, DiscountDate));

每日流程运行如下:

  • 如果每个客户今天都有资格享受折扣(今天提供两种产品)。如果他们在[DiscountDays]表格中添加一行,并附上他们的帐号和今天的日期;
  • 如果客户今天没有资格享受折扣,那就什么都不做。

完成后,我只需从[DiscountDays]表格中提取每位客户的累计折扣天数,然后使用它来确定应该支付多少折扣。我可以很容易地找出他们迄今为止已经支付了多少折扣。如果他们欠了一些折扣,那么这将导致在月底创建新的付款。

我还必须处理损失和其他并发症,但基本模型适用于我迄今为止所抛出的每一种情况。

现在有些事实和数据:

  • 此折扣首次于2014年1月1日开始提供;
  • [DiscountDays]表中目前有27,916,572行;
  • 这是83,376位客户的客户群,他们有资格获得至少一天的折扣。

这里显而易见的变化是存储非连续的日期。例如,假设客户有资格享受2014年1月1日的折扣,并且有资格到2015年5月10日。然后,他们有一个单一供应期,然后在2015年8月10日再次回到合格资格。

旧方法是为每个资格日期存储一行数据,即495 + 4 = 499行。

新方法是存储两行数据:

Account Number,Start Date, End Date
1234567,01-Jan-2014,10-May-2015
1234567,10-Aug-2015,13-Aug-2015

我可以看到这种新方法会大大减少存储的数据量,但它有一个更加复杂的直接缺点。

我喜欢原始解决方案,即使它是一个占位符,因为它很容易理解。它似乎也表现得非常好。

这是SQL-Server 2014。

我的问题是,我是否为自己存储未来的问题以最终创建数百万行数据的方式存储数据。我现在应该咬紧牙关并转而使用新的解决方案吗?

另外,如果我坚持使用原始解决方案,是否有任何"技巧"我可以用来使它更具可扩展性吗?我到目前为止唯一的想法是将帐号转换为整数键(使用查找表)以减少每行所需的存储空间。

编辑 - 我删除了我的表的原始版本,我允许NULL值并使用UNIQUE CLUSTERED索引作为伪PRIMARY KEY,因为主键不允许NULL值。

这引起了很多讨论,我不想讨论是否可以使用NULLable PRIMARY KEYs是好事。相反,我想专注于我原来的问题......

我认为Edgar Codd原本打算将所有数据库列都置为NULL,并且PRIMARY KEY不能允许NULLable列的规则是一个人为的规则,部分原因是由于误解而部分是由于技术限制a时间。但这条规则已经停滞不前,现在人们已经开始思考#34;这实际上是有意义的!

一般情况下,我使用UNIQUE CLUSTERED索引创建没有PRIMARY KEY的所有数据库。这适用于FOREIGN KEY约束,防止重复等。但是,我也可以理解为什么有些人会发现这种方法令人不安,因为它不符合他们对数据库设计的感知规则。

0 个答案:

没有答案