2012-04-07 53 views
1

我已经拥有id|provider_name|url
provider我已经拥有id|name|provider_id存储过程的名称来标识翻译

另一个表user我想创建一个功能create_user(name,provider_name),检查是否存在与该供应商的任何供应商名称。如果存在,则插入该行并返回最后一行ID。其他明智的回报0。我在provider_id - >user.id上设置了外键完整性。两者id字段pkeyserial

insert into users 
    (name, provider_id) 
values($1, (
    select id from provider where name = $2 
)) returning id 

这样行不行?

回答

1

你的说法,如果你让users.provider_id NOT NULL

INSERT INTO users (name, provider_id) 
VALUES ($1, (SELECT id FROM provider WHERE name = $2)) 
RETURNING id; 

会工作。没有这一点,你会输入一个NULL值为一个不存在的provider_id。外键约束不禁止!
(我假设你的意思是:provider_id -> provider.id,不-> user.id。)

您可能会或可能不想让users.name UNIQUE禁止重复的名称。

使用独特的名称,代理主键(user.id)在大多数情况下仍然有意义。处理整数比处理(更长)的文本要快。特别是如果您有多个其他表引用user表的主键通常是这种情况。对外键和伴随索引使用整数要快得多,并且需要更少的磁盘空间和RAM空间。稍后进行更改也比较容易,如将name分为firstnamesurname

0

如果存在具有该名称的多个用户行,则这将不起作用。如果不可能在用户中重复名称,那么它就没关系。 (如果这真的是一个名字,假设没有重复是不可能的,这似乎并不明智。)

当然,如果重复的用户名不可能,那么没有理由在用户表上有一个id列;我强烈建议只把名称命名为主键,离开id列。 (它也可能被称为别的东西。)这将简化和加快这个查询,以及整个类的查询。这种模式设计还假定一个用户最多可以有一个提供者(如果provider_id为null)或者恰好有一个提供者(如果provider_id不是NULL)。