【问题标题】:How to create generic column in database table?如何在数据库表中创建通用列?
【发布时间】:2012-10-09 12:47:11
【问题描述】:

我有一个表,其中包含大量非常具体的列,这些列大多是“字符串”。我相信这种硬编码的名字会在以后规则改变时让我感到悲伤。我正在研究使用第二个表的选项,其中每一行都是主表中的一列,每个表的名称都有一个查找键。

我知道这可能看起来违反 ER 最佳实践,但它会很灵活。我可以使用带有子选择的视图,即从 Table1 中选择 (SQL1)、(SQL2) 等。不确定是否可以在 SQLServer 中更新多表视图。

非常感谢以上的想法。

谢谢,

埃德

【问题讨论】:

    标签: sql-server sql-server-2008 entity-framework


    【解决方案1】:

    听起来你正在寻找类似Entity-Attribute-Value (EAV) table. 的东西

    EAV 在允许进一步定制方面具有灵活性时允许更加动态的过程,但实施不佳可能意味着它不能很好地遵守关系模型。 This SO question 很好地概括了这种解决方案固有的一些问题。

    您最好重构列以使用较少上下文特定的命名约定。

    【讨论】:

    • 这很有趣。我的问题域是关于为包含多个部分的报告收集属性数据,这些部分具有一些共同属性,而其他部分则不然。理想情况下,数据模型应该支持单独的“报告域”。这种设计的另一面可能是应用层变得更加复杂,或者我可能过度担心。我的应用程序技术将是 ASP.NET MVC 3。我将阅读此模式。
    • “你最好重构你的列以使用较少上下文特定的命名约定。”我明白你的意思,但我会失去专栏的意义。我可以有 C1、C2、C3,但我想我需要将 C1、C2、C3 对这种记录类型的含义存储在某个地方。
    • "我需要将 C1、C2、C3 对这种记录类型的含义存储在某个地方。"确切地! SQL 的关键在于数据库存储有关特定实体(客户、产品)以及这些实体之间的关系(当客户购买产品时)的信息。当我说“特定于上下文”时,我的意思是你最好不要使用与外部标准相关的名称——你想为你的表和列使用通用名称,这些名称对该列中的数据具有意义。如果您的数据过于多样化,请进行非规范化并记住您不能始终考虑所有内容。
    • 刚刚查看了 EAV。看起来确实会产生问题,因为一个人正在有效地对抗 RDBMS 的设计目的,也就是说,如果一个人使用的是 SQL Server 而不是 SimpleDB。
    • 关于“C1,C2”评论,我认为可以有一个“C1,.....C20”,根据上下文的需要使用多个,然后有一个metatable 持有 C1....Cn 的意思。所以 C1...Cn 只是用于记录的数据罐。
    【解决方案2】:

    您可以将列存储为类型SQL_VARIANT
    这不是世界上最好的做法,但您可以使用它。

    create table t  (anything sql_variant);
    insert t values (current_timestamp);
    insert t values (current_timestamp+1);
    insert t values (1);
    insert t values ('some text');
    insert t values (current_timestamp-3);
    insert t values (null);
    insert t values (2.1234);
    insert t values (cast(2 as decimal(10,5)));
    insert t values ('some more text');
    
    -- sample based on type
    select *
      from t
     where CAST(sql_variant_property(anything, 'BaseType') as varchar(20)) like '%char';
    

    根据您的问题,您将存储存储在另一列或链接表列中的类型。

    【讨论】:

    • 谢谢。我从来不知道 SQL_VARIANT 数据类型。感觉好像我用这个打破了所有规则!
    【解决方案3】:

    避免使用inner platform effect。 SQL Server 已经让您能够查询表中的哪些列。请参阅sys.tablessys.columns

    使用这些查询您拥有哪些列,并使用标准 DDL 命令根据需要添加和删除列。不要害怕规范化、连接等。

    当您需要做一些在正常设计中微不足道的事情时,“数据库中的数据库”几乎总是会导致失败。

    【讨论】:

    • 感谢您的及时回复。我向您指出“内部平台效应”,但是我无法理解 sys.tables 的使用如何消除了指定非常具体的列名的需要。我可能有点慢...:)
    猜你喜欢
    • 1970-01-01
    • 2014-03-23
    • 2017-06-06
    • 2022-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    相关资源
    最近更新 更多