AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 131116
Accepted
ratherBeKiting
ratherBeKiting
Asked: 2016-03-03 23:25:19 +0800 CST2016-03-03 23:25:19 +0800 CST 2016-03-03 23:25:19 +0800 CST

MySQL中多态关联的最佳实践

  • 772

我有一个 MySQL 数据库,其中包含 3 个包含主要数据类的表:

 companies (company_id)
 persons (person_id, company_id) 
 loans (loan_id, company_id) 

“贷款”和“人”都属于公司。公司可以有贷款,公司可以有人员(如董事、员工等)

在几种情况下,其他数据可能属于公司、个人或贷款,例如“笔记”。例如,用户可以添加特定于公司、个人或贷款的“注释”。

还有其他示例,例如“地址”和“电话号码”,它们可以属于公司或个人。

我显然希望有一个数据表,例如“笔记”、“地址”和“电话号码”,但是我正在努力寻找将这些数据与公司、人员和贷款联系起来的最佳方式。

让我们在这里使用“笔记”作为示例。

更好的做法是:

1/ Have 3 extra tables linking 'notes' to companies people and loans:

notes(note_id)
persons_notes(person_id, note_id)
companies_notes(company_id, note_id)
loans_notes (loan_id, note_id)

2/ Have a single table 'entities' which has a primary key entity_id used to link all 3 tables:

entities(entity_id)
persons(person_id, entity_id)
companies(company_id, entity_id)
loans (loan_id, entity_id)
notes (note_id, entity_id)

后者在逻辑上是有道理的,但感觉不对,因为个人和公司是与贷款完全不同的一类数据。不知怎的,感觉很脏。

备注和地址将与贷款、个人和公司建立一对多的关系。也就是说,一家公司可能有很多地址或备注。这就是我考虑链接表的原因。

一家公司可以有一个注册地址和无限的交易地址。一个人可以有一个当前地址和以前的地址(如果当前地址少于 3 年)。

在这种情况下,拥有贷款(商业贷款)的是公司。人属于公司,通常是公司的董事。所以,一家公司可以有很多人和很多贷款。

  • 一个公司/个人/贷款每人可以有很多笔记
  • 一个公司/个人可以有多个地址
mysql inheritance
  • 2 2 个回答
  • 10003 Views

