允许用户即时向其数据库添加列的最佳方式是啥? [关闭]
Posted
技术标签:
【中文标题】允许用户即时向其数据库添加列的最佳方式是啥? [关闭]【英文标题】:What is the best way to allow a user to add columns to their database on-the-fly? [closed]允许用户即时向其数据库添加列的最佳方式是什么? [关闭] 【发布时间】:2011-01-27 22:37:16 【问题描述】:我们正在考虑设计一个用于管理联系信息的应用程序。
客户的请求之一是允许他们的高级用户或管理员类型的员工通过 UI 向数据库添加列。客户无法直接访问数据库(即,他们无法使用 SSMS 打开数据库并进行更改)。
我看到了 1) 输入字段名称和 2) 输入数据类型以及 3) 选择要添加字段的表的控件。一旦用户单击一个按钮,数据库就会更新为新字段。我需要检查适当的权限、字段是否已经存在等等。我们还需要将表单字段连接到这个新字段,例如报表设计器界面。
-
我在哪里可以找到显示我想要做什么的示例?
这样做有什么缺点?除了对开发人员来说似乎需要做大量工作之外。
您会建议这样做吗?如果不是,有什么更好的解决方案?
编辑 - 我们需要使用 SQL Server。没有商量余地。
【问题讨论】:
您是否被锁定在使用sql server
?也许像mongodb
这样的无模式数据库更适合您的问题。
这样做的最佳方式? 不是!
【参考方案1】:
他们向表中添加列是绝对要求,还是他们能够指定要存储的其他字段?我强烈建议您考虑类似 Entity-Attribute-Value 之类的东西,而不是允许最终用户(管理员算作最终用户)进行架构更改。
对于这样的事情,您将有一个表来定义您的自定义字段,然后是一个多对多关联表,以允许用户为联系人的自定义字段指定一个值。例如:
Contact
---------
-> ContactId
| FirstName
| LastName
| etc.
|
| ContactField
| --------------
| ContactFieldId <---
| FieldName |
| |
| ContactFieldValue |
| ------------------- |
-- ContactId |
ContactFieldId -------------------------
Value
实现的细节显然取决于您(例如,是否使用ContactId + ContactFieldId
作为ContactFieldValue
中的复合主键),但这应该让您大致了解。
【讨论】:
+1:非常非常很少是允许用户创建新列的最佳解决方案。【参考方案2】:我会强烈反对这个要求,让他们知道这是一个多么糟糕的主意。是的,您可以为这些添加一个 EAV 表,但是您会遇到查询它的问题,这既不简单也不高效。或者,您可以按照@Jerry Coffin 的建议使用带有半打备用列的表格,但他会导致报告困难以及当他们全部使用它们时会发生什么。所有这些都导致开发人员进行大量额外工作来支持可能不会导致每年进行 3 次数据库更改的需求。您冒着数据完整性、数据库性能和报告准确性的风险(我敢打赌,这些新字段不会有 PK/FK 关系或默认值,甚至不会是正确的数据类型,因此日期是 varchars,因此数据将被添加到会费日期是 ASAP 的数据库,这对报告不起作用)等等,所以一些不知道自己在做什么的人可以假装进行无效且经过深思熟虑的数据库更改。
我使用过许多允许这样做的 COTS 产品,但当人们实际添加列时,结果总是不好(幸运的是,实际上很少有人有足够的勇气这样做)。他们不会在需要的地方填写表格,不会自动添加到报告中,通常无法搜索,而且在每种情况下,他们最终花费更多的钱来找人修复他们造成的数据混乱。让专业人员进行设计更改是有成本的。
大多数时候,我看到这样的需求是因为高级管理人员认为灵活性很酷,而不是任何高级用户实际需要甚至想要这样做。他们需要了解他们所要求的成本。
多花几天时间与高级用户讨论他们需要什么并从正确开始设计,这比走这条路要好得多。
这是真正需要长时间认真讨论的要求之一,不仅要花费多少开发时间,还要花费数据完整性、性能和可维护性,而几乎没有任何收益。我会做一个正式的成本效益分析,向他们展示这个想法到底有多糟糕。然后,一旦他们完全了解他们所要求的完全愚蠢,如果他们仍然想要它,请继续建造它并开始寻找新工作,因为您不想成为必须维持的人这。
【讨论】:
【参考方案3】:解决方法参考此链接:C# Dynamically Add Columns to table in Database
老实说,我认为让用户控制添加列可能不是最好的做法,因为它很容易被滥用。并且用户可能在技术上不了解数据库结构。以及表之间的多对多关系会发生什么。
希望这会有所帮助。
【讨论】:
【参考方案4】:处理这种情况的简单方法是预先定义半打(或其他)“备用”列,并有一个额外的表,该表从您给列的名称映射到您的名称向用户展示。如果它为空(例如),则不会在表单上显示该字段,但如果它不为空,则显示具有该给定名称的字段。通过这种方式,他们可以自定义,但无需更改表格本身(这在大表格中可能相当很慢)。
【讨论】:
【参考方案5】:尝试查看 Web 数据管理员 (http://sqlwebadmin.codeplex.com/)。它与 phpMyAdmin 类似(在概念上),但用于 MSSQL。
【讨论】:
【参考方案6】:一方面,您必须确保用户不超过最大记录大小。不确定 2008 如何响应会导致行超过行最大字节数的 DDL。 http://msdn.microsoft.com/en-us/library/ms143432.aspx -- 如果你也不知道,可以测试一下。
我不会推荐这个。但如果我要这样做,我会让 UI 具有交互性和低调性:
What kind of field do you want to add?
Date-time
number without a decimal point
number with a decimal point
little text note
large text note
image
yes/no
etc etc
【讨论】:
【参考方案7】:有趣的提议 - 让他们对数据库进行更改,但不允许他们使用为此目的而设计的工具?
我建议给他们两种数据类型,一个 nvarchar 最大长度和一个数字(如果可以的话,整数,如果他们需要的话,小数),然后看看他们能走多远。
但是,如果您尝试设置过多的约束,我希望您将有一个永无止境的过程,即在不伤害自己或他人的情况下弄清楚什么足以完成他们的工作。 (太多了。他们会伤害自己。:) 即使是专业人士也会伤害自己。)
【讨论】:
以上是关于允许用户即时向其数据库添加列的最佳方式是啥? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
React Native Maps:实现可拖动标记的最佳方式是啥?