我有一张provider
表id|provider_name|url
我还有另一张user
张id|name|provider_id
我想创建一个函数create_user(name,provider_name)
,用于检查是否存在具有该提供程序名称的任何提供程序。 if exists插入行并返回最后一行id。其他明智的回归0
。我在provider_id
- >上设置了外键完整性user.id
。并且id
个字段均为pkey
和serial
insert into users
(name, provider_id)
values($1, (
select id from provider where name = $2
)) returning id
那可以吗?
答案 0 :(得分:1)
您的陈述
INSERT INTO users (name, provider_id)
VALUES ($1, (SELECT id FROM provider WHERE name = $2))
RETURNING id;
如果您创建users.provider_id NOT NULL
,将起作用。如果没有它,您将为不存在的provider_id输入NULL
值。外键约束不会禁止这个!
(我假设你的意思是:provider_id -> provider.id
,而不是-> user.id
。)
您可能希望也可能不希望users.name UNIQUE
禁止重复名称。
使用唯一名称,代理主键(user.id
)在大多数情况下仍然有意义。处理整数比处理(更长)文本更快。特别是如果您有多个其他表引用user
表的主键,通常就是这种情况。对外键和附带索引使用整数要快得多,并且在磁盘和RAM中需要的空间更少。稍后进行更改也更容易,例如将name
拆分为firstname
和surname
。
答案 1 :(得分:0)
如果有多个具有该名称的用户行,则无效。如果用户之间的重复名称不可能,那就没关系。 (如果那真的是一个名字,假设没有重复是不明智的。)
当然,如果无法使用重复的用户名,则没有充分的理由在用户表上有一个id列;我强烈建议只将名称作为主键并且不要使用id列。 (它也可能被称为其他东西。)这将简化和加速此查询以及整个查询类。此架构设计还假设一个用户最多只能有一个提供程序(如果provider_id为null)或者只有一个提供程序(如果provider_id为NOT NULL)。