在数据库中存储Dictionary <int,string>或KeyValuePair </int,string>

时间:2014-11-14 03:24:02

标签: c# sql-server linq oop

我想看看其他人在使用List&lt;&gt;等类型时遇到的情况或字典&lt;&gt;并反过来存储和检索该数据?

以下是一个示例场景:用户将创建自己的“模板”,其中这些模板本质上是Dictionary的集合,例如对于user1,值为(1,Account),(2,Bank),(3,Code),(4,Savings),对于user2,值(不相关)可以是(1,Name),(2,Grade) ,(3,类),等等。这些模板/列表的长度可能不同,但它们始终具有索引和值。此外,每个列表/模板都只有一个用户链接到它。

您在数据库方面选择了哪些类型?

我应该注意的痛点和/或建议?

2 个答案:

答案 0 :(得分:1)

列表或任何集合在数据库中的表示应该是表格。始终将其视为一个集合,并将其与数据库提供的内容联系起来。

虽然你总是可以序列化一个集合,但我不建议更新或插入记录,你总是更新整个记录或数据,而有一个表,你只需要查询 KEY 其中字典,你已经拥有它。

答案 1 :(得分:1)

就集合中的类型而言,.Net类型和SQL类型之间存在相当一对一的映射:SQL Server Data Type Mappings。您最需要担心字符串字段:

  • 它们总是ASCII值(0 - 255)吗?然后使用VARCHAR。如果它们可能包含非ASCII / UCS-2字符,则使用NVARCHAR
  • 他们可能的最大长度是多少?

当然,有时您可能希望在数据库中使用稍微不同的数字类型。主要原因是如果在应用程序端选择int,因为它更容易&#34; (或者我被告知)处理比Int16byte,但值永远不会超过32,767或255,那么你应该最有可能使用SMALLINT或{{1 }} 分别。应用层内存方面TINYINTint之间的差异可能很小,但它确实会对物理存储产生影响,尤其是在行数增加时。如果不清楚,&#34;影响&#34;意味着减慢查询速度,有时需要购买更多SAN空间时需要花费更多资金。但是,我说&#34; 最有可能使用byteSMALLINT&#34;是因为如果你有Enterprise Edition并且启用了行压缩或页面压缩,那么这些值将存储在它们适合的最小数据类型中。

就从数据库中检索数据而言,这只是一个简单的TINYINT

至于存储这些数据(至少在高效率方面),嗯,这更有趣:)。将字段列表传输到SQL Server的一种好方法是使用表值参数(TVP)。这些是在SQL Server 2008中引入的。我在这个答案中发布了一个代码示例(C#和T-SQL),其中有一个非常相似的问题:Pass Dictionary<string,int> to Stored Procedure T-SQL。关于该问题还有另一个TVP示例(接受的答案),但它不使用SELECT,而是使用IEnumerable<SqlDataRecord>,这是该集合的不必要副本。

修改 关于最近更新的指定实际数据持久化的问题,应将其存储在类似于以下的表中:

DataTable

PRIMARY KEY应该是(UserID,TemplateIndex),因为它是一个独特的组合。 IDENTITY字段不需要(至少没有给定的信息)。

UserID INT NOT NULL, TemplateIndex INT NOT NULL, TemplateValue VARCHAR(100) NOT NULL TemplateIndex字段将在TVP中传递,如我在上面链接的问题的答案中所示。 TemplateValue将作为第二个UserID自行发送。在存储过程中,您将执行类似于:

的操作
SqlParameter

只是要明确说明,除非有非常特定的理由这样做(这需要包括永远,不需要在任何查询中使用这些数据,这样这个数据实际上只是一个文档,在查询中不再比PDF或图像更有用,那么你就不应该将它序列化为任何格式。虽然如果你倾向于这样做,XML是比JSON更好的选择,至少对于SQL Server来说,因为内置支持在SQL Server中与XML数据交互,但对JSON没有那么多。