SQL Schema - 具有修饰符的汽车模型

时间:2016-10-03 14:57:38

标签: sql database-design

我需要为以下场景构建数据库:

我将有一个拍卖输入流,我想为拍卖中的项目制作价格直方图(即他们通常会去的等等)。

输入流类似于:

    {['item_id': 1, ... 'price': 123, ...],
     ['item_id': 1, ... 'price': 124, ... modifiers: [1, 2, 3],
     ['item_id': 1, ... 'price': 125, ... modifiers: [100, 150, 500...],
     ['item_id': 2, ... 'price': 200, ...],
    ...}

您可能已经注意到,item不仅包含一些id,还包含modifiers。可以把它想象成可以用额外的东西修改的汽车(例如AC,电子窗等)。

存储此信息的最有效方法是什么?基本上我想要的是每个可能发生的组合unique id。没有必要随时存储它,但如果有这种组合的拍卖,并且该组合尚不存在,那么就创建它。

我想到了类似的东西:

base_item:
 id

modifier: 
 id

item:
 id (autonumber)
 base_item_id

item_modifications:
 item_id (FK item.id)
 modification_id (FK modifier.id)

item_price_history:
 item_id (FK item.id)
 price
 time

此设置可能有效。问题是,想象一下,我每天都有数亿次这样的拍卖(即拍卖信息每20分钟更新一次,平均每次拍卖200万次)。

我希望能够快速执行以下操作:INSERT INTO item_price_history VALUES (some_item_id, some_price, now())但是为了做到这一点,我需要找到some_item_id。我知道base_item_idmodifiers(来自拍卖本身),但我认为这样做的次数相当昂贵吗?

即,伪代码:

for a in auctions:
    base_item_id = a['item_id']
    modifiers = a['modifiers']
    price = a['price']

    actual_item_id = some_query(base_item_id, modifiers) #expensive. Can be avoided?
    insert_into_histogram(auctual_item_id, price) #expensive but necessary I think

我在这个设计中是否有一些明显的错误?

1 个答案:

答案 0 :(得分:0)

您描述的架构是教科书解决方案。

但哇,这将是一个与之合作的野兽。据我了解,每次添加价格记录时,您都必须找到具有该确切参数集的项目记录:不多也不少。如果不存在此类项目记录,则必须创建项目记录。只有这样才能添加价格记录。

虽然我认为应该非常小心非规范化,但在这种情况下我会非常想要反规范化。也就是说,在我看来,在实践中,项目记录的关键是基本项目ID和修饰符的组合。我很想创建一个"修饰符字符串"通过将所有修饰符的代码或ID串联在一起而形成。当然要可行,他们必须按照规定的顺序串联起来,就像你不能同时拥有" 1,2"和" 2,1"。但是你可以很容易地找到所需的项目记录:只需要一个构建连接修饰符字符串的函数,然后选择其中base_item_id = @base和modifiers = @modifiers的项目。如果未找到,请创建记录和所有关联的修饰符记录。

我强烈倾向于将此修饰符字符串与单个修饰符记录一起冗余,但是像这样串联在一起的数据很难处理。我的意思是,如果您有一个像您描述的教科书架构,并且有人想知道带空调的汽车的价格,那么很容易从price.item中选择*(从项目连接修改器中选择id) modifier.item_id = item.id其中modifier.name =' AC')。但是尝试在连接的字符串上执行此操作,例如AC的ID是" 17"。选择blah blah,其中modifier_string喜欢'%17%'不起作用:它会找到117和171等等。喜欢'%,17,%'没有工作,因为如果它是第一个或最后一个,它将无法找到它。等等。这就是为什么我经常告诉人们不要像这样将数据串起来:创建单独的记录。但是,如果最常见的用例是您希望记录具有特定的修饰符组合,则创建冗余修饰符字符串是合理的非规范化。 (这是我第一次打字,我不小心输入了“道德败坏”,这可能是弗洛伊德的失误。)