关于EF 一个实体创建多张表问题

zaaserz 2020-03-04 02:18:07
目前项目遇到一个问题,我想将相同结构的表按照不同的类别建立多张表,用Ef如何实现?

例如:一个气象设备,可以采集“温度”“湿度”等多个要素,在数据库内对应了一个设备表,一个 要素表(这个主要记录要素的一些描述),一个要素历史数据表(记录数据),设备与要素一对多的关系,要素与要素历史表一对多的关系。这种情况的话所有要素的历史数据都会被存储在一个表中。我现在的想法是为每一个要素都建立一个历史表(历史表的机构是一样的,时间,值,备注 三个字段)。
我这么考虑是因为数据量问题,要素采集一分钟一条数,一天就是1440条,那如果有两个设备一个设备有10个要素一年就是1千多万条数据。而且如果分开放历史数据的话查询某个要素的历史信息时可以只查看某张表就好。

这个问题使用sql语句可以正常解决,但现在我使用的时EF框架,就想问下能否通过Ef实现这个问题。
...全文
1010 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
luj_1768 2020-03-07
  • 打赏
  • 举报
回复
这种情况,通常可以先针对每个设备建立一个数据表,作为原始数据记录;同一要素对应不同设备的,可以建立一个要素数据表,把不同设备数据作为不同的列,作为数据对比参考表。另外,你对数据库的基本概念理解好像有点问题:设备和要素都是表头(列),数据是对着表头一行行填充上去的。
圣殿骑士18 2020-03-06
  • 打赏
  • 举报
回复
引用 20 楼 正怒月神 的回复:
其实,拆分存储,就是数据库分库分表的实际业务需求。
我们有一个项目,需要把图片二进制保存入数据库。
大家别问我为什么不用url,老板强制要求,我也没办法。
这就导致一条数据的某个img字段,可能有80M
这样的数据来10条。就会明显感觉到很慢了。
因此我们就需要分库分表。

老板是老程序员吧,老观念。
正怒月神 2020-03-06
  • 打赏
  • 举报
回复
引用 26 楼 jhonsonzhang 的回复:
[quote=引用 20 楼 正怒月神 的回复:] 其实,拆分存储,就是数据库分库分表的实际业务需求。 我们有一个项目,需要把图片二进制保存入数据库。 大家别问我为什么不用url,老板强制要求,我也没办法。 这就导致一条数据的某个img字段,可能有80M 这样的数据来10条。就会明显感觉到很慢了。 因此我们就需要分库分表。
那你们也不用拆分数据库和数据表啊,这等同于分页单独建数据表,更不用说,还要重建数据库了。这能比直接用linq语句筛选数据更快?比如我们处理分页,如果出现分页后某些页的数据访问会卡,难道我们会去找数据库的原因,而不是修改和测试分页的方法代码?[/quote] 怎么说呢,数据量大了,分库分表是很正常的。 只是楼主类似于这里先拆分好了。 这并没什么不可取的。 其实现在分布式蛮多的,阿里的用户表存储可能达到16个,每个用户登录,会根据用户的编号取模,确定去不同的库抓取用户信息。 这显然也是同一个逻辑。因为一个表存储所有数据,只适合中小型的数据量,并且一行数据的kb不多的情况。
jhonsonzhang 2020-03-06
  • 打赏
  • 举报
回复
引用 20 楼 正怒月神 的回复:
其实,拆分存储,就是数据库分库分表的实际业务需求。 我们有一个项目,需要把图片二进制保存入数据库。 大家别问我为什么不用url,老板强制要求,我也没办法。 这就导致一条数据的某个img字段,可能有80M 这样的数据来10条。就会明显感觉到很慢了。 因此我们就需要分库分表。
那你们也不用拆分数据库和数据表啊,这等同于分页单独建数据表,更不用说,还要重建数据库了。这能比直接用linq语句筛选数据更快?比如我们处理分页,如果出现分页后某些页的数据访问会卡,难道我们会去找数据库的原因,而不是修改和测试分页的方法代码?
正怒月神 2020-03-06
  • 打赏
  • 举报
回复
引用 23 楼 zaaserz 的回复:
[quote=引用 21 楼 正怒月神 的回复:] 其实我感觉,还是使用 dbcontext.database.sqlquery<> 解决最合适。 这是一个泛型方法,你只需要在<>中输入你要的Model类型就好了。 sql查询出来,会自动映射到Model
是的,目前我使用的方法就是这个,使用sql语句动态创建表,然后通过database.sqlquery<history>(sql语句)的形式进行查询。其余的表是通过dbset<>的形式让ef自动创建。现在就是不知道ef是否支持我的想法。[/quote] 没问题的, 只要你查询出的history字段名字一样就可以了。 哪怕不一样,你也可以通过 sql 字段 as history属性 来解决
zaaserz 2020-03-06
  • 打赏
  • 举报
