在SQL Server数据库中使用单行配置表。坏主意?

在SQL Server数据库中使用单行配置表。坏主意?,sql,database-design,configuration,relational-database,Sql,Database Design,Configuration,Relational Database,在开发购物车应用程序时,我发现我需要根据管理员的首选项和要求保存设置和配置。这些信息可以是公司信息、发货帐户ID、PayPal API密钥、通知首选项等 在关系数据库系统中创建一个表来存储单行似乎非常不合适 存储此信息的适当方式是什么 注意:我的DBMS是SQL Server 2008,编程层是用ASP.NET(C#)实现的。我不确定一行是配置的最佳实现。每个配置项有一行和两列(configName、configValue)可能会更好,尽管这需要将所有值转换为字符串并返回 无论如何,在全局配置中

在开发购物车应用程序时,我发现我需要根据管理员的首选项和要求保存设置和配置。这些信息可以是公司信息、发货帐户ID、PayPal API密钥、通知首选项等

在关系数据库系统中创建一个表来存储单行似乎非常不合适

存储此信息的适当方式是什么


注意:我的DBMS是SQL Server 2008,编程层是用ASP.NET(C#)实现的。

我不确定一行是配置的最佳实现。每个配置项有一行和两列(configName、configValue)可能会更好,尽管这需要将所有值转换为字符串并返回


无论如何,在全局配置中使用一行并没有什么害处。将其存储在DB(全局变量)中的其他选项更差。您可以通过插入第一个配置行来控制它,然后禁用表上的插入以防止多行。

您应该创建一个表,其中包含一列信息类型和信息值(至少)。这样可以避免每次添加新信息时都必须创建新列。

就我个人而言,如果这样做有效,我会将其存储在一行中。将其存储在SQL表中是否有过多的技巧?可能吧,但这样做并没有真正的危害。

实现这一点的常用方法是将“属性”表模拟到属性文件中。在这里,你可以存储你所有的应用程序常量,或者不是你需要的常量

然后,您可以根据需要从该表中获取信息。同样,当您发现有其他设置要保存时,可以将其添加到中。以下是一个例子:

属性项表

[id, scope, refId, propertyName, propertyValue, propertyType] 
1, 0, 1, "COMPANY_INFO", "Acme Tools", "ADMIN"  
2, 0, 1, "SHIPPING_ID", "12333484", "ADMIN"  
3, 0, 1, "PAYPAL_KEY", "2143123412341", "ADMIN"   
4, 0, 1, "PAYPAL_KEY", "123412341234123", "ADMIN"  
5, 0, 1, "NOTIF_PREF", "ON", "ADMIN"  
6, 0, 2, "NOTIF_PREF", "OFF", "ADMIN"   
通过这种方式,您可以存储您现有的数据,以及您明年将拥有但还不知道的数据:)

在本例中,您的作用域和refId可以用于后端的任何内容。所以,如果propertyType“ADMIN”的作用域为0 refId 2,您就知道它是什么首选项

当有一天,您还需要在此处存储非管理员信息时,属性类型就会出现

请注意,您不应以这种方式存储购物车数据,也不应为此进行查找。但是,如果数据是特定于系统的,那么您当然可以使用此方法

例如:如果要存储数据库的版本,可以使用如下表。这样,当您需要升级应用程序时,您可以查看属性表以查看客户端的软件版本


关键是,您不想将其用于与购物车相关的东西。将业务逻辑保存在定义良好的关系表中。属性表仅用于系统信息。

正如您所猜测的,除了最简单的情况外,将所有配置参数放在一行中有许多缺点。这是个坏主意

存储配置和/或用户首选项类型信息的方便方法是XML。许多DBMS支持XML数据类型。XML语法允许您随着配置的发展扩展描述配置的“语言”和结构。XML的一个优点是它对层次结构的隐式支持,例如,允许存储配置参数的小列表,而不必使用数字后缀命名这些参数。XML格式的一个可能缺点是,搜索和通常修改这些数据不像其他方法那样直接(没有什么复杂的,但没有那么简单/自然)

如果您希望保持更接近关系模型,则可能需要的是,其中各个值存储在一个表中,该表通常如下所示:

EntityId     (foreign key to the "owner" of this attribute)
AttributeId  (foreign key to the "metadata" table where the attribute is defined)
StringValue  (it is often convenient to have different columns of different types
IntValue      allowing to store the various attributes in a format that befits 
              them)
其中,AttributeId是表的外键,表中定义了每个可能的属性(“配置参数”)

AttributeId  (Primary Key)
Name
AttributeType     (some code  S = string, I = Int etc.)
Required          (some boolean indicating that this is required)
Some_other_fields   (for example to define in which order these attributes get displayed etc...)
最后,EntityId允许您识别“拥有”这些不同属性的某个实体。在您的情况下,如果您只有一个配置需要管理,那么它可能是一个用户ID,甚至是隐式的


除了允许可能的配置参数列表随着应用程序的发展而增长外,EAV模型还将“元数据”(即与属性本身相关的数据)放在数据表中,因此,避免了将配置参数存储在一行中时常见的列名硬编码。

一行就可以了;它甚至会有强大的类型:

show_borders    bit
admin_name      varchar(50)
max_users       int
一个缺点是,它需要模式更改(
altertable
)来添加新设置。另一种方法是规范化,最终得到如下表:

pref_name       varchar(50) primary key
pref_value      varchar(50) 

它的类型很弱(一切都是varchar),但添加新设置只是添加一行,这可以通过数据库写访问来完成。

我过去用过两种方法—单行表和键/值对表—每种方法都有积极和消极的一面

单行
  • 正:值以正确的类型存储
  • 正面:更容易在代码中处理(由于上述原因)
  • 正:可以分别为每个设置提供默认值
  • 否定:需要更改架构才能添加新设置
  • 否定:如果有很多设置,表格会变得很宽
键/值对
  • 正面:添加新设置不需要更改架构
  • 正面:表架构很窄,额外的行用于新设置
  • 否定:每个设置都有相同的默认值(空/空?)
  • 否定:所有内容都必须存储为字符串(即nvarchar)
  • 否定:在处理代码中的设置时,您必须知道设置的类型并强制转换它
  • SELECT value FROM configurationTable WHERE ApplicationGroup = 'myappgroup' AND keyDescription = 'myKey';
    id, column_num, property_name, intValue, floatValue, charValue, dateValue
    1, 1, weeks, 51, , ,
    2, 2, pi, , 3.14159, , 
    3, 4, FiscYearEnd, , , , 1/31/2015
    4, 3, CompanyName, , , ACME,