我接管了一个项目,该项目的用户表包含超过30列。糟糕的是,列的更改和添加不断发生。
这不对。
我是否应该将额外字段作为值移入第二个表并创建存储这些列名的第三个表?
user
id
email
user_field
id
name
user_value
id
user_field_id
user_id
value
答案 0 :(得分:9)
不去键/值路线。 SQL不是为处理它而设计的,它会让你的数据库中的实际数据成为一种自我折磨的练习。 (示例:索引不能正常工作。当您必须加入以获取您正在加入的数据时,联接会很有趣。继续。)
只要将数据标准化到合适的级别,就不会有太多列。
编辑:要清楚,有一些问题只能通过键/值路由解决。 “太多列”不是其中之一。
答案 1 :(得分:4)
很难说有多少太多了。这真的很主观。我认为你应该问的问题不是“有太多列?”,而是“这些列是否属于这里?”我的意思是,如果您的User表中的列不一定是用户的属性,那么它们可能不属于。例如,如果你有一堆列总结了用户的地址,那么也许你可以把它们带到一个带有FK的地址表进入用户。
如果可能的话,我会避免使用键/值表。这似乎是一种简单易用的方法,但从长远来看,这真的只是一种痛苦。如果您发现您的架构发生了非常一致的变化,您可能需要考虑采用某种变更控制来审核只有那些必要的更改,或者转移到另一种更好地支持无架构存储的技术,如NoSQL with MongoDB或CouchDB的。
答案 2 :(得分:2)
这通常被称为EAV,这是否适合您的数据库取决于很多因素:
http://en.wikipedia.org/wiki/Entity-attribute-value_model
http://karwin.blogspot.com/2009/05/eav-fail.html
http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back
太多列并不是其中之一。
答案 3 :(得分:2)
如果表格中的更改和添加意味着它们准确反映了业务需求的变化,那么对表格进行更改和添加并不是一件坏事。
答案 4 :(得分:1)
如果变化和附加是连续的,那么您可能需要坐下来更好地定义需求。现在我不能说30列是否是因为它取决于它们的宽度以及它是否应该移动到相关的表格。如果你有像phone1,phone2,phone 3这样的字段,那么你需要将其分成一个相关的user_phone表。或者,如果您的所有列都很宽(并且您的整个表宽度比数据库存储数据的页面宽)并且某些列不是您的查询经常需要的,那么它们在具有一对一的相关表中可能会更好一个关系。除非你有实际的性能问题,否则我可能不会这样做。
然而,在所有可能的选择中,您所描述的EAV模型在维护性和性能方面都是最差的。针对这个模型编写体面的查询非常困难。
答案 5 :(得分:0)
这个真的取决于你想要做什么。