回复
引用 22 楼 jhonsonzhang 的回复:
对的,确实不应该放N张表。比如分页。有N页的数据,难道去建N张数据表反而效率更高?所以不应该纠结这个。简单的事情弄复杂了。
其实我感觉历史数据是否放一张表,这是个仁者见仁智者见智的问题,我只是考虑到想要把历史数据根据要素的类型进行分类,这样在数据量特别大的情况下查询也好点。(不要提议数据库优化,本人所在公司比较小没有数据库优化人员本人也不会
zaaserz 2020-03-06
  • 打赏
  • 举报
回复
引用 21 楼 正怒月神 的回复:
其实我感觉,还是使用 dbcontext.database.sqlquery<> 解决最合适。 这是一个泛型方法,你只需要在<>中输入你要的Model类型就好了。 sql查询出来,会自动映射到Model
是的,目前我使用的方法就是这个,使用sql语句动态创建表,然后通过database.sqlquery<history>(sql语句)的形式进行查询。其余的表是通过dbset<>的形式让ef自动创建。现在就是不知道ef是否支持我的想法。
jhonsonzhang 2020-03-06
  • 打赏
  • 举报
回复
对的,确实不应该放N张表。比如分页。有N页的数据,难道去建N张数据表反而效率更高?所以不应该纠结这个。简单的事情弄复杂了。
正怒月神 2020-03-06
  • 打赏
  • 举报
回复
其实我感觉,还是使用 dbcontext.database.sqlquery<> 解决最合适。 这是一个泛型方法,你只需要在<>中输入你要的Model类型就好了。 sql查询出来,会自动映射到Model
正怒月神 2020-03-06
  • 打赏
  • 举报
回复
其实,拆分存储,就是数据库分库分表的实际业务需求。 我们有一个项目,需要把图片二进制保存入数据库。 大家别问我为什么不用url,老板强制要求,我也没办法。 这就导致一条数据的某个img字段,可能有80M 这样的数据来10条。就会明显感觉到很慢了。 因此我们就需要分库分表。
正怒月神 2020-03-06
  • 打赏
  • 举报
回复
引用 18 楼 jhonsonzhang 的回复:
我觉得还是应该所有历史数据都应该放1张表里面,应为实体的属性都一样啊。那以前数据库设计的基础er图设计时候,属性完全一样就是该一张表啊。为什么要分开呢。应该还是我最初想法正确些,新建历史类实体,linq语句得到相应数据。
理论上应该要分开的。 查询效率会高很多。 而且日志分析也清晰明了。 假设有10个日志表,每个100w记录。 那我从100W里查,肯定比1个表1000W里查要快。 而且定位问题也要准。
jhonsonzhang 2020-03-06
  • 打赏
  • 举报
回复
我觉得还是应该所有历史数据都应该放1张表里面,应为实体的属性都一样啊。那以前数据库设计的基础er图设计时候,属性完全一样就是该一张表啊。为什么要分开呢。应该还是我最初想法正确些,新建历史类实体,linq语句得到相应数据。
jhonsonzhang 2020-03-06
  • 打赏
  • 举报
回复
仔细想了下,其实您这初始想法很对的,确实是我没明白您的意思。现在明白了,其实您是想看EF里面能否动态创建子类并相应保存的机制。这个我还没使用过,但我想是肯定行的。我有空帮您看下文档,顺便自己也学习下。但您那用SQL去创建肯定不妥,我那json保存也是笨办法。
jhonsonzhang 2020-03-06
  • 打赏
  • 举报
回复
所有历史数据就是应该放一张表里面,你放1张表跟放N张表没什么不同。在ef里面这个几千万的linq查询,区别不大。按您的思路,创建几百万个历史表反而效率更高?你还不如创建json文本流放数据库里面。xml流也可以。
zaaserz 2020-03-06
  • 打赏
  • 举报
回复
引用 13 楼 jhonsonzhang 的回复:
不知是不是我没有理解到,还是您思路上有些问题,您这儿跑到SQL里面去创建一个空表,是干嘛呢?有这个必要吗。直接再写个类,HistroyByTag。public dbset<historyByTag> Historyes。下面您需要什么时候用,直接用linq语句获取相应的historys就可以了。sql语句到数据库里面去重新读取,还创建临时表,不太可取。 另外项目最终是硬件终端通过物联传到数据库的文本,您在编写时候要考虑解析的类。
可能我上面说的不太清楚,其实我要问的就是你说的使用HistroyByTag类如何在数据库中建立多张表,我知道 dbset<historyByTag> Histroryes 这个方法,这个只会在数据库中建立一张历史表,通过tag.Id与tag表相联系,但是我现在不想将所有要素的历史数据放到一张表内,因为如果有20个要素,一个要素1天1440条数据那一年就是一千多万条,这到后期数据量太大,也不利于单独查询。我想通过Tag的数量,更改tag的内部属性(TableName)动态建立历史表,这些历史表将每个tag的历史分开存放。也就是说有10个tag就有10张历史表,有20个tag就有20个历史表。我不知道如何使用ef实现,所以我只能使用sql语句根据传入的TableName动态创建表。
geek1104 2020-03-06
  • 打赏
  • 举报
回复
建立多个对象继承一下
zaaserz 2020-03-06
  • 打赏
  • 举报
回复
引用 34 楼 dd861202416 的回复:
引用 29 楼 dd861202416 的回复:
用codefirst可以实现
百度一下code first 一对多就有了,定义一个公用聚合根对象,然后用对象继承他,各个对象里实现一下一对多的关系就行了。
但是当实体相同时Ef会只为其建立一张表,并不会建立多张表吧?我们现在讨论的是将这个历史表如何分为多个,就像一个设备有多个要素,一个要素有多个历史记录;使用ef建立的话数据库内只会有1张设备表,1张要素表,1张历史记录表。
geek1104 2020-03-06
  • 打赏
  • 举报
回复
引用 29 楼 dd861202416 的回复:
用codefirst可以实现
百度一下code first 一对多就有了,定义一个公用聚合根对象,然后用对象继承他,各个对象里实现一下一对多的关系就行了。
zaaserz 2020-03-06
  • 打赏
  • 举报
回复
针对这个问题我决定不去纠结如何Ef啦,我决定使用sql语句去进行操作,至于32楼说的dapper听过没有用过,我会去了解下。多谢各位热情的讨论,分不多就平分吧
圣殿骑士18 2020-03-06
  • 打赏
  • 举报
回复
其实针对这个需求,没看出ef的任何优点了,推荐dapper。
加载更多回复(17)

110,567

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