【发布时间】:2021-01-12 19:42:22
【问题描述】:
刚开始学习 SQL 的基础知识。在某些版本的 SQL(Oracle、SQL Server 等)中,有 enable/disable 约束关键字。这些和add/drop 约束关键字有什么区别?为什么我们需要它?
【问题讨论】:
-
例如,您可以在大数据加载之前禁用约束以提高性能并在数据加载结束时重新启用它
标签: sql sql-server oracle constraints
刚开始学习 SQL 的基础知识。在某些版本的 SQL(Oracle、SQL Server 等)中,有 enable/disable 约束关键字。这些和add/drop 约束关键字有什么区别?为什么我们需要它?
【问题讨论】:
标签: sql sql-server oracle constraints
约束验证在执行 DML 操作时会降低性能。在批量插入/导入数据之前禁用约束是很常见的(尤其是在您知道数据“正常”的情况下),然后在批量操作完成后启用它。
【讨论】:
CHECK 选项以 1) 确保操作后数据有效,以及 2) 使约束受信任,这允许优化器利用它们的存在.
我在特殊情况下使用禁用约束。我有一个包含许多表(大约 1000 个)的应用程序。这些表中的记录具有“自然键”,即由外部来源给出的标识符和关系。有些表甚至使用不同的自然键作为对不同表的外键引用。
但我喜欢使用公共代理键作为主键和外部引用。
这是一个例子(不是 100% 确定正确的语法):
CREATE TABLE T_BTS (
OBJ_ID number constraint BTS_PK (OBJ_ID) PRIMARY KEY,
BTS_ID VARCHAR2(20) CONSTRAINT BTS_UK (BTS_ID) UNIQUE,
some more columns);
CREATE TABLE T_CELL (
OBJ_ID number constraint BTS_PK (OBJ_ID) PRIMARY KEY,
OBJ_ID_PARENT number,
BTS_ID VARCHAR2(20),
CELL_ID VARCHAR2(20) CONSTRAINT CELL_UK (BTS_ID, CELL_ID) UNIQUE,
some more columns);
ALTER TABLE T_CELL ADD CONSTRAINT CELL_PARENT_FK
FOREIGN KEY (OBJ_ID_PARENT)
REFERENCES T_BTS (OBJ_ID);
ALTER TABLE T_CELL ADD CONSTRAINT CELL_PARENT
FOREIGN KEY (BTS_ID)
REFERENCES T_BTS (BTS_ID) DISABLE;
在我所有的表中,主键列是always OBJ_ID,父表的键是always OBJ_ID_PARENT,不管自然键是如何定义的.这使我更容易拥有通用的 PL/SQL 过程和编写动态 SQL 语句。
一个例子:为了在插入后设置OBJ_ID_PARENT,需要进行以下更新
UPDATE T_CELL cell SET OBJ_ID_PARENT =
(SELECT OBJ_ID
FROM T_BTS bts
WHERE cell.BTS_ID = bts.BTS_ID)
我懒得写1000+这样的个人陈述。通过使用视图 USER_CONSTRAINTS 和 USER_CONS_COLUMNS,我可以链接自然键和代理键,并且可以通过动态 SQL 执行这些更新。
我所有的键和引用都是完全由约束定义的。我不需要维护任何额外的表来跟踪关系或列名。我的应用程序设计中唯一的限制是,我必须对约束使用特定的命名约定。但这样做的反价值是几乎不需要维护来保持数据一致并具有良好的性能。
为了使用以上所有功能,需要禁用一些约束 - 甚至是永久禁用。
【讨论】:
我 [几乎] 在应用程序的正常运行期间从不禁用约束。约束的重点是保持数据质量。
现在,在维护期间,我可以在添加或删除大量数据时暂时禁用它们。加载数据后,我会确保在重新启动应用程序之前再次启用它们。
【讨论】: