【问题标题】:Database Design - Many to Many or One to Many "Deal" System?数据库设计——多对多还是一对多“交易”系统?
【发布时间】:2018-03-04 03:26:31
【问题描述】:

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

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

【问题讨论】:

  • 最简单的方法是在交易表中包含buyer_user_id 和seller_user_id 列,这也是一种有效的方法。数据库设计问题始终主要基于意见。
  • use text, not images/links, for text (including code, tables & ERDs)。使用图像仅是为了方便补充文本和/或无法在文本中给出的内容。如果您有代表,请使用编辑功能内联,而不是链接 - 使您的帖子独立。永远不要给出没有图例/键的图表。 (解释彩色线条。)
  • 请阅读How to Ask。提出一个设计并提出一个具体的问题。是时候阅读一本关于信息建模、关系模型和数据库设计的书了。
  • @philipxy 请帮我解决问题,否则不要在我的问题中发送垃圾邮件。谢谢。

标签: mysql database database-design relational-database


【解决方案1】:

嗯,这有点像 1:many 和 many:many。

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;

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

“交易”是一个实体,只是一个“用户”。但是,由于一笔交易只涉及一个买家、卖家和对象,因此对于 deal:person 和 deal:object,关系是 1:many。

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

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

  • 您可能希望 seller_idbuyer_id 链接到单个 Users 表。 (除非买家和卖家之间有足够的差异来证明不同的架构是合理的。)
  • 我提议的架构中的 3 个 id 代表 jpg 中的彩色线条。也就是说,您几乎完成了架构!
  • SMALLINT UNSIGNED(只有 2 个字节)允许 64K id。如果您认为这还不够,请选择更大的数据类型。
  • DECIMAL(8,2) 允许价格高达 999999.99 美元、欧元等;如果这不符合您的货币需求,请更改。
  • Deals 中不需要AUTO_INCREMENT PRIMARY KEY
  • 根据需要添加更多INDEXes

(已添加...)

如果 same 卖家/买家对可以出售/购买 same 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)。事情通常分为“实体”(交易、用户)和“关系”(ID,当 1:many 时;当 many:many 时是单独的映射表)。在您的情况下,多:多关系表本身就是一个实体。

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

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

我很少使用 FK 或触发器——我希望应用程序代码说明任何事务的所有步骤,包括原本会隐藏在 FK 和触发器中的副作用。

【讨论】:

  • 好答案,谢谢,但我有一个问题,我说我希望用户之间有多个交易,如果卖家 ID 和买家 ID 是 PRIMARY KEY,那么每个 col 不能有重复值,为什么要设置seller_id 和buyer_id 主键?
  • @HamidAdibzadeh - 我让卖家+买家+反对PK。如果买卖双方的每笔交易都涉及不同的对象,那么我的PK就OK了。如果“object_id”可以相同,那么您的担忧是有效的,需要进行更改。 (我会在一分钟内添加到我的答案中。)
【解决方案2】:

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

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

你应该添加:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-16
    • 2012-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    • 1970-01-01
    • 2011-05-01
    相关资源
    最近更新 更多