抽象主键实现

时间:2011-02-08 06:07:59

标签: oop orm

所以我进入一个项目几个月,我意识到我选择的PK可能不适合版本2计划的增强。我还发现转向复合PK或代理PK将需要代码更改到几乎每个系统的一部分。

例如,我的DAL具有GetPerson(字符串PersonID)方法,需要使用其他类型的参数来运行。此外,大多数网页都采用嵌入了PK的查询字符串(即/ GetPerson?PersonID = BILL)

它让我想到我希望我实现了一些封装,我保护自己免受PK变化。具有从查询字符串放置和读取PK的抽象方法。同样,不是将本机类型传递给DAL,而是传递PersonPK对象并隐藏实现。

理论上我喜欢这个想法,我只是在实践中不确定,有可能阻止它成为“漏洞的抽象”。例如,一旦生成数据库调用,我必须打开PK对象。还有几十个要重写的陈述。

所以对我的问题....有没有人在他们的项目中成功使用PK抽象?它节省了你的时间吗?成功实施此项的关键是什么?

编辑: 一些回复告诉我,我对某些事情并不清楚。

我从未建议在数据库中创建一些抽象的主键列。我只是在考虑将业务逻辑和前端代码设计为能够抵抗PK重构的方式。

4 个答案:

答案 0 :(得分:2)

没有“PK抽象”这样的术语。

有自然主键,并且有代理主键。

您想要一个surrogate主键。咬紧牙关并做出改变,否则你将永远陷入一团糟。

答案 1 :(得分:2)

  

我希望我实施了一些   我保护自己的封装   来自PK的变化。

您正在寻找的封装是简单使用代理键。即:由数据库(不是最终用户)生成的标识符,用于唯一标识一行数据。它们通常是自动递增整数,有时是GUID。

我的经验法则:如果存储在数据库中的一条数据最有可能出现在最终用户面前(更不用说可用于编辑),那么不要将它用作主键!示例:电子邮件地址可以唯一标识系统中的用户。是的,它可以用作pkey但是!

  • 如果用户想要更改他/她的地址怎么办?您必须同时更新电子邮件地址为外键的每个表!
  • 考虑包含该主键的每个表上的索引膨胀!
  • 考虑比较两个字符串而不是两个整数在简单连接中链接两行的性能影响!

许多开发人员都会自动为数据库中的每个表创建一个代理键。这实际上是一种很好的做法,特别是如果代理键不会让你立刻觉得“自然”。

答案 2 :(得分:1)

我已经尝试了很多次,只是简单地把它全部丢掉,结束了我的努力。一旦我接受了严格使用单个列/属性的所有密钥,它不仅简化了代码并使其成为未来证明,在DB中引用这些记录也非常容易。有多个列/属性可将记录标识为唯一吗?好的,确定,保留这些,但仍然有一个唯一的列/属性为该行/对象。

例如:

拥有社交网络的用户 - 与用户和SocialNetworks对象的多对多关系。通常,您的数据库会有一个表达这些关系的查找表:

user_id | network_id

所以唯一性由user_id + network_id表示......但是,因此只需将其中的另一列打成唯一性:

user_network_id | user_id | network_id

在渲染SQL时,“解包”这些单列唯一标识符要容易得多。使用此方法引用内存中对象也更容易。

答案 3 :(得分:0)

一个。与OOP不同,数据库后端的正确设计不包括像PK这样的“抽象”概念。主键的正确定义是可靠数据库设计的核心。根据定义,PK是在他们所引用的表的范围内具体的。第一次没有让关系数据库设计的这个关键元素正确的痛苦就是你现在所经历的。

B中。关系数据库模型的前提是每个表中的信息是唯一的,并且可以通过其主键识别。有一些长期规则(“规范化”)已经形成了识别正确的PK并开发强大,可扩展的表结构的基础。

℃。正如Mitch Wheat在他的帖子中观察到的那样,PK的抽象是不可能的。

d。我强烈建议消化其他人在这个帖子中所说的内容,对主键和规范化进行一些研究,然后咬紧牙关。当您接近应用程序代码的版本3,4,5等时,您会很高兴。

最后一点 - 你会发现很多论据支持和反对使用自动递增PK“身份字段”vs“自然键”。就个人而言,我赞成自动递增ID - 这几乎不可能在将来发生变化。此外,我坚信使用对用户来说无用的PK。