CRM 4.0 集成整合 – 2- 为什么不允许直接修改SQL数据库

在我们的CRM实施部署文档中强调,不能直接使用SQL的查询更新语句( SELECT/UPDATE/INSERT/DELETE)修改CRM数据库,只有一个例外是使用Select语句直接访问Filter Views (就是CRM库表里的那些以Filtered前缀开始的视图)。下面粗略分析为什么会有这样的指导意见.

 

CRM设计的时候有自己的schema库来保存诸如实体(entity)定义,数据类型等原数据(metadata)信息。在3.0中有个单独的数据库叫Metabase, 4.0由于需要支持多组织结构这部分信息被移到组织数据库(orgname_mscrm)那些以MetadataSchema开头的库表中去了。

众所周知SQL server有自己的schema语言描述SQL里的table, column, data types等等。CRM Metadata是依赖SQL server schema语言来实现的,同时作为一个抽象层把CRM平台层需要的逻辑与具体的SQL物理存储实现给隔开了,这提供了一种针对具体的物理存储变化的灵活性。

image

 

CRM平台层提供了很多数据处理方面的功能,比如:

1. 数据安全检查

2. plugin插件。这个类似于SQL server里的触发器(trigger)

3. 针对数据修改变化事件触发的工作流。

4. Outlook离线客户端读取CRM Metadata来在Outlook 客户端创建离线数据库

 

只要通过CRM用户界面/CRMSDK修改数据,平台层就能保证数据会按照定义的规则被修改。反之,如果直接使用SQL server management studio的查询修改语句来修改CRM数据库表,那么MetaData和CRM平台层都被忽略过了,业务上定义的安全角色检查,数据修改触发规则等等都不会起作用。下面是常见的错误做法:

1. 自己定义编写SQL trigger,而不是使用平台层的plugin。我们见过很多引起死锁的问题,当然很多客户的理由是直接编写SQL trigger开发速度要快,节省时间 :)

 

2. 直接修改CRM的库表,添加一个列。比如CRM里没有提供类似Identity类型的列可以自动增加计数,有用户就在CRM界面定制了一个实体随便添加了个属性,然后回到SQL管理器中把该属性的类型修改成Identity. 这类定制引起Outlook客户端不能在本地创建离线数据库。

 

3. 在Plugin里面使用ADO.NET直接查询CRM库表。由于平台层的设计可以统筹库的并发访问,避免死锁;可是如果你手动添加了很多直接库表的连接,平台层并不知道,很容易导致很多SQL端的阻塞问题;另外有可能有数据因为安全方面原因泄露。有一个例外,我们允许的直接库表查询是那些FilteredViews. 这些SQL views主要是做报表用的。大家感兴趣可以打开这些View的定义,你可以看到Where语句里都包含了CRM级别的安全角色检查。

 

当然,目前有一种对SQL server schema的修改是可行的,就是添加/删除自己的索引(index)提高性能,但是不能删除CRM已经有的系统索引。

 

thanks

Clifford