【问题标题】:Database normalization question数据库规范化问题
【发布时间】:2011-11-04 01:47:04
【问题描述】:

我刚开始学习数据库规范化,我对我的一张表有疑问。我现在的数据库结构很糟糕,其中一个原因是因为我有一个看起来像这样的表。

客户表

ID |  Date_Entered   |  First_Name  |  Middle_Name |  Last_Name |    Maiden_Name 

...

Address__street_dmv | Address_city_dmv  | Address_state_dmv |   Address_zip_dmv

...

Address__street_source2  |  Address_state_source2  |  Address_city_source2  | etc

.

由于我的公司从多个来源获取地址数据,因此地址不断出现。但是,当然,其中一些地址对于我们的一些客户来说是空的。所以我想我需要一个像这样连接到客户表的单独地址表。

.

地址

ID  |   Number  |    Street    |  State  |   Zip  |    Source (drop down menu)

但后来我认为来源是冗余数据。那么,我需要这样一个单独的源表吗?

来源

Source_ID  |    Source

然后像这样更改地址表?

ID  |   Number    |  Street    |  State  |   Zip    |  Source _ID (drop down)

这似乎不对,因为现在 Source_ID 是多余的……请帮忙。

如果您能告诉我是否应该在 Customer 表中包含 Maiden 和 Middle 名,则可以加分,因为这些也可能为 Null(如果没有,新表的结构如何?)

对不起,我是菜鸟。

【问题讨论】:

  • 嘿,你在正确的轨道上,不要难过。我们随时为您提供帮助(尤其是措辞优美的此类具体问题)。虽然我认为,从我不断听到的关于 Access 的内容来看,有些人会推荐不同的数据库产品......(我自己从未使用过,所以不能说)。
  • 数据库规范化旨在使您的数据更可靠、更易于使用并且您的结构更易于理解。您绝对应该标准化您的数据以实现这三个目标。但是,很可能过度规范化数据库。如果为了可靠性而不需要为一条信息创建另一个表,并且只是在您的常见查询中强制另一个连接,那么不要这样做。未婚/中间名是可以将其留在主表中的情况之一。
  • 你需要复制一个像 Source_ID 这样的字段,这样你就可以连接两个不同表的记录。这是复制数据的例外,这就是关系数据库的工作方式。
  • @X-Zero - 当有人学习如何用手锯砍树时,不要推荐电锯,直到他们掌握基本知识。访问对于许多应用程序来说都很好。大多数被 Access 劝阻的人都没有使用改进的最新版本。
  • @X-Zero:每个数据库引擎都可以进行非规范化。没有特定于 Access 的东西会导致人们创建电子表格数据表——这通常是人们对数据库设计不够了解的情况。我已经看到了足够多可怕的网站数据库,知道这个问题绝不限于 Access 用户......

标签: sql database database-design ms-access ms-access-2007


【解决方案1】:

我不是 SQL 专家,但我认为您要描述的内容如下。

作为唯一实体的客户有一个当前地址,并且可以有许多其他地址,如果这是正确的,是的,您应该将其他地址分隔到他们自己的表中。

其次,您发现客户有 x 个地址的方式是您为每个客户获取不同公司的此信息,如果是这种情况,我将为公司提供一个单独的表格并按照您的计划记录,是的您将有重复的 source_id 行,但会出现这种情况,因为它们提供了许多不同客户的信息。

关于娘家姓和中间名,这些是您的业务规则所要求的,如果需要,请在需要时存储它们。

再一次,我的 SQL 开发实际上只是学生级别,但据我了解,这就是我将如何去做。

希望这会有所帮助,如果有人可以提供更多专家信息,请使用它。

【讨论】:

    【解决方案2】:

    我会选择类似的东西

    客户

    ID |  Date_Entered  |  First_Name  |  Middle_Name | Last_Name | Maiden_Name
    

    地址

    ID  |   Number  |    Street    |  State_ID  |   Zip
    

    客户地址

    ID | Customer_ID | Address_ID | Source_ID
    

    这允许您拥有来自多个来源的相同地址。您可能还希望有单独的街道表格,可能像

    Table_Street (ID | State_ID | Name)
    

    然后在Addresses 表中你将只有Street_ID 而不是Street 和State_ID。这还允许您在用户选择状态时显示街道选择列表。

    我认为在 Customer 表中可以使用 Maiden 和 Middle 名,即使它们很少使用。

    【讨论】:

    • 我支持你,尽管 OP 可能不需要多源/多客户地址优化(尽管可能是个好主意)。 Maiden_Name 可能是同一客户的不同名称(以前的名称,即不同的姓氏),具体取决于用例。
    【解决方案3】:

    您的问题部分与规范化有关,部分与规范化无关。这并不意味着您的部分问题不重要。它只是意味着它很重要,原因与规范化无关。

    从某种意义上说,您的地址本质上是一个重复的组。因此,将它们从客户中删除是有意义的。 (这与归一化有关;重复组违反 1NF。)

    “来源”不是冗余数据,决定是否用ID号代替文本与规范化无关。

    当您将表格从较低范式移动到较高范式时,原始表格的列数会减少。用 ID 号代替文本不会改变列数。

    您用无意义的 ID 号替换文本的每一列都需要一个连接来获取有意义的文本。按照您的相同逻辑,您还可以用无意义的 ID 号替换街道、州和邮政编码,但这需要四个连接才能返回有意义的数据。

    【讨论】:

    • 感谢 Catcall,这确实很有意义。
    【解决方案4】:

    您也可以尝试以下方法:

    客户

    客户 ID (PK) |日期_输入 |名字 |中间名 |姓氏 | Maiden_Name

    地址

    客户 ID (PK)(FK) |源ID(PK) |号码 |街道 |州|邮编

    这假定客户和地址之间存在一对多的关系。它还完全消除了 Customer_Address 表,支持使用两个表(Customer 和 Addresses),并将 Addresses 表的复合主键定义为 CustomerId 和 SourceID。在此模型中,CustomerId 和 SourceId 唯一确定 Number、Street、State 和 Zip。它还通过确保每个客户只能从每个来源获得一个地址来强制数据完整性。让我知道这是否有帮助,或者我是否偏离了基地。我还在学习!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-03
      • 2011-02-06
      • 1970-01-01
      • 2012-07-30
      • 2012-10-08
      相关资源
      最近更新 更多