简体   繁体   English

尝试考虑最佳的数据库模式来存储需要连接的日期范围

[英]Trying to think of the best database schema for storing dates ranges that will require joins

(Table names in quotes) (表名用引号引起来)

Let's say there are "users" that try to sells "products". 假设有一些“用户”试图销售“产品”。 They earn a commission on all "product_sales" (id, product_id, user_id, total, sale_date). 他们获得所有“ product_sales”(id,product_id,user_id,total,sale_date)的佣金。 I want to somehow store their commission rate based on certain dates. 我想以某种日期存储他们的佣金率。 For example, a user will earn 1% from 2015-01-01 to 2015-01-15, 2% from 2015-01-16 to 2015-01-28, and 3% from 2015-01-29 onwards. 例如,从2015年1月1日到2015年1月15日,用户将获得1%的收入;从2015年1月16日到2015年1月28日,将获得2%的收入;从2015年1月29日起,用户将获得3%的收入。

  1. I want to run a query that calculates the total commissions for a user in January. 我想运行一个查询,计算一月份用户的总佣金。

  2. I want to run a query that calculates daily earnings in January. 我想运行一个查询,计算一月份的每日收入。

How do I store the commission rates? 如何存储佣金率? One idea was having a table "user_commissions" that has (id, user_id, commission_rate, from_date, to_date). 一个想法是拥有一个表“ user_commissions”,该表具有(id,user_id,commission_rate,from_date,to_date)。 It would be easy to calculate the rate for (1) if commissions stayed the same, in which case I'd do this: 如果佣金保持不变,则很容易计算(1)的费率,在这种情况下,我可以这样做:

SELECT (sum(total) * 0.01) as total_commissions FROM product_sales WHERE user_id = 5 and sale_date between '2015-01-01' and '2015-01-31'

But with commission rates variable this is more complex. 但是随着佣金率的变化,这更加复杂。 I need to somehow join the commissions table on each sale to get the right totals. 我需要以某种方式加入每次销售的佣金表,以获取正确的总数。

Another question would be: 另一个问题是:

  • How do I store the users' current commission rate that doesn't have an expiration date and include that in the reports? 如何存储没有到期日期的用户当前佣金率,并将其包括在报告中? In my example, "3% from 2015-01-29 onwards". 在我的示例中,“自2015年1月29日起为3%”。 This has no end date. 没有结束日期。

Your table structure is a very reasonable structure and often used for slowly changing dimensions. 您的表格结构是一种非常合理的结构,通常用于缓慢更改尺寸。 Storing the effective and end dates in the structure is important for efficiency. 在结构中存储有效日期和结束日期对于提高效率很重要。

One way to store to_date for the most recent commission is to use NULL . 存储最新佣金的to_date一种方法是使用NULL This allows you to do: 这使您可以执行以下操作:

select *
from commissions
where to_date is null

to get the most recent record. 获取最新记录。

However, a better way is to use some far distant date, such as '9999-12-12'. 但是,更好的方法是使用一些较远的日期,例如“ 9999-12-12”。 This allows you get the most recent commission using: 这使您可以使用以下方式获得最新的佣金:

where curdate() between from_date and to_date

This is an expression that can also make use of an index on from_date, to_date . 这是一个表达式,也可以使用from_date, to_date上的索引。

Honestly, I would store user commission percentages and the effective dates of those commissions in one table. 老实说,我会将用户佣金百分比和这些佣金的生效日期存储在一张表中。

TABLE: COMMISSION
user_id, date_effective, commission

In the other table I would store sales data. 在另一个表中,我将存储销售数据。 With each sale, I would keep the commission the salesperson got on the sale. 对于每笔交易,我都会保留销售员获得的佣金。 (Added bonus, you can change the commission on any sale, like an override of sorts.) (增加了奖金,您可以更改任何销售的佣金,例如优先选择。)

TABLE: SALE
sale_id, sale_date, user_id, sale_amount, commission

When you create the row in your program, you can grab the correct commission rate using the following query: 在程序中创建行时,可以使用以下查询获取正确的佣金率:

SELECT commission from commission WHERE user_id=[user's id] AND date_effective<=[sale date, today] ORDER BY date_effective ASC;

MySQL Left Joins, and SQL in general, can get really tricky when trying to join on dates that don't exactly match up. 当尝试在不完全匹配的日期上进行连接时,MySQL Left Joins和SQL通常会变得非常棘手。 (Looking back, basically.) I am struggling with the same problem right now without the luxury of the solution I just suggested. (基本上回头看看。)我现在正面临着同样的问题,而没有我刚刚建议的解决方案那么奢侈。

(This whole post is based on the assumption that you aren't going to be directly interacting with this database through a DBMS but instead through an application.) (本篇文章的全部假设是您不会通过DBMS直接与该数据库交互,而是通过应用程序与之交互。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM