Database 标准化和历史数据

Database 标准化和历史数据,database,database-design,relational-model,Database,Database Design,Relational Model,在我描述我的问题之前,我想先解决两件事: 我是一个经验丰富(虽然不是专家)的数据库设计师。我相信我对关系模型有很好的掌握 我对关系模型并没有如此坚定的理解,以至于我不知道在任何情况下该做什么。我还在学习 假设我们每个月从一家银行收到一份Excel电子表格,但并不总是同一家银行。电子表格只有六列:银行名称、账号、账户余额、客户(账户持有人)名称、客户SSN和账户持有人地址。每一行都有不同的帐号,并且没有帐号列在多行中。我们希望将此电子表格导入数据库,并在将来的任何时候说,“约翰·史密斯在2010年

在我描述我的问题之前,我想先解决两件事:

  • 我是一个经验丰富(虽然不是专家)的数据库设计师。我相信我对关系模型有很好的掌握
  • 我对关系模型并没有如此坚定的理解,以至于我不知道在任何情况下该做什么。我还在学习
  • 假设我们每个月从一家银行收到一份Excel电子表格,但并不总是同一家银行。电子表格只有六列:银行名称、账号、账户余额、客户(账户持有人)名称、客户SSN和账户持有人地址。每一行都有不同的帐号,并且没有帐号列在多行中。我们希望将此电子表格导入数据库,并在将来的任何时候说,“约翰·史密斯在2010年10月13日的地址是什么?”

    为了简单起见,假设每个客户只有一个地址,每个客户可以有零个或多个帐户。现在,让我们假设我们只需要导入一个Excel工作表,这是一个愚蠢的前提,但请容忍我。如果是这样,以下设计就足够了:

    bank
    --------
    id
    name
    
    account
    --------
    id
    bank_id
    customer_id
    number
    balance
    
    customer
    --------
    id
    name
    ssn
    address
    city
    state_id
    zip
    
    state
    --------
    id
    name
    
    我的问题的其余部分是基于这样一个前提,即您同意该模式是“正确的”,所以希望您能接受它

    现在,如果我们只做过一次进口,那就好了,但我们每个银行每年要做12次进口。我是这样想的:

    bank
    --------
    id
    name
    
    account
    --------
    id
    import_id
    bank_id
    customer_id
    number
    balance
    
    customer
    --------
    id
    name
    ssn
    address
    city
    state_id
    zip
    
    state
    --------
    id
    name
    
    import
    --------
    id
    date
    excel_file (blob)
    
    现在,每个帐户都与一个导入关联,我们可以肯定地说,“帐户12345来自10/13/10的导入572。”当您查看
    客户
    表时,它可能会变得更加模糊。由于
    customer
    表中的行数少于
    account
    表中的行数(因为有些客户有多个帐户),因此我们不像accounts和imports那样在客户和imports之间建立一对一的关系。我知道不会有数据丢失,也不会有数据完整性的损失,但不知何故,这仍然感觉像某种牺牲

    我的问题是(这可能太开放了):你认为这是存储数据的好方法吗?您是否会采取不同的做法?

    编辑:有一种重要的方式来思考这些实体,你必须意识到。不要将
    帐户
    视为一个随时间推移而存在的帐户。将
    帐户
    视为特定时间点上帐户的快照。因此,余额为100美元的账户12345与余额为150美元的账户12345不同。是的,在现实世界中,两个记录都绑定到同一个银行帐户,但我存储的是某个时间点的帐户快照。与客户的情况类似(但不完全相同)

    <> LI>当每个导入都绑定到一个特定的银行时,我可能会考虑将Bank ID放在导入表中,并将其从帐户表中剔除。
  • 如果您希望对历史地址数据进行记帐,并且您只从导入中获取该数据,则可以将地址字段添加到account表中,并将其从customer表中删除。诚然,如果多个导入的地址相同,这样做可能会导致重复。如果您非常关心这一点,您可以添加另一个表,可能是“address”,可能带有customer_id和address_id的复合主键。然后,您的导入表添加address_id字段,您的导入代码需要检查地址是否已经存在

  • 总的来说,我觉得这个设计不错

    导入/导入id本身除了存储日期之外还有什么意义吗?如果没有,我看不出有什么理由不将该表完全排除在外,并在account表上输入导入日期

    此外,如果需要历史地址信息,还需要客户表上的导入id(或导入日期:)

    更新

    如注释中所述,添加导入id不会考虑历史地址数据

    您需要的是某种类型的customer_history表,它将存储任何可能更改的数据,并通过外键链接回customer表

    customer
    ------
    id
    first_name
    last_name (assuming name wouldn't change--it certainly could)
    
    
    customer_history
    -----------------
    id
    customer_id
    import_id (or date)
    (address fields)
    

    如果帐户的详细信息可能会随着时间的推移而改变,那么您也需要一个历史记录表。

    我会谨慎地考虑客户只有一个地址的想法。(这在我的现实生活中是不真实的)。您可能需要通过更新每个负载上的客户来存储您最近获得的地址,或者您应该考虑将地址拆分为一个新表并将其链接到客户-也许有开始日期和结束日期,以便在您认为地址有效时显示给您。
    我想我也不会把import_id放在账户上。如果您这样做,您将为每个客户到银行的连接获得许多行(x12)。我想这不是你想要的。相反,您可以将一个帐户放在导入链接表中,让您知道该帐户已列在一个或多个导入中。

    对不起,我无法核对“每个客户只有一个地址”和“我们想说‘2010年10月13日约翰·史密斯的地址是什么’”这两种说法。您是否建议在每次导入时,为导入中找到的每个人创建一个新的客户记录?如果是这样,如果账号不同,您如何知道一次进口的John Smith与另一次进口的John Smith相同

    如果您为同一客户重复使用同一客户记录(这对我来说似乎是正确的),您在哪里可以找到以前的地址信息

    [经海报评论和修改后]

    好了,你就快到了。您确实需要将客户地址添加到Account表中(实际上应该重命名为AccountImports或类似的名称)。这是因为每个导入可能有不同的地址

    存储广告