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 / 问题 / 90137
Accepted
Louis Somers
Louis Somers
Asked: 2015-01-26 15:08:11 +0800 CST2015-01-26 15:08:11 +0800 CST 2015-01-26 15:08:11 +0800 CST

标准化共享实体和应用约束

  • 772

我正在寻找一种特定的“最佳实践”或“模式”,涉及在不同实体之间共享的实体,与其中一个实体有关系。

例如,一个人可能有通用实体“地址”,它可用于存储客户、供应商、员工等的公共地址字段......

经验丰富的 DBA 会采用这种方式还是愿意将字段添加到相应的实体中?我也在考虑可维护性,可能(在未来)因实体而异的约束,诸如此类。

我很想获得有关该主题的任何权威或已建立作品的参考。

database-design normalization
  • 2 2 个回答
  • 1071 Views

2 个回答

  • Voted
  1. Joel Brown
    2015-01-27T05:04:29+08:002015-01-27T05:04:29+08:00

    将各种地址堆积到一个表中的动机通常是对代码重用概念的误解和误用。

    人们可能会错误地假设,因为您有两个具有某些共同属性集的实体,所以这些属性属于它们自己的表。有时实体巧合地具有相似或相同的列。人们不会为数据库中的每个NAME或DESCRIPTION或创建一个表EFFECTIVE_DATE,至少我希望人们不会被诱惑这样做。

    有些人错误地将所有将列删除到他们自己的表中的实例称为规范化。规范化涉及将列删除到它们自己的表中,但并不是每个以这种方式删除列的实例实际上都是规范化。规范化规定了从表中删除列的非常具体的原因。如果这些原因都不适用,那么您就没有正常化,您只是让事情变得复杂。

    你有两种正确的思考方式:要么你的地址都属于一堆,因为你有一个实体超类型,它包含几个实体子类型的所有共同特征,包括地址, - 或者 - 你的地址属于不同的堆(表)根据每种具有地址的事物,您针对为每个地址表实现的 IAddress 接口编写程序代码。

    如果您实际上有一个实体超类型,比如LEGAL_ENTITY它有 、 等子类型CUSTOMER,VENDOR那么EMPLOYEE拥有一个ADDRESS子表LEGAL_ENTITY是一种合法的方法。如果您的客户、供应商、员工(或您正在跟踪的任何对象)之间存在显着重叠,这甚至可能是一种有价值的方法,因为您可以一次更改地址,而不是在法人搬迁时更改多个位置。另一方面,如果你没有这样的超级类型,那么你将面临理查德塔伦特指出的问题。

    如果根据拥有地址的实体类型将地址保存在不同的表中,那么假设您使用的语言支持接口,您仍然可以实现代码重用。

    顺便说一句:tvCa 在评论中指出地址可以存储为列而不是单独表中的行。这在很大程度上取决于每个实体需要多少个地址。如果您正在跟踪两个地址(物理地址、邮寄地址)或者如果您正在存储地址历史记录,那么请使用地址表。如果您只为每个收件人存储一个地址,那么一个单独的表可能有点矫枉过正。

    • 5
  2. Best Answer
    richardtallent
    2015-01-27T00:00:44+08:002015-01-27T00:00:44+08:00

    我不能指出任何权威性,但如果您仔细考虑这种实施的细节,潜在的缺点是显而易见的。

    拥有一个“共享”子表是有问题的,主要是因为如果两个“父”表(比如,Customer和Employee)都使用同一个Address表来存储地址,则不能使用外键约束来确保地址记录和相应的父记录。

    即使您放弃使用外键约束,在设置外键列时也会遇到一些难题。您基本上有三种选择,但都不是理想选择:

    1. AddressID在 Customer 和 Employee 表中放置一个字段。这里的问题是(1)你不能保证一个地址不会被多次使用,(2)如果AddressID是自动分配的,你不能将地址存储在客户/员工表中,直到地址已创建,这与您可能希望插入记录的方式相反(即,它创建Address了“父”表)。

    2. 在表中放置CustomerID和EmployeeID列Address。这里的问题包括 (1) 再次,您不能保证重复使用一个地址,(2) 它浪费空间,因为您在一列或另一列中存储 NULL,以及 (3) 它不能很好地扩展当您发现更多需要地址的实体时。

    3. 折叠 CustomerID/EmployeeID/等。分为单列ParentID和另一列,ParentTypeID以区别于Customers. Employees这比上面的 (2) 更好,但有其自身的问题,例如需要为ParentTypeID.

    我不会说这种方法在任何地方都不实用,但您必须考虑在多个表中拥有相似的列是否真的有那么大的问题,以及是否真的试图将它们移动到一个公用表为插入、更新、连接等增加的复杂性买任何东西。恕我直言,通常每个表最好在它们与其他表的关系方面有明确的约束,并且“父”表代表正在创建的核心业务对象(客户、员工等),而不是碰巧为其他几个表所共有的附属复杂类型。

    • 4

相关问题

  • 存储计算值或根据要求重新计算它们更好吗?[复制]

  • 存储与计算聚合值

  • 在数据仓库中实现多对多关系有哪些方法?

  • 高级规范化形式是否总是符合低级规范化形式的标准?

  • 标准化练习资源

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