2 个回答

  • Voted
  1. Best Answer
    Vérace
    2016-03-04T21:17:43+08:002016-03-04T21:17:43+08:00

    这个问题(以各种形式)经常出现在这个论坛上。

    它被称为 EAV(实体属性值)。有充分的理由,它被称为反模式。有很多理由不使用这种形式的数据模型。它们在此处、此处和此处进行了概述(+ 中的链接请查看同一线程中其他发帖人的回复)。

    并非所有人都同意 EAV 总是一件坏事,只是在大多数情况下。Aaron Bertrand(这个小组的大人物)就此事写了这篇文章。然而,我的建议是坚持传统的设计,并且(可能)让自己的生活更轻松。

    为什么不像你描述的那样只有三个主表

    • 人
    • 公司
    • 贷款

    和两个“附属”表

    • 地址
    • 笔记

    那么 Person、Company 和 Loan 可以有 Address_id 和 Note_id 字段。不需要复杂的链接表(至少现在还不需要:-))。或者首先,您甚至可以在主表中包含注释和地址(如果曾经有一个地址和一个注释 (BLOB) 字段)?

    无论您做什么,在您成为经验丰富的数据建模师之前,请避免使用 EAV。ps 欢迎来到论坛!

    [编辑]

    您能告诉我们您使用的是哪个 RDBMS 吗?可能对我的回复有些影响。这里的版主不喜欢长时间的乒乓式聊天。

    我“拼凑”了一个图表和脚本,可以帮助您入门。

    任何进一步的问题/问题,让我知道。大部分应用程序设计和数据建模都是反复试验——你生成一个数据模型,开始对它进行编程,你会发现你最初的想法无法发挥作用的各种方式。这就是原型设计的目的。给它一个bash,然后解决问题。

    在此处输入图像描述

    以及该图表中的脚本。

    CREATE TABLE IF NOT EXISTS `mydb`.`Person` (
      `Person_id` INT NOT NULL AUTO_INCREMENT,
      `Name` VARCHAR(45) NOT NULL,
      `Employed_by` INT NULL,
      PRIMARY KEY (`Person_id`))
    ENGINE = InnoDB;
    
    CREATE TABLE IF NOT EXISTS `mydb`.`Loan` (
      `Loan_id` INT NOT NULL AUTO_INCREMENT,
      `Amount` DECIMAL NOT NULL,
      `Other_fields` VARCHAR(45) NULL,
      PRIMARY KEY (`Loan_id`))
    ENGINE = InnoDB;
    
    
    
    
    
    CREATE TABLE IF NOT EXISTS `mydb`.`Person_loan` (
      `Person_id` INT NOT NULL,
      `Loan_id` INT NOT NULL,
      INDEX (`Person_id` ASC),
      INDEX (`Loan_id` ASC),
      INDEX (`Person_id` ASC, `Loan_id` ASC),
      CONSTRAINT `Person_Loan_P_FK`
        FOREIGN KEY (`Person_id`)
        REFERENCES `mydb`.`Person` (`Person_id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `Person_Loan_L_FK`
        FOREIGN KEY (`Loan_id`)
        REFERENCES `mydb`.`Loan` (`Loan_id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB;
    
    
    
    
    CREATE TABLE IF NOT EXISTS `mydb`.`Company` (
      `Company_id` INT NOT NULL AUTO_INCREMENT,
      `Company_name` VARCHAR(45) NULL,
      PRIMARY KEY (`Company_id`))
    ENGINE = InnoDB;
    
    
    
    
    
    CREATE TABLE IF NOT EXISTS `mydb`.`Works_for` (
      `Person_id` INT NULL,
      `Company_id` INT NULL,
      INDEX `Works_For_P_FK_idx` (`Person_id` ASC),
      INDEX `Works_For_C_FK_idx` (`Company_id` ASC),
      CONSTRAINT `Works_For_P_FK`
        FOREIGN KEY (`Person_id`)
        REFERENCES `mydb`.`Person` (`Person_id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `Works_For_C_FK`
        FOREIGN KEY (`Company_id`)
        REFERENCES `mydb`.`Company` (`Company_id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB;
    
    
    
    
    CREATE TABLE IF NOT EXISTS `mydb`.`Company_loan` (
      `Company_id` INT NOT NULL,
      `Loan_id` INT NOT NULL,
      INDEX `Company_loan_C_L_PK` (`Company_id` ASC, `Loan_id` ASC),
      INDEX `Company_Loan_L_FK_idx` (`Loan_id` ASC),
      CONSTRAINT `Company_Loan_C_FK`
        FOREIGN KEY (`Company_id`)
        REFERENCES `mydb`.`Company` (`Company_id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `Company_Loan_L_FK`
        FOREIGN KEY (`Loan_id`)
        REFERENCES `mydb`.`Loan` (`Loan_id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB;
    
    • 8
  2. Archimedes Trajano
    2022-08-30T14:25:07+08:002022-08-30T14:25:07+08:00

    我通常做的是通过将分层数据结构存储在以简单键为键的 CLOB 中并添加审计字段和乐观锁定版本来避免该问题。

    每个表都是一个“模式”。

    从技术上讲,您也可以使用文件来执行此操作,但是您必须处理备份两件事。

    但是,我确实在数据库中保留了查询和关系数据,但我没有限制自己遍历多个表并加入它们(使用像 Hibernate 这样的对象关系映射器更容易),我使用R DBMS 作为其主要强度关系映射。

    如果我在“数据”表中添加一条新记录,会发生什么情况,我会在要查询的关系表和查找表中构建相应的条目。

    它的好处是,如果您能够处理备份两组事物,您可以将数据作为单独的文件,让您的数据库只有关系/查找数据。这是 Mail.app 在 mac 和 WinAmp 中完成的方法。

    您也不会被困在您的结构中,因为您可以根据需要使用文件进行重建。

    • 0

相关问题

  • 是否有任何 MySQL 基准测试工具?[关闭]

  • 我在哪里可以找到mysql慢日志?

  • 如何优化大型数据库的 mysqldump?

  • 什么时候是使用 MariaDB 而不是 MySQL 的合适时机,为什么?

  • 组如何跟踪数据库架构更改?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve