我目前正在使用C#开发一个软件,并希望它将数据存储在数据库中。我的问题是我正在寻找存储包含两个数组的对象数据的最佳方法。数组中的对象看起来完全相同,但它们有不同的含义。
作为信息:数据中对象的数据正在定期更改。
例如,我得到以下两个classe:
public class ObjectA
{
public string Text { get; set; }
public int Value { get; set; }
}
public class ObjectB
{
public string Text { get; set; }
public int Value { get; set; }
}
public class ObjectC
{
public string Name { get; set; }
public List<ObjectA> DetailsA { get; set; }
public List<ObjectB> DetailsB { get; set; }
}
请注意,我目前从ObjectC获得了超过24000个对象。这些对象的每个数组包含的对象数量可能会有很大差异(最多200个,将来可能更多)。如果我使用其中一个解决方案,这会导致最大行数的问题吗?
我对数据库shema的外观有两个看法:
一个表中的所有属性。
为ObjectA
和ObjectB
的每个属性创建一个coloumn,以便我可以将数组中的每个对象存储在一行中。
CREATE TABLE `data` (
`data_id` INT NOT NULL,
`name_a` NVARCHAR(50) NOT NULL,
`text_a` NVARCHAR(100) NOT NULL,
`name_b` NVARCHAR(50) NOT NULL,
`text_b` NVARCHAR(100) NOT NULL,
`value` INT NOT NULL,
PRIMARY KEY (`data_id`)
)
在这种情况下,我会冗余地存储name
的值。
在ObjectA的表中创建外键
通过这样做,我可以避免在查询数据时必须使用连接时冗余地存储来自ObjectC
的数据。
CREATE TABLE `data` (
`data_id` INT NOT NULL AUTO_INCREMENT,
`name` NVARCHAR(50) NOT NULL,
PRIMARY KEY (`data_id`)
)
CREATE TABLE `details_a` (
`a_id` INT NOT NULL AUTO_INCREMENT,
`text` NVARCHAR(100) NOT NULL,
`value` INT NOT NULL,
`data_fk` INT NOT NULL,
PRIMARY KEY (`a_id`)
)
CREATE TABLE `details_b` (
`b_id` INT NOT NULL AUTO_INCREMENT,
`text` NVARCHAR(100) NOT NULL,
`value` INT NOT NULL,
`data_fk` INT NOT NULL,
PRIMARY KEY (`b_id`)
)
另外,每次数组数据发生变化时,最好在数据库中创建一个新行,还是应该更改现有数据呢?
编辑:添加了一些有关对象数量的信息(在c#示例的正下方)。
答案 0 :(得分:2)
(从评论转到回答,太长了)
方法1不适用于As或Bs btw的列表 - 至少你需要第二个版本的fks。
使用连接很好,数据库规范化也很好。它对您的数据进行分区,并允许数据库更好地优化查询。
作为第三种方法,您可以使用descriminator-column并将A和B存储在同一个dbtable中 - 鉴别器会告诉您它是A还是B.
CREATE TABLE `details_ab` (
`a_id` INT NOT NULL AUTO_INCREMENT,
`text` NVARCHAR(100) NOT NULL,
`value` INT NOT NULL,
'isA' BIT NOT NULL, -- True == A else B
`data_fk` INT NOT NULL,
PRIMARY KEY (`a_id`)
)
正常/懒惰的方法是使用/配置orm映射器为您执行此操作,以便您可以将数据库视为C#对象并让详细信息由orm映射器处理(google EntityFramework,Hibernate,代码优先, data-first,fe here:msdn.microsoft.com/en-us/library/jj200620(v=vs.113).aspx)。
至于插入或更新 - 取决于。如果你必须(合法地为fe或保险)必须在你的数据库中拥有完整的数据系列,你可以使用一个表,并且只插入 - 并且顶部有一个视图,它覆盖了数据项目的“最新”版本。 / p>
即。每一行都有一个ID,你有一个“BusinessID”,它为你唯一标记“一个对象” - 你第一次插入它,然后你修改它:这将插入一个新的DB-Id和相同的“BusinessID”。您在表上创建一个仅显示每个BusinessID的最高DB-ID的视图(假设整数DB-Ids)。您在表中拥有完整的历史记录,但您的应用程序“通常”只能看到视图,但管理员可能可以访问整个表而不是视图...等等。
答案 1 :(得分:0)
使用外键创建表结构可能是最好的解决方案,它将是最常用的。也就是说,我知道需求会根据使用情况而有所不同,所以这是一种可能的选择。
根据用途和大小,我发现在DB中将对象和变量存储为XML序列化等价物会很有帮助。如果您只需要持久存储,那么这是最简单的方法,然后您可以使用包含时间戳和XML对象的简单表来保存版本控制。在紧要关头,您甚至可以使用SQL查询XML对象以访问数据,或者在以后需要更改时迁移存储方法。我使用这种方法在单个表中存储具有不同数据类型的字典样式数据,以便快速访问环境变量。