重构数据库应该使用代理键吗?

时间:2013-03-20 00:02:48

标签: database refactoring relational-database

我继承了一个Access数据库,我正在迁移到SQL Server。在数据库中有很多标签或分类栏。例如,订单表可以具有状态属性,供应商可以具有评级属性。大多数人没有真正的业务逻辑,他们本身不是实体,他们都只是允许用户标记和搜索的描述符。

一方面,我认为这些描述符应放在自己的表中,并使用外键引用。然后在我的应用程序代码中,我可以使用与代理ID匹配的枚举。为什么?因为我可以轻松添加它们,所以可以轻松更改值,也许可以节省一些空间。

Order { OrderId int, CustomerId int, StatusId int}
Status { StatusId int, Name varchar(50)} 

另一方面,因为其中许多属性永远不会改变,所以永远不会被添加,我还有很多其他的东西要做,我想我应该放弃它。

Order{OrderId int, CustomerId int, Status varchar(50)}

第一个选项是否应该始终如一?第二种选择是否可以接受?我认为离开它的唯一缺点是表格会稍大一些,字符串比较可能没有int比较那么快。

1 个答案:

答案 0 :(得分:0)

如果您需要更多地控制在“Status”列中找到的值,您还可以将Order.Status中的不同值插入另一个表中,并设置对它的外键引用。按照你描述表格的方式。 。

Order{OrderId int, CustomerId int, Status varchar(50)}
Status {Name varchar(50)} 

但是,我会为该列选择比“名称”更具描述性的内容。级联更新或删除是否取决于应用程序。当您使用SQL Server时,可以控制允许谁使用SQL GRANT和REVOKE语句更新“状态”表。 (你也可以用Access做到这一点,但你似乎正在远离它。)

要从此表中获取有意义的数据,需要两个连接而不是三个。考虑一下你是否需要50个字符。 (访问默认为50.大多数人永远不会改变它。)

现在,要回答您的问题,上面的第一个选项不是总是完成的方式。 ID号总是会增加所需的连接数,并且您仍然需要对自然键使用UNIQUE约束。使用ID号码来表示美国州代码,邮政编码等等是没有任何意义的。第二种选择对我来说通常是不可接受的;我通常引用另一个带有外键的表,就像我在这个答案的顶部所做的那样。

相关问题