我在SQL中有一个表格,其中包含来自iFix SCADA系统的报警数据,其设计如下:
CREATE TABLE [dbo].[FIXALARMS](
[ALM_ID] [int] IDENTITY(1,1) NOT NULL,
[ALM_NATIVETIMEIN] [datetime] NOT NULL,
[ALM_PHYSLNODE] [char](8) NOT NULL,
[ALM_TAGNAME] [varchar](32) NOT NULL,
[ALM_VALUE] [varchar](16) NOT NULL,
[ALM_MSGTYPE] [varchar](8) NOT NULL,
[ALM_DESCR] [varchar](128) NOT NULL,
[ALM_ALMSTATUS] [varchar](4) NOT NULL,
[ALM_ALMPRIORITY] [varchar](8) NOT NULL,
[ALM_ALMAREA] [varchar](32) NOT NULL,
)
SCADA指定列必须命名的内容和数据类型,并且不提供将数据拆分为多个表的其他选项。差不多,我将被迫以这种格式接收信息并且它变得很痛苦,因为我的很多查询都在使用多个类似的和字符串比较真正应该被id的数据。
现在,我想规范化这个表并将其拆分为多个具有键控关系的表,这样我就可以节省数据库空间,查询性能并增加一些灵活性。
使用数据库触发器最好能实现这一目标吗?数据库的增长速度约为40Mb /天(约300k行),而我缺乏SQL经验使我担心在添加条目时会给服务器增加额外的负载。相反,我应该使用代理来不时地清理表格吗?我可能不知道的其他一些选择是什么?
答案 0 :(得分:1)
触发器会增加一些处理开销,并可能引入争用和事务锁。如果没有针对最新完成的数据执行复杂查询,那么您可以通过定期调度的ETL过程来提取数据并将其转换为更可用的形式。 您可以根据需要安排ETL每天或每隔几小时运行一次。
答案 1 :(得分:1)
假设你使用触发器,很可能会将传入的数据分成多个表,对吧? 这是一种可行的方法。 如果传入数据与该表的架构匹配,则执行“常规”触发器。如果传入的数据模式与您的模式不完全匹配,请考虑使用INSTEAD OF触发器。
在任何情况下,在触发器中,您必须在某些INSERT期间生成密钥并在其他INSERT中重新使用它们。一些好的做法是让你的触发器业务逻辑免费 - 只做RDBMS的事情。还要仔细考虑如何生成和读回密钥 - 注意范围污染。最后,考虑您的事务隔离级别,并尽可能快地控制吞吐量。
答案 2 :(得分:1)
如果您不需要数据实时,请使用SSIS设置ETl流程以将数据转换为规范化形式。
如果您必须实时拥有数据,那么请使用触发器,但要非常小心地使用它们,并确保它们处理数据集。永远不应期望Sql server触发器只处理一行数据。您可能希望确保您的触发器代码具有尽可能高的性能,因为您正在从中获取数据,因此您正在从中获取数据。这意味着你需要阅读一本关于性能调优技术的好书,这样你才能知道哪些查询形式可以避免使用诸如相关子查询,非sargable where子句,游标。您还希望在负载下进行昂贵的测试以阻止问题。