1

我有一张桌子我 有另一张provider桌子id|provider_name|url
userid|name|provider_id

我想创建一个函数create_user(name,provider_name)来检查是否存在具有该提供程序名称的任何提供程序。如果存在则插入行并返回最后一行 id。其他明智的回报0provider_id我已经在->上设置了外键完整性user.id。两个id字段都是pkeyserial

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

可以吗 ?

4

2 回答 2

1

你的陈述

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

如果您制作 users.provider_id 将起作用NOT NULL。否则,您将输入一个NULL不存在的 provider_id 的值。外键约束不禁止这一点!
(我假设你的意思是:provider_id -> provider.id,不是-> user.id。)

您可能希望也可能不想users.name UNIQUE禁止重复名称。

使用唯一名称,代理主键 ( user.id) 在大多数情况下仍然有意义。处理整数比处理(更长的)文本更快。特别是如果您有多个其他表引用该表的主键,user这通常是这种情况。使用整数作为外键和相关索引的速度要快得多,并且需要更少的磁盘和 RAM 空间。以后进行更改也更容易,例如拆分namefirstnamesurname

于 2012-04-14T00:09:04.937 回答
0

如果有多个具有该名称的用户行,这将不起作用。如果用户之间的重复名称是不可能的,那么就可以了。(如果这真的是一个名字,假设不可能有重复似乎是不明智的。)

当然,如果不可能有重复的用户名,那么就没有充分的理由在 user 表上有一个 id 列;我强烈建议只将 name 设为主键并省略 id 列。(它也应该被称为别的东西。)这将简化和加速这个查询,以及整个查询类。这种模式设计还假设一个用户最多可以有一个提供者(如果 provider_id 可以为空)或只有一个提供者(如果 provider_id 不为空)。

于 2012-04-07T20:18:37.150 回答