我正在升级我刚才创建的支付管理系统。它目前有一个表可以接受每种付款方式。它仅限于能够支付一件事,这个升级是为了缓解。我一直在询问我应该如何设计它的建议,我有这些基本的想法:
我的目标是:不要过于缓慢,尽可能自我记录,并在保持其他目标的同时最大限度地提高灵活性。
由于每个表中的重复列,我不太喜欢1。它反映了继承基类的支付类型类,该基类为所有支付类型提供功能...... ORM反向?
我最倾向于2,因为它就像当前设计的“类型安全”和自我记录一样。但是,与1一样,要添加新的付款方式,我需要添加一个新表。
我不喜欢3因为它的“浪费的空间”,并且不能立即清楚哪些列用于哪种支付类型。文档可以减轻这种痛苦,但我公司的内部工具没有一种有效的方法来存储/查找技术文档。
我给出的4个论点是,它可以减少在添加新的付款方式时需要更改数据库的情况,但是由于缺乏明确性,它会比3更糟。目前,更改数据库不是问题,但如果我们决定开始让客户保留自己的数据库,它可能会成为一个后勤噩梦。
所以,我当然有偏见。有没有人有更好的想法?您认为哪种设计最合适?我应该根据什么标准做出决定?
答案 0 :(得分:29)
答案 1 :(得分:9)
也许你应该看this question
Bill Karwin接受的答案涉及通常称为实体属性值(EVA)的键/值表的特定参数
..虽然很多人似乎都很青睐 EAV,我没有。这似乎是最多的 灵活的解决方案,因此 最好。但是,请记住这句格言 TANSTAAFL。这是一些 EAV的缺点:
- 无法强制列(相当于
NOT NULL
)。- 无法使用SQL数据类型来验证条目。
- 无法确保属性名称拼写一致。
- 无法将外键放在任何给定属性的值上,例如 查找表。
- 在传统的表格布局中获取结果非常复杂 昂贵,因为要获得属性 从你需要做的多行 每个属性
JOIN
。EAV给出的灵活程度 你需要在其他方面做出牺牲 区域,可能使您的代码成为 比它复杂(或更糟) 一直在解决原来的问题 一种更传统的方式。
在大多数情况下,这是不必要的 具有这种程度的灵活性。 在OP关于产品的问题上 类型,创建一个更简单 每种产品类型的表格 产品特定的属性,所以你 有一些一致的结构 至少强制执行的条目 相同的产品类型。
我只有在每一行必须时才使用EAV 被允许可能有一个 不同的属性集。当你 有一组有限的产品类型, EAV太过分了。班级表 继承将是我的第一选择。
答案 2 :(得分:2)
我的第一原则是不要无缘无故地重新设计。因此,我会选择选项1,因为这是您当前的设计,并且具有良好的工作记录。
改为在新功能上花费重新设计时间。
答案 3 :(得分:2)
如果我从头开始设计,我会选择第二名。它为您提供所需的灵活性。然而,第1号已经到位并正在工作,而这对于整个应用程序来说相当重要,我可能会警惕做出重大的设计更改而不知道究竟是什么查询,存储过程,视图,UDF,报告,导入等你必须改变。如果这是我可以用相对较低的风险做的事情(以及适当的测试结果)。我可能会改变解决方案2,否则你可能会引入新的更糟糕的错误。
在任何情况下我都不会使用EAV表来做这样的事情。它们对于查询和性能而言非常糟糕,并且灵活性被高估了(询问用户是否希望能够每年添加3-4次新类型,而不会以日常性能为代价更改程序)。
答案 4 :(得分:0)
乍一看,我会选择2(或3):如果可能,请概括。
我认为选项4不是很关系,会让你的查询变得复杂。
当遇到这些问题时,我通常会用“用例”来面对这些选项:
- 当这个或这个操作时,设计2/3会如何表现?