我正在学习SQL,但偶然发现了CONSTRAINT。我可以这样定义它们:
CREATE TABLE products (
product_no integer,
name text,
price numeric CHECK (price > 0)
);
并且像这样:
CREATE TABLE products (
product_no integer,
name text,
price numeric CONSTRAINT positive_price CHECK (price > 0)
);
为什么给他们起名字?或为什么我应该或不应该给他们起名字?正如我在该示例中看到的,在我脑海中大多数情况下,我无法重用它们。那么给CONSTRAINT命名有什么好处?
为约束指定一个明确的名称有很多好处。仅举几个例子:
似乎您使用的是PostgreSQL,但实际上差别并不大。
这是因为PostgreSQL中系统生成的名称实际上是有意义的。但是“ positive_price”仍然比“ foo_price_check”更容易理解:
考虑哪种错误消息更好理解:new row for relation "foo" violates check constraint "foo_price_check"
要么new row for relation "foo" violates check constraint "positive_price"
在Oracle中,这甚至更糟,因为生成的系统不包含关于错误原因的any提示:ORA-02290: check constraint (SYS_C0024109) violated
与ORA-02290: check constraint (POSITIVE_PRICE) violated
您未指定RDBMS。以下几点适用于SQL Server,我想其他RDBMS也很有可能。
您需要知道约束的名称为drop
,约束的名称也会出现在约束违规错误消息中,因此提供明确的名称可以使约束更有意义(SQL Server将自动为约束生成一个名称不会告诉您约束的意图。
约束为SQL中的对象,其方式与PK,FK,表或几乎其他任何方式相同。如果给约束起一个名称,则可以根据需要轻松删除它,例如在某种批量数据导入期间。如果您没有给它起一个名字,您仍然可以删除它,但是您必须找出SQL会给它自动生成的名字。
如果违反了约束,则在错误消息中显示其名称有助于调试它并将错误消息呈现给用户。
命名约束在某些情况下非常有用。这是到目前为止我所遇到的:
[如果您需要比较DEV和UT之类的环境以查看差异,则表级可能会出现“假阳性”,这确实很烦人。表定义在字面上是相同的,但是由于自动生成的名称不同,因此将其标记为更改。
是,某些工具允许跳过/忽略约束名称,但不是全部。
如果您正在使用基于状态的迁移工具(例如MS SSDT),然后在将生成的更改应用于PRODUCTION之前手动对其进行检查,则您希望最终脚本尽可能短。
具有一百行,它们确实执行了约束并用不同的名称创建约束,这是“ noise”。可以从该工具禁用某些约束,而某些约束仍将重新生成(DEFAULT / CHECK)。具有明确的名称和良好的命名约定可以解决所有问题。
最后,但并非最不重要。露骨可简化事情。如果您有明确的名称,则可以在不搜索系统/元数据视图的情况下引用数据库对象。