【问题标题】:Database SQL design数据库 SQL 设计
【发布时间】:2020-03-29 07:44:21
【问题描述】:

我正在制作一个 React 应用,现在我需要为每个用户存储 IBAN number, bank_name, bank_location etc...,每个用户只能拥有 1 个银行。

目前我有一个描述用户的表,

User(uid, name, lastname, bio, url_img, ..)

现在我必须添加新信息,您认为为银行信息创建一个新表是个好主意还是将新信息放在 User 表中更好?

想法 1:

User (  uid
      , name
      , lastname
      , bio
      , url_img
      , IBAN_number
      , bank_name
      , bank_location
      )

想法2:

User (uid, name, lastname, bio, url_img)

Bank_user_info(
       id
     , uid_user
     , IBAN_number
     , bank_name
     , bank_location
     )

想法 2 是个好主意,即使用户最多只有一个 bank_user_info 行???

【问题讨论】:

  • 这是一个口味问题,但我更喜欢第二种想法,因为每个表都会“持有”它自己的域。
  • IBAN 号码对每家银行都是唯一的。您缺少的一个字段是员工银行帐号。银行 ID 和银行帐号进入用户行。银行信息进入银行行。镇上通常只有几家银行,但员工很多。

标签: sql reactjs postgresql database-design


【解决方案1】:

第一种情况会导致逻辑错误,基本上没有bank 就不能存在user。鉴于一家银行可以拥有多个客户,您可能会不断重复银行信息并最终导致信息相互矛盾。冗余迟早会导致矛盾。

在第二种情况下,user 是独立的,但是(逻辑上)bank 在没有user 的情况下不存在,并且与第一种情况相同的冗余银行信息问题。

所以,我会推荐

-- only attributes relevant to a user
--
user {USER_ID, ...}
  PK {USER_ID}

-- only attributes relevant to a bank
--
bank {BANK_ID, ...}
  PK {BANK_ID}


-- User banking detail (only one bank per user)
--
user_bank {USER_ID, BANK_ID, ACCOUNT_NO, ... }
       PK {USER_ID}
       AK {BANK_ID, ACCOUNT_NO}

FK1 {USER_ID} REFERENCES user {USER_ID}
FK2 {BANK_ID} REFERENCES bank {BANK_ID}

如果用户可以使用多个银行:

user_bank {USER_ID, BANK_ID, ACCOUNT_NO, ... }
       PK {USER_ID, BANK_ID}
       AK {BANK_ID, ACCOUNT_NO}

FK1 {USER_ID} REFERENCES user {USER_ID}
FK2 {BANK_ID} REFERENCES bank {BANK_ID}

注意事项:

All attributes (columns) NOT NULL

PK = Primary Key
AK = Alternate Key (Unique)
FK = Foreign Key

【讨论】:

    【解决方案2】:

    由于银行表包含有关用户 ID 的信息,因此两个表的大小必须相等,因此两个表将毫无意义。由于 1 家银行(在现实世界中)将拥有 1 个以上的用户,因此可以通过使用单独的银行信息表来节省磁盘空间,而不会丢失任何数据。这是关系数据库的基本思想。

    重新考虑您为表格建议的字段。用户表应该有关于每个用户的唯一信息,加上一个标识他们的银行的 id。银行信息表将包含相同的 id,以及每家银行独有的任何其他内容。

    现在磁盘空间更便宜了,如果不太笨重,您可以考虑将所有内容放在一张表中。但是……假设一家银行有 1,000,000 名客户,然后更改了名称。您是更新一张巨表中的 1,000,000 行,还是更新银行信息表中的 1 行?

    【讨论】:

    • 也许我误解了我的情况,用户将使用表格自己输入信息(IBAN,location_delete 等...),而我不会提前输入可用的银行等...所以那里将是很少的共同数据。因为每个用户都会输入他们的银行详细信息,然后我将使用这些信息进行每月转账。
    • 数据集的大小将决定您是否从拥有两个表中获得任何收益。如果两条数据之间确实存在 1:1 的关系,那么将它们放入两个表中会稍微降低性能(更长的查询、更多出错的机会等)。
    • 1:1 的问题在于大多数情况下实际上都不是。这就是属于这种情况。我将授予用户只能拥有 1 个银行的规则,但 1:1 也意味着银行只能拥有 1 个用户。要执行 1:1,您的两个想法都需要对 IBAN_number 进行唯一约束。如果客户仅限于 1 家银行,那么您就有 1:M 关系。
    【解决方案3】:

    This answer 解释何时使用新表或新列。在您的情况下,IBAN 号码可以是 User 表的一个属性,但是其他列应该是 Bank 实体的一部分。这可以防止复制每个用户的银行信息(名称、位置)。所以表格可以是:

    用户(uid, name, lastname, bio, url_img, IBAN, bank_id)
    银行(id,bank_name,bank_location)

    【讨论】:

    • 也许我误解了我的情况,用户将使用表格自己输入信息(IBAN,location_delete 等...),而我不会提前输入可用的银行等...所以那里将是很少有共同点的数据。因为每个用户都会输入他们的银行详细信息,然后我将使用这些信息进行每月转账。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    • 2019-11-27
    • 2015-05-17
    • 2011-09-22
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多