这是一个好的数据库设计概念吗?

时间:2008-11-26 07:52:44

标签: database-design normalization

EDIT1:尝试通过重命名表格及其关系来解决问题。 编辑2:请不要查看我在三个数据库表中保存的数据类型。它们是在飞行中组成的。它们不是我真实世界的场景(不,我不能谈论我的真实世界数据......实际上它是1个父母和6个孩子,目前)。请忽略哪种类型的数据,只看一些数据是必需的。 EDIT3:两个FK是0或1比1的关系。不是0到很多。不是1比1.我试图避免0或1比1关系到1比1的关系,所以我不需要有OUTER JOINS而是有INNER JOIN。

问题:我需要知道建议的数据库设计是好/坏/跛足等等。

问题:今天我尝试制作索引视图,但失败了因为我的表有外连接。叹。所以我想知道我是否可以将其重新设置为以下设计:

  • 三张桌子。
  • table_User在table_Address上有一个FK
  • table_User在table_Vehicle上有一个FK
  • 等。

和表B和C(现在像查找表一样)具有..

  • Id INT IDENTITY PK
  • 说明NVARCHAR(100) NULLABLE

注意到可空?这样,table_Address中的某些内容在table_Address中不存在...该字段为空(因为内连接)。

之前,我做了一个LEFT OUTER JOIN,所以如果table_b中没有数据,我将得到空值是每个字段的结果。

我会在这里提出一些数据示例......

Table_User

  • ID:1,名称:Fred,地址ID:1(空)
  • ID:2,姓名:Joe,地址ID:2(史密斯街1号)
  • ID:3,姓名:Jane,地址ID:2(史密斯街1号)

Table_Address

  • ID:1,描述= NULL
  • ID:2,Description = 1 smith street

那么我终于可以把这一切都放到索引视图中了。 (我的现实生活场景大约有8张桌子。)

注意:数据库是Microsoft Sql Server 2008,但这可能适用于任何数据库。

Q1:那个设计看起来好吗?

Q2:所以我在这里做的是我正在对数据进行规范化,对吧?通过保持内部连接在一起。

问题3:最后,如果这是一个好的方法..我还可以确保表中的数据是唯一的(例如街道地址),有一些独特的约束或键或索引或什么(我'我不确定正确的术语。)

感谢大师!

4 个答案:

答案 0 :(得分:5)

我发现你的问题令人困惑,但也许我可以帮助一点。

首先,表没有连接,查询有。您不创建具有到另一个表的连接的表。只有两个表可能相关,您可以使用连接查询这些表。

我建议你阅读有关db规范化的内容。维基百科有一篇很棒的文章:http://en.wikipedia.org/wiki/Database_normalization

关于你目前的情况,我不确定你想做什么。如果该地址在不同的行中重复,那么拥有地址的ID似乎没问题。但是,需要几个“地址表”似乎很奇怪。设计时要记住的最重要的事情是: - 在每个表中都有一个正确的主键,因此您可以正确地连接表。 - 除非你有充分的理由,否则不要重复数据。 但我再次推荐上一篇文章。

希望有所帮助! :)

答案 1 :(得分:1)

一个非常令人困惑的问题,请查看数据库的规范化。第三种常规形式(希望它被称为英语中的那种形式)可以解决大多数问题。

快速提示:如果您有重复的数据,那么您需要一个单独的表,您可以通过外键在第一个表中引用该表。其他一切都只是查询。

答案 2 :(得分:0)

所以你基本上是在表B和C中添加虚假记录,以便拥有与A中相同的行数?如果我是你,我不会这样做,因为如果你的数据集很大,那么你就是在没有任何实际需要的情况下增加行数而且你也存在不一致的风险(你的布局很大程度上取决于你的能力)插入这些虚假记录)。除此之外,您希望通过索引视图实现什么?性能提升?您没有编写您正在使用的DBMS,但根据我在MSSQL中的经验,这不会给您带来很多好处,因为如果您在表A,B和C中有适当的索引,服务器将能够使用即使没有索引视图,它们也可以构建一个好的查询计划。

答案 3 :(得分:0)

我个人对这个设计说'不'。原因:

  • (可能不适用)尝试保持地址字段规范化意味着您需要处理此字段以确保避免意外重复。即你必须确保用户以正确的格式输入地址(否则'1 mystreet'也可以输入为'1,mystreet'或其他任何东西 - 需要检查这一点以避免重复,否则标准化是没有用的)
  • 即使你找到了归一化的理由(即保留单独的地址表),“虚拟”地址的概念对我来说也很奇怪。为什么不使用可空的FK关系,即在父用户表中存储NULL地址ID,而不是仅仅在其中放置一个虚拟ID。