我在一个新的小项目中面临这个问题:要建立的系统将允许用户添加新的列到系统中的表中,然后用户将能够维护数据,我认为有两种方法来实现这一点: 1)创建几个表,包括“列”表与"columnName“"columnValue”“数据类型”等来存储列定义,另一个表"XXCoumn“来存储列的值(由用户输入),并使用一个存储过程来查询/更新列数据。2)当用户输入新的列时,在表模式中创建列,这样表数据的维护就正常了
你们认为是哪种方式?或者有什么新的建议?
一些附加信息:数据量很小,我需要创建报告。
发布于 2009-02-27 01:30:39
任何好的建议都需要更好地理解你的需求,但这里有一些关于你提到的选项的评论,以及一些额外的想法。
1) 实体-属性-值(EAV)设计:这是您描述的选项,其中您有一个表,其中包含ColumnName、类型和值的列。此选项的优点是能够轻松容纳无限的新列,但我发现当需要检索有意义的数据时,这是非常痛苦的。例如,假设您在此EAV表中有{Color,varchar}{Red,Green,Blue}和{Size,varchar}{Small,Medium,Large}的行。如果你想找到所有的绿色小东西,你需要类似这样的东西(当然是未经测试的SQL ):
SELECT *
FROM ITEMS
WHERE ITEMID IN (SELECT ITEMID
FROM ITEM_ATTRIBUTES ATT INNER JOIN ITEM_VALUES VLS
ON ATT.AttributeID = VLS.AttributeID
WHERE ATT.ColumnName = 'Color' AND VLS.Value = 'Green')
AND ITEMID IN (SELECT ITEMID
FROM ITEM_ATTRIBUTES ATT INNER JOIN ITEM_VALUES VLS
ON ATT.AttributeID = VLS.AttributeID
WHERE ATT.ColumnName = 'Size' AND VLS.Value = 'Small')将其与items表上的实际列的颜色和大小进行对比:
SELECT *
FROM ITEMS
WHERE COLOR = 'Green' AND SIZE = 'Small'此外,如果这对这个应用程序很重要,你将很难维护数据完整性(而且几乎总是重要的,即使你被告知不是这样的)。在上面的示例中,如果"Color“应该限制为Blue、Green和Red,则需要实现额外的逻辑。此外,如果某些颜色只有特定的尺寸(例如,蓝色仅在中小型产品中可用),您将需要实现更多的逻辑。
2) user -Defined Columns:只允许用户向表中添加额外的列的优点是使数据检索更简单,但所有数据完整性问题仍然存在。此外,您的应用程序通常需要额外的逻辑来处理未知的列。
3) 预先存在的自定义列:我使用过一些应用程序,比如CRM,它们为用户定义提供了十几个甚至更多的列。基本上,设计者将"Text1“、"Text2”、"Text3“、"Number1”、"Number2“等列放入列中,然后用户为这些列提供标题和描述信息,这就是应用程序用于显示的目的。此模型具有易于数据检索的优势,以及预定义的DB模式,这应该简化应用程序逻辑。然而,数据完整性问题仍然存在。另一个明显的缺点是,您将耗尽预定义的列,而这正是您在使用这种类型的解决方案时通常试图避免的。
与大多数设计问题一样,每个解决方案都有权衡之处。我的经验是,虽然许多用户/客户说他们想要这样的解决方案,但实际上他们只是想确保自己不会被一个无法满足自己需求的应用程序所困。我发现,实际上很少有地方需要这样的设计。我几乎总是可以创建一个满足客户端扩展需求的设计,而不需要让他们扮演数据库设计师的角色。
发布于 2009-02-27 00:42:34
“要构建的系统将允许用户向系统中的表中添加新列...”
真的吗?这就是用户故事吗?对我来说,听起来你已经对解决方案下定决心了。
允许用户扩展模式是不是一个好主意,这完全取决于上下文。在管理员式的、有限的使用方式下,我会遇到一些小问题。但是用MySpace类型的方式来说,这是一个非常糟糕的想法。我怀疑你的情况介于这两个极端之间。
扩展模式将导致更高效的查询-因为您可以添加索引等-但它确实向您的用户公开了一些关系规则。此外,扩展将(可能)锁定整个表,并且需要处理并发编辑。
发布于 2009-02-27 00:30:00
如果这是由您集中托管的,我建议不要允许用户输入的数据更改数据库的模式(即驱动新表的创建)。
相反,您可能希望研究在SQL中使用XML字段来存储数据的变量字段名,或者更通用的表结构...如果我们谈论的不是疯狂的数据量,这种技术非常有效……
https://stackoverflow.com/questions/593088
复制相似问题