我是否真的需要检查另一个表中的记录是否真的存在,如果PostgreSQL还是会检查外键约束?
Normaly parent在创建child记录之前检查是否存在记录.但这是另一个执行查询.所以我认为如果只处理PostgreSQL错误并检查是否parent存在记录不存在(违反外键约束)会更好.
是否更好地利用数据库服务器功能,或者它没有用于此目的?您是否建议在创建新记录之前进行所有完整性检查?
CREATE TABLE "public"."categories" (
"id" serial,
"name" varchar(100),
CONSTRAINT "categories__id_pkey" PRIMARY KEY ("id")
);
CREATE TABLE "public"."products" (
"id" serial,
"category_id" integer NOT NULL,
"name" varchar(100),
CONSTRAINT "products__id_pkey" PRIMARY KEY ("id"),
CONSTRAINT "products__category_id_fkey" FOREIGN KEY ("category_id")
REFERENCES "categories" ("id") ON DELETE CASCADE
);
Run Code Online (Sandbox Code Playgroud)
伪代码:
if (query("SELECT * FROM categories WHERE id = 123"))
query("INSERT INTO products (category_id, name) VALUES (123, 'Something')")
else
throw Error("Parent record does not exist")
try
query("INSERT INTO products (category_id, name) VALUES (123, 'Something')")
catch (Exception e)
if (e.code == '23503')
throw Error("Parent record does not exist")
else
throw Error("Some other error occured")
Run Code Online (Sandbox Code Playgroud)
23503PostgreSQL中的错误代码是:
ERROR: insert or update on table "products" violates foreign key constraint "products__category_id_fkey"
是否更好地利用数据库服务器功能,或者它没有用于此目的
它完全是为了这个目的.
只是处理错误,否则你做了太多的工作.
如果检查相关行的存在,则只需复制工作,因为PostgreSQL也会这样做.
如果您不想关心插入行的顺序,可以将约束声明为deferrable initially deferred.在这种情况下,所有相关的行必须在提交事务时存在,而不是在运行每个语句时.这是一个简短的例子:http://sqlfiddle.com/#!12/33de1/1
在这种情况下,您在提交时需要处理错误,而不是在运行每个语句时.