在开发购物车应用程序时,我发现需要根据管理员的偏好和要求保存设置和配置。这些信息可以是公司信息、运输账户ID、PayPal API密钥、通知偏好等任何内容。
在关系型数据库系统中创建一个表来存储单行数据似乎非常不合适。
那么,应该采用什么方法来存储这些信息呢?
注意:我的DBMS是SQL Server 2008,编程层使用ASP.NET(使用C#实现)。
在开发购物车应用程序时,我发现需要根据管理员的偏好和要求保存设置和配置。这些信息可以是公司信息、运输账户ID、PayPal API密钥、通知偏好等任何内容。
在关系型数据库系统中创建一个表来存储单行数据似乎非常不合适。
那么,应该采用什么方法来存储这些信息呢?
注意:我的DBMS是SQL Server 2008,编程层使用ASP.NET(使用C#实现)。
我过去有两种方法来处理这个问题 - 单行表格和键值对表格 - 每种方法都有其优缺点。
单行选项是最容易使用的选项。因为您可以将每个设置以其正确的类型存储在数据库中,而无需在代码中��储设置的类型以及其查找键。
使用此方法时,我担心的一件事是在“特殊”的单行设置表中有多个行。我通过以下方式(在SQL Server中)克服了这一点:
这意味着表格中只能存在一行,因为位列必须具有值0,但由于唯一约束,只能有一行具有该值。
你应该创建一个表格,其中包含信息类型和信息值(至少)。这样一来,每当添加新信息时,就可以避免创建新列。
一个单独的行就可以了,它甚至可以有强类型:
show_borders bit
admin_name varchar(50)
max_users int
其中一个缺点是需要进行模式更改(alter table
)才能添加新的设置。另一种替代方法是规范化,这将使你最终得到一个类似于以下表格的表:
pref_name varchar(50) primary key
pref_value varchar(50)
这里使用的是弱类型(所有内容都是varchar类型),但是只需要添加一行新设置,就可以通过数据库写入访问来实现。
就我个人而言,如果单行存储可行的话,我会选择这样做。把它存储在 SQL 表中可能有点浪费,但实际上这样做也没有什么大碍。
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...)
在规范化方法中添加新的配置参数时,您无需更改模式,但可能仍需更改代码以处理新值。
将“alter table”添加到部署中似乎并不像使用单行方法那样简单且类型安全,但这并不是一个很大的权衡。
键(key)和值(value)对类似于 .Net 的 App.Config,可以存储配置设置。
所以当您想要检索值时,可以执行以下操作:
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,
[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,则知道它是哪个首选项。
当您需要存储非管理员信息时,属性类型非常有用。
请注意,您不应以这种方式存储购物车数据,或者查找数据。但是,如果数据是系统特定的,则可以使用此方法。
例如:如果要存储您的DATABASE_VERSION,则可以使用此类表格。这样,当您需要升级应用程序时,可以检查属性表以查看客户端软件的版本。
关键是不要将其用于与购物车相关的事物。将业务逻辑保留在定义良好的关系表中。属性表仅用于系统信息。
1
是数字,而"1"
是字符串。 true
和false
都是布尔值。您还可以拥有对象。