代码之家  ›  专栏  ›  技术社区  ›  Hamid Adibzadeh

数据库设计-多对多或一对多“交易”系统?

  •  0
  • Hamid Adibzadeh  · 技术社区  · 7 年前

    我有一个用户可以相互“处理”的系统,我想知道我应该使用什么样的关系。 想象一下这样的系统。 我们有一个数据库,它有两个表,一个是“用户”,另一个是“交易” “deal”表中的每一行都与两个“user”行相关。 我应该如何设计这个数据库? 我是说表格的逻辑应该是什么? 一对一还是多对多?为什么呢?

    https://i.stack.imgur.com/so7iS.jpg

    2 回复  |  直到 7 年前
        1
  •  1
  •   Rick James diyism    7 年前

    嗯,有点像1:多和多:多。

    CREATE TABLE Deals (
        seller_id SMALLINT UNSIGNED NOT NULL,  -- link to `Users`
        buyer_id  SMALLINT UNSIGNED NOT NULL,  -- link to `Users`
        object_id SMALLINT UNSIGNED NOT NULL,  -- link to `Objects`
        price DECIMAL(8,2) NOT NULL,
        etc.,
        PRIMARY KEY(seller_id, buyer_id, object_id),
        INDEX(...)
    ) ENGINE=InnoDB;
    

    这允许两个“用户”之间进行多个对象销售,同一对象在其他人之间以其他价格销售,等等。

    “交易”是一个实体,只有“用户”才是。但是,由于一项交易只涉及一个买家、卖家和对象,因此交易:人和交易:对象的关系是1:多。

    另一方面 Deals 行为就像一个多:多关系表,在这个意义上,它将卖方和买方、卖方和对象等联系起来。

    有关架构的一些详细信息:

    • 你可能想要 seller_id buyer_id 链接到单个 Users 桌子(除非买方和卖方之间有足够的差异来证明不同的模式是合理的。)
    • 我提议的模式中的3个ID表示jpg中的彩色线。也就是说,您几乎完成了架构!
    • SMALLINT UNSIGNED (仅2个字节)允许64K ID。如果您认为这还不够,请选择一个更大的数据类型。
    • DECIMAL(8,2) 允许价格高达999999.99美元、欧元等。;如果这不符合您的货币需求,请更改。
    • 不需要 AUTO_INCREMENT PRIMARY KEY 在里面 交易 .
    • 添加更多 INDEXes 根据需要。

    (已添加…)

    如果 相同的 卖方/买方对可以出售/购买 相同的 object\u id,则PK(以上)将不起作用。(注意:PK必须是“唯一的”。)要解决此问题,您需要

    deal_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    PRIMARY KEY(deal_id),
    INDEX(seller_id, buyer_id, object_id),  -- in some order
    INDEX(...)
    

    卖方id ). 事物通常分为“实体”(交易、用户)和“关系”(ID,当1:many时;单独的映射表,当many:many时)。在您的例子中,多:多关系表本身就是一个实体。

    我还喜欢画出 SELECTs 查看表是否方便地支持查询。

    只有在最后,我才会考虑 FOREIGN KEYs . 一般来说 索引 映射到FKs。

    我很少使用FKs或触发器——我希望应用程序代码能够详细说明任何事务的所有步骤,包括FKs和触发器中隐藏的副作用。

        2
  •  0
  •   alexq    7 年前

    这里不能选择多对多关系,因为您需要保存其他交易属性:价格、时间、对象。

    因此,您可以在用户和交易之间使用2个一对多关系。

    • Deals表的SELLER\u ID和BUYER\u ID字段。
    • 从Deals表SELLER\u ID字段到Users表主键的外键引用。
    • 从Deals表BUYER\u ID字段到Users表主键的外键引用。