Chr*_*s B 7 database oracle database-design
如果我知道正确的字段格式,我应该为所有这些字段创建检查约束,还是会影响插入/更新的性能?为复杂规则使用正则表达式是一个好主意,还是应该只使用像case和length这样的简单约束?
这些字段已在应用程序级别进行验证.
通常,最好不要信任应用程序并使用检查约束.数据必须保持完整性(谁知道可能运行的是什么流氓脚本,或者哪些程序错误可能会漏掉).
但是,如果您有许多复杂的检查约束,并且您注意到插入/更新速度减慢,则可能需要重新评估.是否真的有必要在每个领域都有一个?不.列数据类型和长度也充当约束.
Quassnoi的观点是有效的,但值得记住的是并非所有CHECK约束条件都相同.在接下来的测试中,我将REGEXP_LIKE()支票与另外两张"老式"支票进行了对比; 第一个将值转换为一个零字符串然后进行相等性检查,第二个使用进行范围检查BETWEEN().
"挂钟"测试对环境条件敏感(例如检查点点火),因此我们需要多次运行它们.另外要记住的是,性能因版本而异.例如,我正在运行11g并且正则表达式检查一直在9-10秒运行,这表明Oracle自10g以来已经对它进行了相当大的优化.另一方面,未经检查的插入程序运行时间为1.7 - 2 -h,因此正则表达式仍然相对昂贵.其他支票的重量约为2.5-3.0秒,大约相当于50%的完整性.
是否值得付出代价实际上取决于您对数据的看法.经验说依靠客户来执行数据规则不可避免地意味着在某些时候规则将被打破.或者是因为开发人员省略了应用它们或从应用程序中删除它们.或者因为有人在数据库中附加了一个不包含这些规则的新客户端应用程序(例如批量上载,Web服务).
最后,大多数应用程序不会一次加载一百万行.与网络往返相比,将检查应用于单个插入或上载所需的微秒可能是一个微不足道的开销.
SQL> CREATE TABLE t_check (value VARCHAR2(50))
2 /
Table created.
Elapsed: 00:00:00.01
SQL>
SQL> INSERT
2 INTO t_check
3 SELECT level
4 FROM dual
5 CONNECT BY
6 level <= 1000000
7 /
1000000 rows created.
Elapsed: 00:00:01.68
SQL>
SQL> prompt Regex check
Regex check
SQL>
SQL> drop table t_check
2 /
Table dropped.
Elapsed: 00:00:00.37
SQL> CREATE TABLE t_check (value VARCHAR2(50) NOT NULL
2 , CHECK(REGEXP_LIKE(value, '^[0-9]{1,10}$')))
3 /
Table created.
Elapsed: 00:00:00.07
SQL>
SQL> INSERT
2 INTO t_check
3 SELECT level
4 FROM dual
5 CONNECT BY
6 level <= 1000000
7 /
1000000 rows created.
Elapsed: 00:00:09.53
SQL>
SQL> prompt old fashioned "mask" check
old fashioned "mask" check
SQL>
SQL> drop table t_check
2 /
Table dropped.
Elapsed: 00:00:00.59
SQL> CREATE TABLE t_check
2 (value VARCHAR2(50) NOT NULL
3 , CHECK(translate(lpad(value, 20, '0')
4 , '1234567890', '0000000000') = '00000000000000000000' ))
5 /
Table created.
Elapsed: 00:00:00.01
SQL>
SQL> INSERT
2 INTO t_check
3 SELECT level
4 FROM dual
5 CONNECT BY
6 level <= 1000000
7 /
1000000 rows created.
Elapsed: 00:00:02.82
SQL>
SQL> prompt old fashioned "range" check
old fashioned "range" check
SQL>
SQL> drop table t_check
2 /
Table dropped.
Elapsed: 00:00:00.39
SQL> CREATE TABLE t_check
2 (value VARCHAR2(50) NOT NULL
3 , CHECK( value between 1 and 1000000))
4 /
Table created.
Elapsed: 00:00:00.01
SQL>
SQL> INSERT
2 INTO t_check
3 SELECT level
4 FROM dual
5 CONNECT BY
6 level <= 1000000
7 /
1000000 rows created.
Elapsed: 00:00:02.23
SQL>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1840 次 |
| 最近记录: |