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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库设计 - 多对多或一对多“交易”系统?相关的知识,希望对你有一定的参考价值。

我有一个系统,用户可以互相“处理”,我想知道我应该使用什么样的关系。想到这样的系统。我们有一个数据库有两个表,一个“用户”和一个“交易”,“交易”表中的每一行都与两个“用户”行相关。因此,当创建交易时,一个用户是买方,一个用户是卖方。我该如何设计这个数据库?我的意思是表的逻辑应该是什么?一对一还是多对多?为什么?

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

答案

嗯,它有点像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_idbuyer_id成为单个Users表的链接。 (除非买家和卖家之间有足够的差异来证明不同的模式。)
  • 我提出的架构中的3个ID表示jpg中的彩色线条。也就是说,你几乎完成了架构!
  • SMALLINT UNSIGNED(只有2个字节)允许64K ID。如果您认为不够,请选择更大的数据类型。
  • DECIMAL(8,2)允许价格高达999999.99美元,欧元等;如果这不符合您的货币需求,请更改。
  • AUTO_INCREMENT PRIMARY KEY不需要Deals
  • 根据需要添加更多INDEXes

(添加...)

如果相同的卖家/买家对可以出售/购买相同的object_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(...)

在设计一组表时,我喜欢关注需要一起收集的内容(例如,“交易”的属性)。并确保处理关系(例如,seller_id)。通常情况属于“实体”(交易,用户)和“关系”(ids,当1:很多时;单独的映射表,当很多:很多时)。在你的情况下,很多:很多关系表本身就是一个实体。

我还想勾勒出SELECTs以查看表格是否方便地支持查询。

只有到最后,我才会想到FOREIGN KEYs。通常,INDEXes映射到FK。

我很少使用FK或触发器 - 我希望应用程序代码拼出任何事务的所有步骤,包括否则将隐藏在FK和触发器中的副作用。

另一答案

多对多关系不是一个选项,因为您需要保存额外的交易属性:价格,时间,对象。

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

你应该添加:

  • SELLER_ID和BUYER_ID字段到Deals表。
  • 从Deals表SELLER_ID字段到Users表主键的外键引用。
  • 从Deals表BUYER_ID字段到Users表主键的外键引用。

以上是关于数据库设计 - 多对多或一对多“交易”系统?的主要内容,如果未能解决你的问题,请参考以下文章

多对多、一对多或多对一

多对多或一对多 Django

在 PostgreSQL 中存储一对多或多对多关系的最佳方式是啥?

一对一、一对多、多对多,如何设计数据表?

数据库表设计(一对多,多对多)

数据库表设计(一对多,多对多)